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
309 return result;
310 }
311
JsSetLoop(napi_env env, napi_callback_info info)312 napi_value SoundPoolNapi::JsSetLoop(napi_env env, napi_callback_info info)
313 {
314 MediaTrace trace("SoundPool::JsSetLoop");
315 MEDIA_LOGI("SoundPoolNapi::JsSetLoop");
316 size_t argCount = PARAM3;
317 napi_value args[PARAM3] = { nullptr };
318
319 napi_value result = nullptr;
320 napi_get_undefined(env, &result);
321
322 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
323 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
324 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
325 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
326 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
327
328 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM2]);
329 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
330 napi_status status = napi_get_value_int32(env, args[PARAM0], &asyncCtx->streamId_);
331 if (status != napi_ok || asyncCtx->streamId_ <= 0) {
332 asyncCtx->SignError(MSERR_EXT_API9_INVALID_PARAMETER, "SetLoop streamId failed,invaild value");
333 }
334 status = napi_get_value_int32(env, args[PARAM1], &asyncCtx->loop_);
335 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "failed to setloop id");
336
337 napi_value resource = nullptr;
338 napi_create_string_utf8(env, "JsSetLoop", NAPI_AUTO_LENGTH, &resource);
339 if (status == napi_ok && asyncCtx->streamId_ > 0) {
340 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
341 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
342 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
343 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
344 int32_t ret = asyncCtx->soundPool_->SetLoop(asyncCtx->streamId_, asyncCtx->loop_);
345 if (ret != MSERR_OK) {
346 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "setLoop streamId failed");
347 }
348 MEDIA_LOGI("The js thread of SetLoop finishes execution and returns");
349 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
350 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
351 } else {
352 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
353 MEDIA_LOGD("JsSetLoop napi_create_async_work");
354 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
355 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
356 }
357 asyncCtx.release();
358 return result;
359 }
360
JsSetPriority(napi_env env, napi_callback_info info)361 napi_value SoundPoolNapi::JsSetPriority(napi_env env, napi_callback_info info)
362 {
363 MediaTrace trace("SoundPool::JsSetPriority");
364 MEDIA_LOGI("SoundPoolNapi::JsSetPriority");
365 size_t argCount = PARAM3;
366 napi_value args[PARAM3] = { nullptr };
367
368 napi_value result = nullptr;
369 napi_get_undefined(env, &result);
370
371 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
372 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
373 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
374 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
375 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
376
377 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM2]);
378 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
379 napi_status status = napi_get_value_int32(env, args[PARAM0], &asyncCtx->streamId_);
380 if (status != napi_ok || asyncCtx->streamId_ <= 0) {
381 asyncCtx->SignError(MSERR_EXT_API9_INVALID_PARAMETER, "SetPriority streamId failed");
382 }
383 status = napi_get_value_int32(env, args[PARAM1], &asyncCtx->priority_);
384 if (status != napi_ok || asyncCtx->priority_ < 0) {
385 asyncCtx->SignError(MSERR_EXT_API9_INVALID_PARAMETER, "SetPriority priority failed");
386 }
387
388 napi_value resource = nullptr;
389 napi_create_string_utf8(env, "JsSetPriority", NAPI_AUTO_LENGTH, &resource);
390 if (status == napi_ok && asyncCtx->streamId_ > 0) {
391 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
392 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
393 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
394 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
395 int32_t ret = asyncCtx->soundPool_->SetPriority(asyncCtx->streamId_, asyncCtx->priority_);
396 if (ret != MSERR_OK) {
397 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "SetPriority streamId failed");
398 }
399 MEDIA_LOGI("The js thread of SetPriority finishes execution and returns");
400 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
401 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
402 } else {
403 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
404 MEDIA_LOGD("JsSetPriority napi_create_async_work");
405 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
406 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
407 }
408 asyncCtx.release();
409 return result;
410 }
411
JsSetRate(napi_env env, napi_callback_info info)412 napi_value SoundPoolNapi::JsSetRate(napi_env env, napi_callback_info info)
413 {
414 MediaTrace trace("SoundPool::JsSetRate");
415 MEDIA_LOGI("SoundPoolNapi::JsSetRate");
416 size_t argCount = PARAM3;
417 napi_value args[PARAM3] = { nullptr };
418
419 napi_value result = nullptr;
420 napi_get_undefined(env, &result);
421
422 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
423 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
424 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
425 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
426 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
427
428 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM2]);
429 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
430 napi_value resource = nullptr;
431 napi_create_string_utf8(env, "JsSetRate", NAPI_AUTO_LENGTH, &resource);
432 if (asyncCtx->napi->ParserRateOptionFromJs(asyncCtx, env, args) == MSERR_OK) {
433 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
434 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
435 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
436 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
437 int32_t ret = asyncCtx->soundPool_->SetRate(asyncCtx->streamId_, asyncCtx->renderRate_);
438 if (ret != MSERR_OK) {
439 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "SetRate streamId failed");
440 }
441 MEDIA_LOGI("The js thread of SetRate finishes execution and returns");
442 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
443 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
444 } else {
445 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
446 MEDIA_LOGD("JsSetRate napi_create_async_work");
447 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
448 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
449 }
450 asyncCtx.release();
451 return result;
452 }
453
JsSetVolume(napi_env env, napi_callback_info info)454 napi_value SoundPoolNapi::JsSetVolume(napi_env env, napi_callback_info info)
455 {
456 MediaTrace trace("SoundPool::JsSetVolume");
457 MEDIA_LOGI("SoundPoolNapi::JsSetVolume");
458 size_t argCount = PARAM4;
459 napi_value args[PARAM4] = { nullptr };
460
461 napi_value result = nullptr;
462 napi_get_undefined(env, &result);
463
464 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
465 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
466 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
467 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
468 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
469
470 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM3]);
471 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
472 napi_value resource = nullptr;
473 napi_create_string_utf8(env, "JsSetVolume", NAPI_AUTO_LENGTH, &resource);
474 if (asyncCtx->napi->ParserVolumeOptionFromJs(asyncCtx, env, args) == MSERR_OK) {
475 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
476 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
477 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
478 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
479 int32_t ret = asyncCtx->soundPool_->SetVolume(asyncCtx->streamId_,
480 asyncCtx->leftVolume_, asyncCtx->rightVolume_);
481 if (ret != MSERR_OK) {
482 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "setVolume streamId failed");
483 }
484 MEDIA_LOGI("The js thread of SetVolume finishes execution and returns");
485 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
486 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
487 } else {
488 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
489 MEDIA_LOGD("JsSetVolume napi_create_async_work");
490 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
491 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
492 }
493 asyncCtx.release();
494 return result;
495 }
496
JsUnload(napi_env env, napi_callback_info info)497 napi_value SoundPoolNapi::JsUnload(napi_env env, napi_callback_info info)
498 {
499 MediaTrace trace("SoundPool::JsUnload");
500 MEDIA_LOGI("SoundPoolNapi::JsUnload");
501 size_t argCount = PARAM2;
502 napi_value args[PARAM2] = { nullptr };
503
504 napi_value result = nullptr;
505 napi_get_undefined(env, &result);
506
507 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
508 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
509 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
510 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
511 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
512
513 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM1]);
514 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
515 napi_status status = napi_get_value_int32(env, args[PARAM0], &asyncCtx->soundId_);
516 if (status != napi_ok || asyncCtx->soundId_ <= 0) {
517 asyncCtx->SignError(MSERR_EXT_API9_IO, "unLoad failed,inavild value");
518 }
519
520 napi_value resource = nullptr;
521 napi_create_string_utf8(env, "JsUnload", NAPI_AUTO_LENGTH, &resource);
522 if (status == napi_ok && asyncCtx->soundId_ > 0) {
523 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
524 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
525 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
526 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
527 int32_t ret = asyncCtx->soundPool_->Unload(asyncCtx->soundId_);
528 if (ret != MSERR_OK) {
529 asyncCtx->SignError(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "unLoad soundID failed");
530 }
531 MEDIA_LOGI("The js thread of Unload finishes execution and returns, soundID: %{public}d",
532 asyncCtx->soundId_);
533 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
534 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
535 } else {
536 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
537 MEDIA_LOGD("JsUnload napi_create_async_work");
538 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
539 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
540 }
541 asyncCtx.release();
542
543 return result;
544 }
545
JsRelease(napi_env env, napi_callback_info info)546 napi_value SoundPoolNapi::JsRelease(napi_env env, napi_callback_info info)
547 {
548 MediaTrace trace("SoundPool::JsRelease");
549 MEDIA_LOGI("SoundPoolNapi::JsRelease");
550 size_t argCount = PARAM1;
551 napi_value args[PARAM1] = { nullptr };
552
553 napi_value result = nullptr;
554 napi_get_undefined(env, &result);
555
556 auto asyncCtx = std::make_unique<SoundPoolAsyncContext>(env);
557 CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get SoundPoolAsyncContext");
558 asyncCtx->napi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
559 CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
560 asyncCtx->soundPool_ = asyncCtx->napi->soundPool_;
561
562 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM0]);
563 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
564
565 napi_value resource = nullptr;
566 napi_create_string_utf8(env, "JsRelease", NAPI_AUTO_LENGTH, &resource);
567 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
568 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
569 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
570 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
571 int32_t ret = asyncCtx->soundPool_->Release();
572 CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Release failed!");
573 asyncCtx->napi->CancelCallback();
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_ERROR) {
606 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "SetEventCallback");
607 return result;
608 }
609
610 napi_ref ref = nullptr;
611 napi_status status = napi_create_reference(env, args[1], 1, &ref);
612 CHECK_AND_RETURN_RET_LOG(status == napi_ok && ref != nullptr, result, "failed to create reference!");
613
614 std::shared_ptr<AutoRef> autoRef = std::make_shared<AutoRef>(env, ref);
615 soundPoolNapi->SetCallbackReference(callbackName, autoRef);
616
617 MEDIA_LOGI("JsSetOnCallback callbackName: %{public}s success", callbackName.c_str());
618 return result;
619 }
620
JsClearOnCallback(napi_env env, napi_callback_info info)621 napi_value SoundPoolNapi::JsClearOnCallback(napi_env env, napi_callback_info info)
622 {
623 MediaTrace trace("SoundPool::JsClearOnCallback");
624 MEDIA_LOGI("SoundPoolNapi::JsClearOnCallback");
625 napi_value result = nullptr;
626 napi_get_undefined(env, &result);
627
628 size_t argCount = 1;
629 napi_value args[1] = { nullptr };
630 SoundPoolNapi *soundPoolNapi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
631 CHECK_AND_RETURN_RET_LOG(soundPoolNapi != nullptr, result, "Failed to retrieve instance");
632
633 napi_valuetype valueType0 = napi_undefined;
634 if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string) {
635 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "CancelEventCallback");
636 return result;
637 }
638
639 std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
640 if (callbackName != SoundPoolEvent::EVENT_LOAD_COMPLETED && callbackName != SoundPoolEvent::EVENT_PLAY_FINISHED &&
641 callbackName != SoundPoolEvent::EVENT_ERROR) {
642 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "CancelEventCallback");
643 return result;
644 }
645
646 soundPoolNapi->CancelCallbackReference(callbackName);
647
648 MEDIA_LOGI("0x%{public}06" PRIXPTR " JsClearOnCallback success", FAKE_POINTER(soundPoolNapi));
649 return result;
650 }
651
GetJsInstanceAndArgs(napi_env env, napi_callback_info info, size_t &argCount, napi_value *args)652 SoundPoolNapi* SoundPoolNapi::GetJsInstanceAndArgs(napi_env env, napi_callback_info info,
653 size_t &argCount, napi_value *args)
654 {
655 napi_value jsThis = nullptr;
656 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
657 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr, "failed to napi_get_cb_info");
658 MEDIA_LOGI("0x:%{public}06" PRIXPTR " instance argCount:%{public}zu", FAKE_POINTER(jsThis), argCount);
659
660 SoundPoolNapi *soundPoolNapi = nullptr;
661
662 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&soundPoolNapi));
663 CHECK_AND_RETURN_RET_LOG(status == napi_ok && soundPoolNapi != nullptr, nullptr, "failed to retrieve instance");
664
665 return soundPoolNapi;
666 }
667
GetJsInstanceWithParameter(napi_env env, napi_value *argv)668 napi_status SoundPoolNapi::GetJsInstanceWithParameter(napi_env env, napi_value *argv)
669 {
670 napi_status status = napi_get_value_int32(env, argv[PARAM0], &maxStreams); // get maxStreams
671 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "failed to get napi maxStreams");
672
673 napi_value tempValue = nullptr;
674 int32_t intValue = {0};
675 status = napi_get_named_property(env, argv[PARAM1], "content", &tempValue);
676 if (status == napi_ok) {
677 napi_get_value_int32(env, tempValue, &intValue);
678 rendererInfo.contentType = static_cast<AudioStandard::ContentType>(intValue);
679 }
680
681 status = napi_get_named_property(env, argv[PARAM1], "usage", &tempValue);
682 if (status == napi_ok) {
683 napi_get_value_int32(env, tempValue, &intValue);
684 rendererInfo.streamUsage = static_cast<AudioStandard::StreamUsage>(intValue);
685 }
686
687 status = napi_get_named_property(env, argv[PARAM1], "rendererFlags", &tempValue);
688 if (status == napi_ok) {
689 napi_get_value_int32(env, tempValue, &(rendererInfo.rendererFlags));
690 }
691
692 return status;
693 }
694
ParserLoadOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx, napi_env env, napi_value *argv, size_t argCount)695 int32_t SoundPoolNapi::ParserLoadOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
696 napi_env env, napi_value *argv, size_t argCount)
697 {
698 int32_t ret = MSERR_OK;
699 MEDIA_LOGI("ParserLoadOptionFromJs argCount %{public}zu", argCount);
700 if ((argCount < PARAM3) && (argCount > 0)) {
701 asyncCtx->url_ = CommonNapi::GetStringArgument(env, argv[PARAM0]);
702 CHECK_AND_RETURN_RET(asyncCtx->url_ != "",
703 (asyncCtx->SoundPoolAsyncSignError(MSERR_OPEN_FILE_FAILED, "geturl", "url"), MSERR_OPEN_FILE_FAILED));
704 } else if ((argCount >= PARAM3) && (argCount < MAX_PARAM)) {
705 napi_status status = napi_get_value_int32(env, argv[PARAM0], &asyncCtx->fd_);
706 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->fd_ > 0),
707 (asyncCtx->SoundPoolAsyncSignError(MSERR_OPEN_FILE_FAILED, "getfd", "fd"), MSERR_OPEN_FILE_FAILED));
708
709 status = napi_get_value_int64(env, argv[PARAM1], &asyncCtx->offset_);
710 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->offset_ >= 0),
711 (asyncCtx->SoundPoolAsyncSignError(MSERR_OPEN_FILE_FAILED, "getoffset", "offset"), MSERR_OPEN_FILE_FAILED));
712
713 status = napi_get_value_int64(env, argv[PARAM2], &asyncCtx->length_);
714 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->length_ > 0),
715 (asyncCtx->SoundPoolAsyncSignError(MSERR_OPEN_FILE_FAILED, "getlength", "length"), MSERR_OPEN_FILE_FAILED));
716 } else {
717 MEDIA_LOGI("Get Value error,return error:MSERR_INVALID_VAL");
718 return MSERR_INVALID_VAL;
719 }
720 return ret;
721 }
722
GetAbilityContext(napi_env env)723 static std::shared_ptr<AbilityRuntime::Context> GetAbilityContext(napi_env env)
724 {
725 auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
726 if (ability == nullptr) {
727 MEDIA_LOGE("Failed to obtain ability in FA mode");
728 return nullptr;
729 }
730 auto faContext = ability->GetAbilityContext();
731 if (faContext == nullptr) {
732 MEDIA_LOGE("GetAbilityContext returned null in FA model");
733 return nullptr;
734 }
735 return faContext;
736 }
737
ParserPlayOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx, napi_env env, napi_value *argv, size_t argCount)738 int32_t SoundPoolNapi::ParserPlayOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
739 napi_env env, napi_value *argv, size_t argCount)
740 {
741 int32_t ret = MSERR_OK;
742 MEDIA_LOGI("ParserPlayOptionFromJs argCount %{public}zu", argCount);
743 napi_status status = napi_get_value_int32(env, argv[PARAM0], &asyncCtx->soundId_);
744 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->soundId_ > 0),
745 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getplaysoundId", "soundId"), MSERR_INVALID_VAL));
746
747 CommonNapi::GetPropertyInt32(env, argv[PARAM1], "loop", asyncCtx->playParameters_.loop);
748 CommonNapi::GetPropertyInt32(env, argv[PARAM1], "rate", asyncCtx->playParameters_.rate);
749 double leftVolume;
750 ret = CommonNapi::GetPropertyDouble(env, argv[PARAM1], "leftVolume", leftVolume);
751 if (ret > 0) {
752 asyncCtx->playParameters_.leftVolume = static_cast<float>(leftVolume);
753 }
754 ret = CommonNapi::GetPropertyDouble(env, argv[PARAM1], "rightVolume", leftVolume);
755 if (ret > 0) {
756 asyncCtx->playParameters_.rightVolume = static_cast<float>(leftVolume);
757 }
758 CommonNapi::GetPropertyInt32(env, argv[PARAM1], "priority", asyncCtx->playParameters_.priority);
759 GetPropertyBool(env, argv[PARAM1], "parallelPlayFlag", asyncCtx->playParameters_.parallelPlayFlag);
760
761 std::shared_ptr<AbilityRuntime::Context> abilityContext = GetAbilityContext(env);
762 if (abilityContext != nullptr) {
763 asyncCtx->playParameters_.cacheDir = abilityContext->GetCacheDir();
764 } else {
765 asyncCtx->playParameters_.cacheDir = "/data/storage/el2/base/temp";
766 }
767 MEDIA_LOGI("playParameters_ loop:%{public}d, rate:%{public}d, leftVolume:%{public}f, rightvolume:%{public}f,"
768 "priority:%{public}d, parallelPlayFlag:%{public}d", asyncCtx->playParameters_.loop,
769 asyncCtx->playParameters_.rate, asyncCtx->playParameters_.leftVolume,
770 asyncCtx->playParameters_.rightVolume, asyncCtx->playParameters_.priority,
771 asyncCtx->playParameters_.parallelPlayFlag);
772 return MSERR_OK;
773 }
774
ParserRateOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx, napi_env env, napi_value *argv)775 int32_t SoundPoolNapi::ParserRateOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
776 napi_env env, napi_value *argv)
777 {
778 int32_t ret = MSERR_OK;
779 napi_status status = napi_get_value_int32(env, argv[PARAM0], &asyncCtx->streamId_);
780 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->streamId_ > 0),
781 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getratestreamId", "streamId"), MSERR_INVALID_VAL));
782 int32_t rendderRate;
783 status = napi_get_value_int32(env, argv[PARAM1], &rendderRate);
784 CHECK_AND_RETURN_RET(status == napi_ok,
785 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getaudiorennderrate",
786 "audiorennderrate"), MSERR_INVALID_VAL));
787 asyncCtx->renderRate_ = static_cast<AudioStandard::AudioRendererRate>(rendderRate);
788
789 return ret;
790 }
791
ParserVolumeOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx, napi_env env, napi_value *argv)792 int32_t SoundPoolNapi::ParserVolumeOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
793 napi_env env, napi_value *argv)
794 {
795 int32_t ret = MSERR_OK;
796 napi_status status = napi_get_value_int32(env, argv[PARAM0], &asyncCtx->streamId_);
797 CHECK_AND_RETURN_RET((status == napi_ok && asyncCtx->streamId_ > 0),
798 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getvolumestreamId", "streamId"), MSERR_INVALID_VAL));
799 double tempvolume;
800 status = napi_get_value_double(env, argv[PARAM1], &tempvolume);
801 CHECK_AND_RETURN_RET(status == napi_ok,
802 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getleftvolme", "leftvolme"), MSERR_INVALID_VAL));
803 asyncCtx->leftVolume_ = static_cast<float>(tempvolume);
804
805 status = napi_get_value_double(env, argv[PARAM2], &tempvolume);
806 CHECK_AND_RETURN_RET(status == napi_ok,
807 (asyncCtx->SoundPoolAsyncSignError(MSERR_INVALID_VAL, "getrightvolme", "rightvolme"), MSERR_INVALID_VAL));
808 asyncCtx->rightVolume_ = static_cast<float>(tempvolume);
809
810 return ret;
811 }
812
ErrorCallback(int32_t errCode, const std::string &operate, const std::string &add)813 void SoundPoolNapi::ErrorCallback(int32_t errCode, const std::string &operate, const std::string &add)
814 {
815 MEDIA_LOGE("failed to %{public}s, errCode = %{public}d", operate.c_str(), errCode);
816 CHECK_AND_RETURN_LOG(callbackNapi_ != nullptr, "soundpoolCb_ is nullptr!");
817 auto napiCb = std::static_pointer_cast<SoundPoolCallBackNapi>(callbackNapi_);
818
819 MediaServiceExtErrCodeAPI9 err = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errCode));
820 std::string msg = MSExtErrorAPI9ToString(err, operate, "") + add;
821 napiCb->SendErrorCallback(errCode, msg);
822 }
823
SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref)824 void SoundPoolNapi::SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref)
825 {
826 eventCbMap_[callbackName] = ref;
827 CHECK_AND_RETURN_LOG(callbackNapi_ != nullptr, "soundpoolCb_ is nullptr!");
828 auto napiCb = std::static_pointer_cast<SoundPoolCallBackNapi>(callbackNapi_);
829 napiCb->SaveCallbackReference(callbackName, ref);
830 }
831
CancelCallbackReference(const std::string &callbackName)832 void SoundPoolNapi::CancelCallbackReference(const std::string &callbackName)
833 {
834 CHECK_AND_RETURN_LOG(callbackNapi_ != nullptr, "soundpoolCb_ is nullptr!");
835 auto napiCb = std::static_pointer_cast<SoundPoolCallBackNapi>(callbackNapi_);
836 napiCb->CancelCallbackReference(callbackName);
837 eventCbMap_[callbackName] = nullptr;
838 }
839
CancelCallback()840 void SoundPoolNapi::CancelCallback()
841 {
842 CHECK_AND_RETURN_LOG(callbackNapi_ != nullptr, "soundpoolCb_ is nullptr!");
843 auto napiCb = std::static_pointer_cast<SoundPoolCallBackNapi>(callbackNapi_);
844 napiCb->ClearCallbackReference();
845 }
846
GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result)847 bool SoundPoolNapi::GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result)
848 {
849 napi_value item = nullptr;
850 bool exist = false;
851 napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
852 if (status != napi_ok || !exist) {
853 MEDIA_LOGE("can not find %{public}s property", type.c_str());
854 return false;
855 }
856
857 if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
858 MEDIA_LOGE("get %{public}s property fail", type.c_str());
859 return false;
860 }
861
862 if (napi_get_value_bool(env, item, &result) != napi_ok) {
863 MEDIA_LOGE("get %{public}s property value fail", type.c_str());
864 return false;
865 }
866 return true;
867 }
868
GetRetInfo(int32_t errCode, const std::string &operate, const std::string ¶m, const std::string &add = �)869 RetInfo GetRetInfo(int32_t errCode, const std::string &operate, const std::string ¶m, const std::string &add = "")
870 {
871 MEDIA_LOGE("failed to %{public}s, param %{public}s, errCode = %{public}d", operate.c_str(), param.c_str(), errCode);
872 MediaServiceExtErrCodeAPI9 err = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errCode));
873 if (errCode == MSERR_UNSUPPORT_VID_PARAMS) {
874 return RetInfo(err, "The video parameter is not supported. Please check the type and range.");
875 }
876
877 if (errCode == MSERR_UNSUPPORT_AUD_PARAMS) {
878 return RetInfo(err, "The audio parameter is not supported. Please check the type and range.");
879 }
880
881 std::string message;
882 if (err == MSERR_EXT_API9_INVALID_PARAMETER) {
883 message = MSExtErrorAPI9ToString(err, param, "") + add;
884 } else {
885 message = MSExtErrorAPI9ToString(err, operate, "") + add;
886 }
887
888 MEDIA_LOGE("errCode: %{public}d, errMsg: %{public}s", err, message.c_str());
889 return RetInfo(err, message);
890 }
891
SoundPoolAsyncSignError(int32_t errCode, const std::string &operate, const std::string ¶m, const std::string &add)892 void SoundPoolAsyncContext::SoundPoolAsyncSignError(int32_t errCode, const std::string &operate,
893 const std::string ¶m, const std::string &add)
894 {
895 RetInfo retInfo = GetRetInfo(errCode, operate, param, add);
896 SignError(retInfo.first, retInfo.second);
897 }
898 } // namespace Media
899 } // namespace OHOS