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