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 asyncCtx->callbackNapi_ = asyncCtx->napi->callbackNapi_;
562
563 asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[PARAM0]);
564 asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
565
566 napi_value resource = nullptr;
567 napi_create_string_utf8(env, "JsRelease", NAPI_AUTO_LENGTH, &resource);
568 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
569 SoundPoolAsyncContext* asyncCtx = reinterpret_cast<SoundPoolAsyncContext *>(data);
570 CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
571 CHECK_AND_RETURN_LOG(asyncCtx->soundPool_ != nullptr, "soundPool_ is nullptr!");
572 int32_t ret = asyncCtx->soundPool_->Release();
573 CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Release failed!");
574 CHECK_AND_RETURN_LOG(asyncCtx->callbackNapi_ != nullptr, "release callbackNapi_ is nullptr!");
575 asyncCtx->napi->CancelCallback(asyncCtx->callbackNapi_);
576 MEDIA_LOGI("The js thread of JsRelease finishes execution and returns");
577 }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
578 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated));
579 asyncCtx.release();
580
581 return result;
582 }
583
JsSetOnCallback(napi_env env,napi_callback_info info)584 napi_value SoundPoolNapi::JsSetOnCallback(napi_env env, napi_callback_info info)
585 {
586 MediaTrace trace("SoundPool::JsSetOnCallback");
587 MEDIA_LOGI("SoundPoolNapi::JsSetOnCallback");
588 napi_value result = nullptr;
589 napi_get_undefined(env, &result);
590
591 size_t argCount = 2;
592 napi_value args[2] = { nullptr, nullptr };
593 SoundPoolNapi *soundPoolNapi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
594 CHECK_AND_RETURN_RET_LOG(soundPoolNapi != nullptr, result, "Failed to retrieve instance");
595
596 napi_valuetype valueType0 = napi_undefined;
597 napi_valuetype valueType1 = napi_undefined;
598 if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string ||
599 napi_typeof(env, args[1], &valueType1) != napi_ok || valueType1 != napi_function) {
600 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "SetEventCallback");
601 return result;
602 }
603
604 std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
605 MEDIA_LOGI("set callbackName: %{public}s", callbackName.c_str());
606 if (callbackName != SoundPoolEvent::EVENT_LOAD_COMPLETED && callbackName != SoundPoolEvent::EVENT_PLAY_FINISHED &&
607 callbackName != SoundPoolEvent::EVENT_ERROR) {
608 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "SetEventCallback");
609 return result;
610 }
611
612 napi_ref ref = nullptr;
613 napi_status status = napi_create_reference(env, args[1], 1, &ref);
614 CHECK_AND_RETURN_RET_LOG(status == napi_ok && ref != nullptr, result, "failed to create reference!");
615
616 std::shared_ptr<AutoRef> autoRef = std::make_shared<AutoRef>(env, ref);
617 soundPoolNapi->SetCallbackReference(callbackName, autoRef);
618
619 MEDIA_LOGI("JsSetOnCallback callbackName: %{public}s success", callbackName.c_str());
620 return result;
621 }
622
JsClearOnCallback(napi_env env,napi_callback_info info)623 napi_value SoundPoolNapi::JsClearOnCallback(napi_env env, napi_callback_info info)
624 {
625 MediaTrace trace("SoundPool::JsClearOnCallback");
626 MEDIA_LOGI("SoundPoolNapi::JsClearOnCallback");
627 napi_value result = nullptr;
628 napi_get_undefined(env, &result);
629
630 size_t argCount = 1;
631 napi_value args[1] = { nullptr };
632 SoundPoolNapi *soundPoolNapi = SoundPoolNapi::GetJsInstanceAndArgs(env, info, argCount, args);
633 CHECK_AND_RETURN_RET_LOG(soundPoolNapi != nullptr, result, "Failed to retrieve instance");
634
635 napi_valuetype valueType0 = napi_undefined;
636 if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string) {
637 soundPoolNapi->ErrorCallback(MSERR_INVALID_VAL, "CancelEventCallback");
638 return result;
639 }
640
641 std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
642 if (callbackName != SoundPoolEvent::EVENT_LOAD_COMPLETED && callbackName != SoundPoolEvent::EVENT_PLAY_FINISHED &&
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