1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "media_errors.h"
17 #include "media_log.h"
18 #include "ability.h"
19 #include "napi_base_context.h"
20 #include "soundpool_napi.h"
21
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_SOUNDPOOL, "SoundPoolNapi"};
24 }
25
26 namespace OHOS {
27 namespace Media {
28 int32_t SoundPoolNapi::maxStreams = 0;
29 AudioStandard::AudioRendererInfo SoundPoolNapi::rendererInfo;
30 thread_local napi_ref SoundPoolNapi::constructor_ = nullptr;
31 const std::string CLASS_NAME = "SoundPool";
32
~SoundPoolNapi()33 SoundPoolNapi::~SoundPoolNapi()
34 {
35 MEDIA_LOGI("SoundPoolNapi::~SoundPoolNapi");
36 }
37
Init(napi_env env,napi_value exports)38 napi_value SoundPoolNapi::Init(napi_env env, napi_value exports)
39 {
40 napi_property_descriptor staticProperty[] = {
41 DECLARE_NAPI_STATIC_FUNCTION("createSoundPool", JsCreateSoundPool),
42 };
43
44 napi_property_descriptor properties[] = {
45 DECLARE_NAPI_FUNCTION("load", JsLoad),
46 DECLARE_NAPI_FUNCTION("play", JsPlay),
47 DECLARE_NAPI_FUNCTION("stop", JsStop),
48 DECLARE_NAPI_FUNCTION("setLoop", JsSetLoop),
49 DECLARE_NAPI_FUNCTION("setPriority", JsSetPriority),
50 DECLARE_NAPI_FUNCTION("setRate", JsSetRate),
51 DECLARE_NAPI_FUNCTION("setVolume", JsSetVolume),
52 DECLARE_NAPI_FUNCTION("unload", JsUnload),
53 DECLARE_NAPI_FUNCTION("release", JsRelease),
54 DECLARE_NAPI_FUNCTION("on", JsSetOnCallback),
55 DECLARE_NAPI_FUNCTION("off", JsClearOnCallback),
56 };
57
58 napi_value constructor = nullptr;
59 napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
60 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
61 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define SoundPool class");
62
63 status = napi_create_reference(env, constructor, 1, &constructor_);
64 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to create reference of constructor");
65
66 status = napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor);
67 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to set constructor");
68
69 status = napi_define_properties(env, exports, sizeof(staticProperty) / sizeof(staticProperty[0]), staticProperty);
70 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define static function");
71
72 MEDIA_LOGD("Init success");
73 return exports;
74 }
75
Constructor(napi_env env,napi_callback_info info)76 napi_value SoundPoolNapi::Constructor(napi_env env, napi_callback_info info)
77 {
78 MEDIA_LOGI("Constructor enter");
79 napi_value result = nullptr;
80 napi_get_undefined(env, &result);
81
82 size_t argCount = 0;
83 napi_value jsThis = nullptr;
84 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
85 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "failed to napi_get_cb_info");
86
87 SoundPoolNapi *soundPoolNapi = new(std::nothrow) SoundPoolNapi();
88 CHECK_AND_RETURN_RET_LOG(soundPoolNapi != nullptr, result, "No memory!");
89
90 soundPoolNapi->env_ = env;
91 soundPoolNapi->soundPool_ = SoundPoolFactory::CreateSoundPool(maxStreams, rendererInfo);
92 if (soundPoolNapi->soundPool_ == nullptr) {
93 delete soundPoolNapi;
94 MEDIA_LOGE("failed to CreateSoundPool");
95 return result;
96 }
97
98 if (soundPoolNapi->callbackNapi_ == nullptr && soundPoolNapi->soundPool_ != nullptr) {
99 soundPoolNapi->callbackNapi_ = std::make_shared<SoundPoolCallBackNapi>(env);
100 (void)soundPoolNapi->soundPool_->SetSoundPoolCallback(soundPoolNapi->callbackNapi_);
101 }
102
103 status = napi_wrap(env, jsThis, reinterpret_cast<void *>(soundPoolNapi),
104 SoundPoolNapi::Destructor, nullptr, nullptr);
105 if (status != napi_ok) {
106 delete soundPoolNapi;
107 MEDIA_LOGE("Failed to warp native instance!");
108 return result;
109 }
110 MEDIA_LOGI("Constructor success");
111 return jsThis;
112 }
113
Destructor(napi_env env,void * nativeObject,void * finalize)114 void SoundPoolNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
115 {
116 (void)env;
117 (void)finalize;
118 if (nativeObject != nullptr) {
119 SoundPoolNapi *napi = reinterpret_cast<SoundPoolNapi *>(nativeObject);
120 napi->callbackNapi_ = nullptr;
121
122 if (napi->soundPool_) {
123 napi->soundPool_->Release();
124 napi->soundPool_ = nullptr;
125 }
126 delete napi;
127 }
128 MEDIA_LOGD("Destructor success");
129 }
130
JsCreateSoundPool(napi_env env,napi_callback_info info)131 napi_value SoundPoolNapi::JsCreateSoundPool(napi_env env, napi_callback_info info)
132 {
133 MediaTrace trace("SoundPool::JsCreateSoundPool");
134 MEDIA_LOGI("SoundPoolNapi::JsCreateSoundPool");
135 napi_value result = nullptr;
136 napi_get_undefined(env, &result);
137
138 // get args
139 napi_value jsThis = nullptr;
140 napi_value args[PARAM3] = { nullptr };
141 size_t argCount = PARAM3;
142 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
143 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "failed to napi_get_cb_info");
144
145 // get create soundpool Parameter
146 status = GetJsInstanceWithParameter(env, args);
147 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "failed to Get InstanceWithParameter");
148
149 std::unique_ptr<SoundPoolAsyncContext> asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
150
151 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM2]);
152 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
153 asyncCtx->JsResult = std::make_unique<MediaJsResultInstance>(constructor_);
154 asyncCtx->ctorFlag = true;
155
156 napi_value resource = nullptr;
157 napi_create_string_utf8(env, "JsCreateSoundPool", NAPI_AUTO_LENGTH, &resource);
158 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
159 MEDIA_LOGD("JsCreateSoundPool napi_create_async_work");
160 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
161 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
162 asyncCtx.release();
163
164 return result;
165 }
166
JsLoad(napi_env env,napi_callback_info info)167 napi_value SoundPoolNapi::JsLoad(napi_env env, napi_callback_info info)
168 {
169 MediaTrace trace("SoundPool::JsLoad");
170 MEDIA_LOGI("SoundPoolNapi::JsLoad");
171 size_t argCount = PARAM4;
172 napi_value args[PARAM4] = { nullptr };
173 napi_value result = nullptr;
174 napi_get_undefined(env, &result);
175
176 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
177 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
178 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
179 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
180 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
181
182 if (argCount == PARAM4) {
183 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM3]);
184 } else {
185 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM1]);
186 }
187 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
188 napi_value resource = nullptr;
189 napi_create_string_utf8(env, "JsLoad", NAPI_AUTO_LENGTH, &resource);
190 if (asyncCtx->napi->ParserLoadOptionFromJs(asyncCtx, env, args, argCount) == MSERR_OK) {
191 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
192 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
193 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
194 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
195 int32_t soundId;
196 if (asyncCtx->url_.empty()) {
197 soundId = asyncCtx->soundPool_->Load(asyncCtx->fd_, asyncCtx->offset_, asyncCtx->length_);
198 } else {
199 soundId = asyncCtx->soundPool_->Load(asyncCtx->url_);
200 }
201 if (soundId < 0) {
202 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "load sound failed");
203 } else {
204 asyncCtx->JsResult = std::make_unique<MediaJsResultInt>(soundId);
205 }
206 MEDIA_LOGI("The js thread of load finishes execution and returns, soundId: %{public}d", soundId);
207 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
208 } else {
209 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
210 MEDIA_LOGD("JsLoad napi_create_async_work");
211 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
212 }
213 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
214 asyncCtx.release();
215 return result;
216 }
217
JsPlay(napi_env env,napi_callback_info info)218 napi_value SoundPoolNapi::JsPlay(napi_env env, napi_callback_info info)
219 {
220 MediaTrace trace("SoundPool::JsPlay");
221 MEDIA_LOGI("SoundPoolNapi::JsPlay");
222 size_t argCount = PARAM3;
223 napi_value args[PARAM3] = { nullptr };
224
225 napi_value result = nullptr;
226 napi_get_undefined(env, &result);
227
228 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
229 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
230 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
231 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
232 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
233
234 if (argCount == PARAM3) {
235 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM2]);
236 } else {
237 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM1]);
238 }
239 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
240 napi_value resource = nullptr;
241 napi_create_string_utf8(env, "JsPlay", NAPI_AUTO_LENGTH, &resource);
242 if (asyncCtx->napi->ParserPlayOptionFromJs(asyncCtx, env, args, argCount) == MSERR_OK) {
243 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
244 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
245 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
246 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
247 int32_t streamId = asyncCtx->soundPool_->Play(asyncCtx->soundId_, asyncCtx->playParameters_);
248 if (streamId < 0) {
249 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "play sound failed");
250 } else {
251 asyncCtx->JsResult = std::make_unique<MediaJsResultInt>(streamId);
252 }
253 MEDIA_LOGI("The js thread of play finishes execution and returns, streamId: %{public}d", streamId);
254 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
255 } else {
256 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
257 MEDIA_LOGD("JsPlay napi_create_async_work");
258 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
259 }
260 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
261 asyncCtx.release();
262 return result;
263 }
264
JsStop(napi_env env,napi_callback_info info)265 napi_value SoundPoolNapi::JsStop(napi_env env, napi_callback_info info)
266 {
267 MediaTrace trace("SoundPool::JsStop");
268 MEDIA_LOGI("SoundPoolNapi::JsStop");
269 size_t argCount = PARAM2;
270 napi_value args[PARAM2] = { nullptr };
271
272 napi_value result = nullptr;
273 napi_get_undefined(env, &result);
274
275 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
276 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
277 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
278 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
279 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
280
281 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM1]);
282 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
283 napi_status status = napi_get_value_int32(env, args[PARAM0], &asyncCtx->streamId_);
284 if (status != napi_ok || asyncCtx->streamId_ <= 0) {
285 asyncCtx->SignError(MSERR_EXT_API9_INVALID_PARAMETER, "stop streamId failed, invaild value");
286 }
287 napi_value resource = nullptr;
288 napi_create_string_utf8(env, "JsStop", NAPI_AUTO_LENGTH, &resource);
289 if (status == napi_ok && asyncCtx->streamId_ > 0) {
290 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
291 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
292 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
293 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
294 int32_t ret = asyncCtx->soundPool_->Stop(asyncCtx->streamId_);
295 if (ret != MSERR_OK) {
296 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "stop streamId failed");
297 }
298 MEDIA_LOGI("The js thread of stop finishes execution and returns");
299 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
300 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
301 } else {
302 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
303 MEDIA_LOGD("JsStop napi_create_async_work");
304 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
305 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
306 }
307 asyncCtx.release();
308 return result;
309 }
310
JsSetLoop(napi_env env,napi_callback_info info)311 napi_value SoundPoolNapi::JsSetLoop(napi_env env, napi_callback_info info)
312 {
313 MediaTrace trace("SoundPool::JsSetLoop");
314 MEDIA_LOGI("SoundPoolNapi::JsSetLoop");
315 size_t argCount = PARAM3;
316 napi_value args[PARAM3] = { nullptr };
317
318 napi_value result = nullptr;
319 napi_get_undefined(env, &result);
320
321 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
322 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
323 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
324 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
325 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
326
327 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM2]);
328 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
329 napi_status status = napi_get_value_int32(env, args[PARAM0], &asyncCtx->streamId_);
330 if (status != napi_ok || asyncCtx->streamId_ <= 0) {
331 asyncCtx->SignError(MSERR_EXT_API9_INVALID_PARAMETER, "SetLoop streamId failed,invaild value");
332 }
333 status = napi_get_value_int32(env, args[PARAM1], &asyncCtx->loop_);
334 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "failed to setloop id");
335
336 napi_value resource = nullptr;
337 napi_create_string_utf8(env, "JsSetLoop", NAPI_AUTO_LENGTH, &resource);
338 if (status == napi_ok && asyncCtx->streamId_ > 0) {
339 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
340 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
341 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
342 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
343 int32_t ret = asyncCtx->soundPool_->SetLoop(asyncCtx->streamId_, asyncCtx->loop_);
344 if (ret != MSERR_OK) {
345 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "setLoop streamId failed");
346 }
347 MEDIA_LOGI("The js thread of SetLoop finishes execution and returns");
348 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
349 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
350 } else {
351 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
352 MEDIA_LOGD("JsSetLoop napi_create_async_work");
353 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
354 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
355 }
356 asyncCtx.release();
357 return result;
358 }
359
JsSetPriority(napi_env env,napi_callback_info info)360 napi_value SoundPoolNapi::JsSetPriority(napi_env env, napi_callback_info info)
361 {
362 MediaTrace trace("SoundPool::JsSetPriority");
363 MEDIA_LOGI("SoundPoolNapi::JsSetPriority");
364 size_t argCount = PARAM3;
365 napi_value args[PARAM3] = { nullptr };
366
367 napi_value result = nullptr;
368 napi_get_undefined(env, &result);
369
370 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
371 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
372 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
373 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
374 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
375
376 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM2]);
377 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
378 napi_status status = napi_get_value_int32(env, args[PARAM0], &asyncCtx->streamId_);
379 if (status != napi_ok || asyncCtx->streamId_ <= 0) {
380 asyncCtx->SignError(MSERR_EXT_API9_INVALID_PARAMETER, "SetPriority streamId failed");
381 }
382 status = napi_get_value_int32(env, args[PARAM1], &asyncCtx->priority_);
383 if (status != napi_ok || asyncCtx->priority_ < 0) {
384 asyncCtx->SignError(MSERR_EXT_API9_INVALID_PARAMETER, "SetPriority priority failed");
385 }
386
387 napi_value resource = nullptr;
388 napi_create_string_utf8(env, "JsSetPriority", NAPI_AUTO_LENGTH, &resource);
389 if (status == napi_ok && asyncCtx->streamId_ > 0) {
390 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
391 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
392 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
393 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
394 int32_t ret = asyncCtx->soundPool_->SetPriority(asyncCtx->streamId_, asyncCtx->priority_);
395 if (ret != MSERR_OK) {
396 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "SetPriority streamId failed");
397 }
398 MEDIA_LOGI("The js thread of SetPriority finishes execution and returns");
399 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
400 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
401 } else {
402 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
403 MEDIA_LOGD("JsSetPriority napi_create_async_work");
404 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
405 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
406 }
407 asyncCtx.release();
408 return result;
409 }
410
JsSetRate(napi_env env,napi_callback_info info)411 napi_value SoundPoolNapi::JsSetRate(napi_env env, napi_callback_info info)
412 {
413 MediaTrace trace("SoundPool::JsSetRate");
414 MEDIA_LOGI("SoundPoolNapi::JsSetRate");
415 size_t argCount = PARAM3;
416 napi_value args[PARAM3] = { nullptr };
417
418 napi_value result = nullptr;
419 napi_get_undefined(env, &result);
420
421 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
422 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
423 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
424 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
425 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
426
427 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM2]);
428 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
429 napi_value resource = nullptr;
430 napi_create_string_utf8(env, "JsSetRate", NAPI_AUTO_LENGTH, &resource);
431 if (asyncCtx->napi->ParserRateOptionFromJs(asyncCtx, env, args) == MSERR_OK) {
432 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
433 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
434 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
435 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
436 int32_t ret = asyncCtx->soundPool_->SetRate(asyncCtx->streamId_, asyncCtx->renderRate_);
437 if (ret != MSERR_OK) {
438 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "SetRate streamId failed");
439 }
440 MEDIA_LOGI("The js thread of SetRate finishes execution and returns");
441 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
442 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
443 } else {
444 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
445 MEDIA_LOGD("JsSetRate napi_create_async_work");
446 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
447 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
448 }
449 asyncCtx.release();
450 return result;
451 }
452
JsSetVolume(napi_env env,napi_callback_info info)453 napi_value SoundPoolNapi::JsSetVolume(napi_env env, napi_callback_info info)
454 {
455 MediaTrace trace("SoundPool::JsSetVolume");
456 MEDIA_LOGI("SoundPoolNapi::JsSetVolume");
457 size_t argCount = PARAM4;
458 napi_value args[PARAM4] = { nullptr };
459
460 napi_value result = nullptr;
461 napi_get_undefined(env, &result);
462
463 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
464 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
465 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
466 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
467 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
468
469 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM3]);
470 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
471 napi_value resource = nullptr;
472 napi_create_string_utf8(env, "JsSetVolume", NAPI_AUTO_LENGTH, &resource);
473 if (asyncCtx->napi->ParserVolumeOptionFromJs(asyncCtx, env, args) == MSERR_OK) {
474 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
475 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
476 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
477 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
478 int32_t ret = asyncCtx->soundPool_->SetVolume(asyncCtx->streamId_,
479 asyncCtx->leftVolume_, asyncCtx->rightVolume_);
480 if (ret != MSERR_OK) {
481 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "setVolume streamId failed");
482 }
483 MEDIA_LOGI("The js thread of SetVolume finishes execution and returns");
484 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
485 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
486 } else {
487 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
488 MEDIA_LOGD("JsSetVolume napi_create_async_work");
489 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
490 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
491 }
492 asyncCtx.release();
493 return result;
494 }
495
JsUnload(napi_env env,napi_callback_info info)496 napi_value SoundPoolNapi::JsUnload(napi_env env, napi_callback_info info)
497 {
498 MediaTrace trace("SoundPool::JsUnload");
499 MEDIA_LOGI("SoundPoolNapi::JsUnload");
500 size_t argCount = PARAM2;
501 napi_value args[PARAM2] = { nullptr };
502
503 napi_value result = nullptr;
504 napi_get_undefined(env, &result);
505
506 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
507 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
508 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
509 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
510 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
511
512 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM1]);
513 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
514 napi_status status = napi_get_value_int32(env, args[PARAM0], &asyncCtx->soundId_);
515 if (status != napi_ok || asyncCtx->soundId_ <= 0) {
516 asyncCtx->SignError(MSERR_EXT_API9_IO, "unLoad failed,inavild value");
517 }
518
519 napi_value resource = nullptr;
520 napi_create_string_utf8(env, "JsUnload", NAPI_AUTO_LENGTH, &resource);
521 if (status == napi_ok && asyncCtx->soundId_ > 0) {
522 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
523 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
524 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
525 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
526 int32_t ret = asyncCtx->soundPool_->Unload(asyncCtx->soundId_);
527 if (ret != MSERR_OK) {
528 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "unLoad soundID failed");
529 }
530 MEDIA_LOGI("The js thread of Unload finishes execution and returns, soundID: %{public}d",
531 asyncCtx->soundId_);
532 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
533 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
534 } else {
535 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
536 MEDIA_LOGD("JsUnload napi_create_async_work");
537 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
538 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
539 }
540 asyncCtx.release();
541 return result;
542 }
543
JsRelease(napi_env env,napi_callback_info info)544 napi_value SoundPoolNapi::JsRelease(napi_env env, napi_callback_info info)
545 {
546 MediaTrace trace("SoundPool::JsRelease");
547 MEDIA_LOGI("SoundPoolNapi::JsRelease");
548 size_t argCount = PARAM1;
549 napi_value args[PARAM1] = { nullptr };
550
551 napi_value result = nullptr;
552 napi_get_undefined(env, &result);
553
554 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
555 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
556 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
557 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
558 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
559 asyncCtx->callbackNapi_ = asyncCtx->napi->callbackNapi_;
560
561 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM0]);
562 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
563
564 napi_value resource = nullptr;
565 napi_create_string_utf8(env, "JsRelease", NAPI_AUTO_LENGTH, &resource);
566 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
567 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
568 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
569 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
570 int32_t ret = asyncCtx->soundPool_->Release();
571 CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Release failed!");
572 CHECK_AND_RETURN_LOG(asyncCtx->callbackNapi_ != nullptr, "release callbackNapi_ is nullptr!");
573 asyncCtx->napi->CancelCallback(asyncCtx->callbackNapi_);
574 MEDIA_LOGI("The js thread of JsRelease finishes execution and returns");
575 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
576 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
577 asyncCtx.release();
578
579 return result;
580 }
581
JsSetOnCallback(napi_env env,napi_callback_info info)582 napi_value SoundPoolNapi::JsSetOnCallback(napi_env env, napi_callback_info info)
583 {
584 MediaTrace trace("SoundPool::JsSetOnCallback");
585 MEDIA_LOGI("SoundPoolNapi::JsSetOnCallback");
586 napi_value result = nullptr;
587 napi_get_undefined(env, &result);
588
589 size_t argCount = 2;
590 napi_value args[2] = { nullptr, nullptr };
591 SoundPoolNapi *soundPoolNapi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
592 CHECK_AND_RETURN_RET_LOG(soundPoolNapi != nullptr, result, "Failed to retrieve instance");
593
594 napi_valuetype valueType0 = napi_undefined;
595 napi_valuetype valueType1 = napi_undefined;
596 if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string ||
597 napi_typeof(env, args[1], &valueType1) != napi_ok || valueType1 != napi_function) {
598 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "SetEventCallback");
599 return result;
600 }
601
602 std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
603 MEDIA_LOGI("set callbackName: %{public}s", callbackName.c_str());
604 if (callbackName != SoundPoolEvent::EVENT_LOAD_COMPLETED && callbackName != SoundPoolEvent::EVENT_PLAY_FINISHED &&
605 callbackName != SoundPoolEvent::EVENT_PLAY_FINISHED_WITH_STREAM_ID &&
606 callbackName != SoundPoolEvent::EVENT_ERROR) {
607 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "SetEventCallback");
608 return result;
609 }
610
611 napi_ref ref = nullptr;
612 napi_status status = napi_create_reference(env, args[1], 1, &ref);
613 CHECK_AND_RETURN_RET_LOG(status == napi_ok && ref != nullptr, result, "failed to create reference!");
614
615 std::shared_ptr<AutoRef> autoRef = std::make_shared<AutoRef>(env, ref);
616 soundPoolNapi->SetCallbackReference(callbackName, autoRef);
617
618 MEDIA_LOGI("JsSetOnCallback callbackName: %{public}s success", callbackName.c_str());
619 return result;
620 }
621
JsClearOnCallback(napi_env env,napi_callback_info info)622 napi_value SoundPoolNapi::JsClearOnCallback(napi_env env, napi_callback_info info)
623 {
624 MediaTrace trace("SoundPool::JsClearOnCallback");
625 MEDIA_LOGI("SoundPoolNapi::JsClearOnCallback");
626 napi_value result = nullptr;
627 napi_get_undefined(env, &result);
628
629 size_t argCount = 1;
630 napi_value args[1] = { nullptr };
631 SoundPoolNapi *soundPoolNapi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
632 CHECK_AND_RETURN_RET_LOG(soundPoolNapi != nullptr, result, "Failed to retrieve instance");
633
634 napi_valuetype valueType0 = napi_undefined;
635 if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string) {
636 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "CancelEventCallback");
637 return result;
638 }
639
640 std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
641 if (callbackName != SoundPoolEvent::EVENT_LOAD_COMPLETED && callbackName != SoundPoolEvent::EVENT_PLAY_FINISHED &&
642 callbackName != SoundPoolEvent::EVENT_PLAY_FINISHED_WITH_STREAM_ID &&
643 callbackName != SoundPoolEvent::EVENT_ERROR) {
644 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "CancelEventCallback");
645 return result;
646 }
647
648 soundPoolNapi->CancelCallbackReference(callbackName);
649
650 MEDIA_LOGI("0x%{public}06" PRIXPTR " JsClearOnCallback success", FAKE_POINTER(soundPoolNapi));
651 return result;
652 }
653
GetJsInstanceAndArgs(napi_env env,napi_callback_info info,size_t & argCount,napi_value * args)654 SoundPoolNapi* SoundPoolNapi::GetJsInstanceAndArgs(napi_env env, napi_callback_info info,
655 size_t &argCount, napi_value *args)
656 {
657 napi_value jsThis = nullptr;
658 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
659 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr, "failed to napi_get_cb_info");
660 MEDIA_LOGI("0x:%{public}06" PRIXPTR " instance argCount:%{public}zu", FAKE_POINTER(jsThis), argCount);
661
662 SoundPoolNapi *soundPoolNapi = nullptr;
663
664 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&soundPoolNapi));
665 CHECK_AND_RETURN_RET_LOG(status == napi_ok && soundPoolNapi != nullptr, nullptr, "failed to retrieve instance");
666
667 return soundPoolNapi;
668 }
669
GetJsInstanceWithParameter(napi_env env,napi_value * argv)670 napi_status SoundPoolNapi::GetJsInstanceWithParameter(napi_env env, napi_value *argv)
671 {
672 napi_status status = napi_get_value_int32(env, argv[PARAM0], &maxStreams); // get maxStreams
673 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "failed to get napi maxStreams");
674
675 napi_value tempValue = nullptr;
676 int32_t intValue = {0};
677 status = napi_get_named_property(env, argv[PARAM1], "content", &tempValue);
678 if (status == napi_ok) {
679 napi_get_value_int32(env, tempValue, &intValue);
680 rendererInfo.contentType = static_cast<AudioStandard::ContentType>(intValue);
681 }
682
683 status = napi_get_named_property(env, argv[PARAM1], "usage", &tempValue);
684 if (status == napi_ok) {
685 napi_get_value_int32(env, tempValue, &intValue);
686 rendererInfo.streamUsage = static_cast<AudioStandard::StreamUsage>(intValue);
687 }
688
689 status = napi_get_named_property(env, argv[PARAM1], "rendererFlags", &tempValue);
690 if (status == napi_ok) {
691 napi_get_value_int32(env, tempValue, &(rendererInfo.rendererFlags));
692 }
693
694 return status;
695 }
696
ParserLoadOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> & asyncCtx,napi_env env,napi_value * argv,size_t argCount)697 int32_t SoundPoolNapi::ParserLoadOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
698 napi_env env, napi_value *argv, size_t argCount)
699 {
700 int32_t ret = MSERR_OK;
701 MEDIA_LOGI("ParserLoadOptionFromJs argCount %{public}zu", argCount);
702 if ((argCount < PARAM3) && (argCount > 0)) {
703 asyncCtx->url_ = CommonNapi::GetStringArgument(env, argv[PARAM0]);
704 CHECK_AND_RETURN_RET(asyncCtx->url_ != "",
705 (asyncCtx->SoundPoolAsyncSignError(MSERR_OPEN_FILE_FAILED, "geturl", "url"), MSERR_OPEN_FILE_FAILED));
706 } else if ((argCount >= PARAM3) && (argCount < MAX_PARAM)) {
707 napi_status status = napi_get_value_int32(env, argv[PARAM0], &asyncCtx->fd_);
708 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->fd_ > 0),
709 (asyncCtx->SoundPoolAsyncSignError(MSERR_OPEN_FILE_FAILED, "getfd", "fd"), MSERR_OPEN_FILE_FAILED));
710
711 status = napi_get_value_int64(env, argv[PARAM1], &asyncCtx->offset_);
712 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->offset_ >= 0),
713 (asyncCtx->SoundPoolAsyncSignError(MSERR_OPEN_FILE_FAILED, "getoffset", "offset"), MSERR_OPEN_FILE_FAILED));
714
715 status = napi_get_value_int64(env, argv[PARAM2], &asyncCtx->length_);
716 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->length_ > 0),
717 (asyncCtx->SoundPoolAsyncSignError(MSERR_OPEN_FILE_FAILED, "getlength", "length"), MSERR_OPEN_FILE_FAILED));
718 } else {
719 MEDIA_LOGI("Get Value error,return error:MSERR_INVALID_VAL");
720 return MSERR_INVALID_VAL;
721 }
722 return ret;
723 }
724
GetAbilityContext(napi_env env)725 static std::shared_ptr<AbilityRuntime::Context> GetAbilityContext(napi_env env)
726 {
727 auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
728 if (ability == nullptr) {
729 MEDIA_LOGE("Failed to obtain ability in FA mode");
730 return nullptr;
731 }
732 auto faContext = ability->GetAbilityContext();
733 if (faContext == nullptr) {
734 MEDIA_LOGE("GetAbilityContext returned null in FA model");
735 return nullptr;
736 }
737 return faContext;
738 }
739
ParserPlayOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> & asyncCtx,napi_env env,napi_value * argv,size_t argCount)740 int32_t SoundPoolNapi::ParserPlayOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
741 napi_env env, napi_value *argv, size_t argCount)
742 {
743 int32_t ret = MSERR_OK;
744 MEDIA_LOGI("ParserPlayOptionFromJs argCount %{public}zu", argCount);
745 napi_status status = napi_get_value_int32(env, argv[PARAM0], &asyncCtx->soundId_);
746 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->soundId_ > 0),
747 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getplaysoundId", "soundId"), MSERR_INVALID_VAL));
748
749 CommonNapi::GetPropertyInt32(env, argv[PARAM1], "loop", asyncCtx->playParameters_.loop);
750 CommonNapi::GetPropertyInt32(env, argv[PARAM1], "rate", asyncCtx->playParameters_.rate);
751 double leftVolume;
752 ret = CommonNapi::GetPropertyDouble(env, argv[PARAM1], "leftVolume", leftVolume);
753 if (ret > 0) {
754 asyncCtx->playParameters_.leftVolume = static_cast<float>(leftVolume);
755 }
756 ret = CommonNapi::GetPropertyDouble(env, argv[PARAM1], "rightVolume", leftVolume);
757 if (ret > 0) {
758 asyncCtx->playParameters_.rightVolume = static_cast<float>(leftVolume);
759 }
760 CommonNapi::GetPropertyInt32(env, argv[PARAM1], "priority", asyncCtx->playParameters_.priority);
761 GetPropertyBool(env, argv[PARAM1], "parallelPlayFlag", asyncCtx->playParameters_.parallelPlayFlag);
762
763 std::shared_ptr<AbilityRuntime::Context> abilityContext = GetAbilityContext(env);
764 if (abilityContext != nullptr) {
765 asyncCtx->playParameters_.cacheDir = abilityContext->GetCacheDir();
766 } else {
767 asyncCtx->playParameters_.cacheDir = "/data/storage/el2/base/temp";
768 }
769 MEDIA_LOGI("playParameters_ loop:%{public}d, rate:%{public}d, leftVolume:%{public}f, rightvolume:%{public}f,"
770 "priority:%{public}d, parallelPlayFlag:%{public}d", asyncCtx->playParameters_.loop,
771 asyncCtx->playParameters_.rate, asyncCtx->playParameters_.leftVolume,
772 asyncCtx->playParameters_.rightVolume, asyncCtx->playParameters_.priority,
773 asyncCtx->playParameters_.parallelPlayFlag);
774 return MSERR_OK;
775 }
776
ParserRateOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> & asyncCtx,napi_env env,napi_value * argv)777 int32_t SoundPoolNapi::ParserRateOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
778 napi_env env, napi_value *argv)
779 {
780 int32_t ret = MSERR_OK;
781 napi_status status = napi_get_value_int32(env, argv[PARAM0], &asyncCtx->streamId_);
782 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->streamId_ > 0),
783 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getratestreamId", "streamId"), MSERR_INVALID_VAL));
784 int32_t rendderRate;
785 status = napi_get_value_int32(env, argv[PARAM1], &rendderRate);
786 CHECK_AND_RETURN_RET(status == napi_ok,
787 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getaudiorennderrate",
788 "audiorennderrate"), MSERR_INVALID_VAL));
789 asyncCtx->renderRate_ = static_cast<AudioStandard::AudioRendererRate>(rendderRate);
790
791 return ret;
792 }
793
ParserVolumeOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> & asyncCtx,napi_env env,napi_value * argv)794 int32_t SoundPoolNapi::ParserVolumeOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
795 napi_env env, napi_value *argv)
796 {
797 int32_t ret = MSERR_OK;
798 napi_status status = napi_get_value_int32(env, argv[PARAM0], &asyncCtx->streamId_);
799 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->streamId_ > 0),
800 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getvolumestreamId", "streamId"), MSERR_INVALID_VAL));
801 double tempvolume;
802 status = napi_get_value_double(env, argv[PARAM1], &tempvolume);
803 CHECK_AND_RETURN_RET(status == napi_ok,
804 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getleftvolme", "leftvolme"), MSERR_INVALID_VAL));
805 asyncCtx->leftVolume_ = static_cast<float>(tempvolume);
806
807 status = napi_get_value_double(env, argv[PARAM2], &tempvolume);
808 CHECK_AND_RETURN_RET(status == napi_ok,
809 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getrightvolme", "rightvolme"), MSERR_INVALID_VAL));
810 asyncCtx->rightVolume_ = static_cast<float>(tempvolume);
811
812 return ret;
813 }
814
ErrorCallback(int32_t errCode,const std::string & operate,const std::string & add)815 void SoundPoolNapi::ErrorCallback(int32_t errCode, const std::string &operate, const std::string &add)
816 {
817 MEDIA_LOGE("failed to %{public}s, errCode = %{public}d", operate.c_str(), errCode);
818 CHECK_AND_RETURN_LOG(callbackNapi_ != nullptr, "soundpoolCb_ is nullptr!");
819 auto napiCb = std::static_pointer_cast<SoundPoolCallBackNapi>(callbackNapi_);
820
821 MediaServiceExtErrCodeAPI9 err = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errCode));
822 std::string msg = MSExtErrorAPI9ToString(err, operate, "") + add;
823 napiCb->SendErrorCallback(errCode, msg);
824 }
825
SetCallbackReference(const std::string & callbackName,std::shared_ptr<AutoRef> ref)826 void SoundPoolNapi::SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref)
827 {
828 eventCbMap_[callbackName] = ref;
829 CHECK_AND_RETURN_LOG(callbackNapi_ != nullptr, "soundpoolCb_ is nullptr!");
830 auto napiCb = std::static_pointer_cast<SoundPoolCallBackNapi>(callbackNapi_);
831 napiCb->SaveCallbackReference(callbackName, ref);
832 }
833
CancelCallbackReference(const std::string & callbackName)834 void SoundPoolNapi::CancelCallbackReference(const std::string &callbackName)
835 {
836 CHECK_AND_RETURN_LOG(callbackNapi_ != nullptr, "soundpoolCb_ is nullptr!");
837 auto napiCb = std::static_pointer_cast<SoundPoolCallBackNapi>(callbackNapi_);
838 napiCb->CancelCallbackReference(callbackName);
839 eventCbMap_[callbackName] = nullptr;
840 }
841
CancelCallback(std::shared_ptr<ISoundPoolCallback> callback)842 void SoundPoolNapi::CancelCallback(std::shared_ptr<ISoundPoolCallback> callback)
843 {
844 CHECK_AND_RETURN_LOG(callback != nullptr, "soundpoolCb_ is nullptr!");
845 auto napiCb = std::static_pointer_cast<SoundPoolCallBackNapi>(callback);
846 napiCb->ClearCallbackReference();
847 }
848
GetPropertyBool(napi_env env,napi_value configObj,const std::string & type,bool & result)849 bool SoundPoolNapi::GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result)
850 {
851 napi_value item = nullptr;
852 bool exist = false;
853 napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
854 if (status != napi_ok || !exist) {
855 MEDIA_LOGE("can not find %{public}s property", type.c_str());
856 return false;
857 }
858
859 if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
860 MEDIA_LOGE("get %{public}s property fail", type.c_str());
861 return false;
862 }
863
864 if (napi_get_value_bool(env, item, &result) != napi_ok) {
865 MEDIA_LOGE("get %{public}s property value fail", type.c_str());
866 return false;
867 }
868 return true;
869 }
870
GetRetInfo(int32_t errCode,const std::string & operate,const std::string & param,const std::string & add="")871 RetInfo GetRetInfo(int32_t errCode, const std::string &operate, const std::string ¶m, const std::string &add = "")
872 {
873 MEDIA_LOGE("failed to %{public}s, param %{public}s, errCode = %{public}d", operate.c_str(), param.c_str(), errCode);
874 MediaServiceExtErrCodeAPI9 err = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errCode));
875 if (errCode == MSERR_UNSUPPORT_VID_PARAMS) {
876 return RetInfo(err, "The video parameter is not supported. Please check the type and range.");
877 }
878
879 if (errCode == MSERR_UNSUPPORT_AUD_PARAMS) {
880 return RetInfo(err, "The audio parameter is not supported. Please check the type and range.");
881 }
882
883 std::string message;
884 if (err == MSERR_EXT_API9_INVALID_PARAMETER) {
885 message = MSExtErrorAPI9ToString(err, param, "") + add;
886 } else {
887 message = MSExtErrorAPI9ToString(err, operate, "") + add;
888 }
889
890 MEDIA_LOGE("errCode: %{public}d, errMsg: %{public}s", err, message.c_str());
891 return RetInfo(err, message);
892 }
893
SoundPoolAsyncSignError(int32_t errCode,const std::string & operate,const std::string & param,const std::string & add)894 void SoundPoolAsyncContext::SoundPoolAsyncSignError(int32_t errCode, const std::string &operate,
895 const std::string ¶m, const std::string &add)
896 {
897 RetInfo retInfo = GetRetInfo(errCode, operate, param, add);
898 SignError(retInfo.first, retInfo.second);
899 }
900 } // namespace Media
901 } // namespace OHOS