1 /*
2  * Copyright (c) 2023 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 #ifndef LOG_TAG
16 #define LOG_TAG "NapiAudioManager"
17 #endif
18 
19 #include "napi_audio_manager.h"
20 #include "napi_audio_routing_manager.h"
21 #include "napi_audio_stream_manager.h"
22 #include "napi_audio_volume_manager.h"
23 #include "napi_audio_interrupt_manager.h"
24 #include "napi_audio_spatialization_manager.h"
25 #include "napi_audio_enum.h"
26 #include "napi_audio_error.h"
27 #include "napi_param_utils.h"
28 #include "audio_errors.h"
29 #include "audio_manager_log.h"
30 #include "audio_utils.h"
31 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
32 #include "xpower_event_js.h"
33 #endif
34 #include "napi_audio_manager_callbacks.h"
35 #include "napi_audio_ringermode_callback.h"
36 #include "napi_audio_manager_interrupt_callback.h"
37 #include "napi_audio_volume_key_event.h"
38 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
39 #include "napi_audio_session_manager.h"
40 #endif
41 
42 namespace OHOS {
43 namespace AudioStandard {
44 using namespace std;
45 using namespace HiviewDFX;
46 static __thread napi_ref g_managerConstructor = nullptr;
47 
NapiAudioManager()48 NapiAudioManager::NapiAudioManager()
49     : audioMngr_(nullptr), env_(nullptr) {}
50 
~NapiAudioManager()51 NapiAudioManager::~NapiAudioManager()
52 {
53     AUDIO_DEBUG_LOG("NapiAudioManager::~NapiAudioManager()");
54 }
55 
GetParamWithSync(const napi_env & env,napi_callback_info info,size_t & argc,napi_value * args)56 NapiAudioManager* NapiAudioManager::GetParamWithSync(const napi_env &env, napi_callback_info info,
57     size_t &argc, napi_value *args)
58 {
59     napi_status status;
60     NapiAudioManager *napiAudioManager = nullptr;
61     napi_value jsThis = nullptr;
62 
63     status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
64     CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr,
65         "GetParamWithSync fail to napi_get_cb_info");
66 
67     status = napi_unwrap(env, jsThis, (void **)&napiAudioManager);
68     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "napi_unwrap failed");
69     CHECK_AND_RETURN_RET_LOG(napiAudioManager != nullptr && napiAudioManager->audioMngr_ !=
70         nullptr, napiAudioManager, "GetParamWithSync fail to napi_unwrap");
71     return napiAudioManager;
72 }
73 
CheckContextStatus(std::shared_ptr<AudioManagerAsyncContext> context)74 bool NapiAudioManager::CheckContextStatus(std::shared_ptr<AudioManagerAsyncContext> context)
75 {
76     CHECK_AND_RETURN_RET_LOG(context != nullptr, false, "context object is nullptr.");
77     if (context->native == nullptr) {
78         context->SignError(NAPI_ERR_SYSTEM);
79         AUDIO_ERR_LOG("context object state is error.");
80         return false;
81     }
82     return true;
83 }
84 
CheckAudioManagerStatus(NapiAudioManager * napi,std::shared_ptr<AudioManagerAsyncContext> context)85 bool NapiAudioManager::CheckAudioManagerStatus(NapiAudioManager *napi,
86     std::shared_ptr<AudioManagerAsyncContext> context)
87 {
88     CHECK_AND_RETURN_RET_LOG(napi != nullptr, false, "napi object is nullptr.");
89     if (napi->audioMngr_ == nullptr) {
90         context->SignError(NAPI_ERR_SYSTEM);
91         AUDIO_ERR_LOG("audioMngr_ is nullptr.");
92         return false;
93     }
94     return true;
95 }
96 
InitNapiAudioManager(napi_env env,napi_value & constructor)97 napi_status NapiAudioManager::InitNapiAudioManager(napi_env env, napi_value &constructor)
98 {
99     napi_property_descriptor audio_svc_mngr_properties[] = {
100         DECLARE_NAPI_FUNCTION("setVolume", SetVolume),
101         DECLARE_NAPI_FUNCTION("getVolume", GetVolume),
102         DECLARE_NAPI_FUNCTION("getMaxVolume", GetMaxVolume),
103         DECLARE_NAPI_FUNCTION("getMinVolume", GetMinVolume),
104         DECLARE_NAPI_FUNCTION("getDevices", GetDevices),
105         DECLARE_NAPI_FUNCTION("mute", SetStreamMute),
106         DECLARE_NAPI_FUNCTION("isMute", IsStreamMute),
107         DECLARE_NAPI_FUNCTION("isActive", IsStreamActive),
108         DECLARE_NAPI_FUNCTION("setRingerMode", SetRingerMode),
109         DECLARE_NAPI_FUNCTION("getRingerMode", GetRingerMode),
110         DECLARE_NAPI_FUNCTION("setAudioScene", SetAudioScene),
111         DECLARE_NAPI_FUNCTION("getAudioScene", GetAudioScene),
112         DECLARE_NAPI_FUNCTION("getAudioSceneSync", GetAudioSceneSync),
113         DECLARE_NAPI_FUNCTION("setDeviceActive", SetDeviceActive),
114         DECLARE_NAPI_FUNCTION("isDeviceActive", IsDeviceActive),
115         DECLARE_NAPI_FUNCTION("setAudioParameter", SetAudioParameter),
116         DECLARE_NAPI_FUNCTION("getAudioParameter", GetAudioParameter),
117         DECLARE_NAPI_FUNCTION("setExtraParameters", SetExtraParameters),
118         DECLARE_NAPI_FUNCTION("getExtraParameters", GetExtraParameters),
119         DECLARE_NAPI_FUNCTION("setMicrophoneMute", SetMicrophoneMute),
120         DECLARE_NAPI_FUNCTION("isMicrophoneMute", IsMicrophoneMute),
121         DECLARE_NAPI_FUNCTION("requestIndependentInterrupt", RequestIndependentInterrupt),
122         DECLARE_NAPI_FUNCTION("abandonIndependentInterrupt", AbandonIndependentInterrupt),
123         DECLARE_NAPI_FUNCTION("on", On),
124         DECLARE_NAPI_FUNCTION("off", Off),
125         DECLARE_NAPI_FUNCTION("getStreamManager", GetStreamManager),
126 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
127         DECLARE_NAPI_FUNCTION("getSessionManager", GetSessionManager),
128 #endif
129         DECLARE_NAPI_FUNCTION("getRoutingManager", GetRoutingManager),
130         DECLARE_NAPI_FUNCTION("getVolumeManager", GetVolumeManager),
131         DECLARE_NAPI_FUNCTION("getInterruptManager", GetInterruptManager),
132         DECLARE_NAPI_FUNCTION("getSpatializationManager", GetSpatializationManager),
133         DECLARE_NAPI_FUNCTION("disableSafeMediaVolume", DisableSafeMediaVolume),
134     };
135 
136     napi_status status = napi_define_class(env, NAPI_AUDIO_MNGR_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
137         Construct, nullptr,
138         sizeof(audio_svc_mngr_properties) / sizeof(audio_svc_mngr_properties[PARAM0]),
139         audio_svc_mngr_properties, &constructor);
140     return status;
141 }
142 
Init(napi_env env,napi_value exports)143 napi_value NapiAudioManager::Init(napi_env env, napi_value exports)
144 {
145     AUDIO_DEBUG_LOG("Init");
146     napi_status status;
147     napi_value constructor;
148     napi_value result = nullptr;
149     const int32_t refCount = 1;
150 
151     napi_property_descriptor static_prop[] = {
152         DECLARE_NAPI_STATIC_FUNCTION("getAudioManager", GetAudioManager),
153     };
154 
155     status = InitNapiAudioManager(env, constructor);
156     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "InitNapiAudioRenderer fail");
157 
158     status = napi_create_reference(env, constructor, refCount, &g_managerConstructor);
159     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_reference fail");
160     status = napi_set_named_property(env, exports, NAPI_AUDIO_MNGR_CLASS_NAME.c_str(), constructor);
161     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_set_named_property fail");
162     status = napi_define_properties(env, exports, sizeof(static_prop) / sizeof(static_prop[PARAM0]),
163         static_prop);
164     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_define_properties fail");
165     return exports;
166 }
167 
Destructor(napi_env env,void * nativeObject,void * finalizeHint)168 void NapiAudioManager::Destructor(napi_env env, void *nativeObject, void *finalizeHint)
169 {
170     if (nativeObject != nullptr) {
171         auto obj = static_cast<NapiAudioManager*>(nativeObject);
172         ObjectRefMap<NapiAudioManager>::DecreaseRef(obj);
173         AUDIO_DEBUG_LOG("NapiAudioManager::Destructor delete NapiAudioManager obj done");
174     }
175 }
176 
Construct(napi_env env,napi_callback_info info)177 napi_value NapiAudioManager::Construct(napi_env env, napi_callback_info info)
178 {
179     napi_status status;
180     napi_value jsThis;
181     napi_value undefinedResult = nullptr;
182     NapiParamUtils::GetUndefinedValue(env);
183     size_t argCount = PARAM0;
184 
185     status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
186     if (status == napi_ok) {
187         unique_ptr<NapiAudioManager> managerNapi = make_unique<NapiAudioManager>();
188         if (managerNapi != nullptr) {
189             ObjectRefMap<NapiAudioManager>::Insert(managerNapi.get());
190             managerNapi->env_ = env;
191             managerNapi->audioMngr_ = AudioSystemManager::GetInstance();
192             managerNapi->cachedClientId_ = getpid();
193 
194             status = napi_wrap(env, jsThis, static_cast<void*>(managerNapi.get()),
195                                NapiAudioManager::Destructor, nullptr, nullptr);
196             if (status != napi_ok) {
197                 ObjectRefMap<NapiAudioManager>::Erase(managerNapi.get());
198                 return undefinedResult;
199             }
200             managerNapi.release();
201             return jsThis;
202         }
203     }
204     return undefinedResult;
205 }
206 
CreateAudioManagerWrapper(napi_env env)207 napi_value NapiAudioManager::CreateAudioManagerWrapper(napi_env env)
208 {
209     napi_status status;
210     napi_value result = nullptr;
211     napi_value constructor;
212 
213     status = napi_get_reference_value(env, g_managerConstructor, &constructor);
214     if (status != napi_ok) {
215         AUDIO_ERR_LOG("Failed in CreateAudioManagerWrapper, %{public}d", status);
216         goto fail;
217     }
218     status = napi_new_instance(env, constructor, 0, nullptr, &result);
219     if (status != napi_ok) {
220         AUDIO_ERR_LOG("napi_new_instance failed, status:%{public}d", status);
221         goto fail;
222     }
223     return result;
224 
225 fail:
226     napi_get_undefined(env, &result);
227     return result;
228 }
229 
GetAudioManager(napi_env env,napi_callback_info info)230 napi_value NapiAudioManager::GetAudioManager(napi_env env, napi_callback_info info)
231 {
232     napi_status status;
233     size_t argCount = PARAM0;
234 
235     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
236     if (status != napi_ok || argCount != 0) {
237         AUDIO_ERR_LOG("Invalid arguments!");
238         return nullptr;
239     }
240 
241     return NapiAudioManager::CreateAudioManagerWrapper(env);
242 }
243 
GetStreamManager(napi_env env,napi_callback_info info)244 napi_value NapiAudioManager::GetStreamManager(napi_env env, napi_callback_info info)
245 {
246     napi_status status;
247     size_t argCount = PARAM0;
248 
249     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
250     if (status != napi_ok || argCount != 0) {
251         AUDIO_ERR_LOG("Invalid arguments!");
252         return nullptr;
253     }
254 
255     return NapiAudioStreamMgr::CreateStreamManagerWrapper(env);
256 }
257 
258 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
GetSessionManager(napi_env env,napi_callback_info info)259 napi_value NapiAudioManager::GetSessionManager(napi_env env, napi_callback_info info)
260 {
261     napi_status status;
262     size_t argCount = PARAM0;
263 
264     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
265     if (status != napi_ok || argCount != 0) {
266         AUDIO_ERR_LOG("Invalid arguments!");
267         return nullptr;
268     }
269 
270     return NapiAudioSessionMgr::CreateSessionManagerWrapper(env);
271 }
272 #endif
273 
GetRoutingManager(napi_env env,napi_callback_info info)274 napi_value NapiAudioManager::GetRoutingManager(napi_env env, napi_callback_info info)
275 {
276     napi_status status;
277     size_t argCount = PARAM0;
278 
279     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
280     if (status != napi_ok || argCount != 0) {
281         AUDIO_ERR_LOG("Invalid arguments!");
282         return nullptr;
283     }
284 
285     return NapiAudioRoutingManager::CreateRoutingManagerWrapper(env);
286 }
287 
GetVolumeManager(napi_env env,napi_callback_info info)288 napi_value NapiAudioManager::GetVolumeManager(napi_env env, napi_callback_info info)
289 {
290     napi_status status;
291     size_t argCount = PARAM0;
292 
293     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
294     if (status != napi_ok || argCount != 0) {
295         AUDIO_ERR_LOG("Invalid arguments!");
296         return nullptr;
297     }
298 
299     return NapiAudioVolumeManager::CreateVolumeManagerWrapper(env);
300 }
301 
GetInterruptManager(napi_env env,napi_callback_info info)302 napi_value NapiAudioManager::GetInterruptManager(napi_env env, napi_callback_info info)
303 {
304     napi_status status;
305     size_t argCount = PARAM0;
306 
307     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
308     if (status != napi_ok || argCount != 0) {
309         AUDIO_ERR_LOG("Invalid arguments!");
310         return nullptr;
311     }
312 
313     return NapiAudioInterruptManager::CreateInterruptManagerWrapper(env);
314 }
315 
GetSpatializationManager(napi_env env,napi_callback_info info)316 napi_value NapiAudioManager::GetSpatializationManager(napi_env env, napi_callback_info info)
317 {
318     napi_status status;
319     size_t argCount = 0;
320     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
321         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
322 
323     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
324     if (status != napi_ok || argCount != 0) {
325         AUDIO_ERR_LOG("Invalid arguments!");
326         return nullptr;
327     }
328 
329     return NapiAudioSpatializationManager::CreateSpatializationManagerWrapper(env);
330 }
331 
SetVolume(napi_env env,napi_callback_info info)332 napi_value NapiAudioManager::SetVolume(napi_env env, napi_callback_info info)
333 {
334     auto context = std::make_shared<AudioManagerAsyncContext>();
335     if (context == nullptr) {
336         AUDIO_ERR_LOG("SetVolume failed : no memory");
337         NapiAudioError::ThrowError(env, "SetVolume failed : no memory", NAPI_ERR_NO_MEMORY);
338         return NapiParamUtils::GetUndefinedValue(env);
339     }
340 
341     auto inputParser = [env, context](size_t argc, napi_value *argv) {
342         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_TWO, "invalid arguments", NAPI_ERR_INVALID_PARAM);
343         context->status = NapiParamUtils::GetValueInt32(env, context->volType, argv[PARAM0]);
344         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volType failed", NAPI_ERR_INVALID_PARAM);
345         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentVolType(context->volType),
346             "get volType unsupport", NAPI_ERR_UNSUPPORTED);
347         context->status = NapiParamUtils::GetValueInt32(env, context->volLevel, argv[PARAM1]);
348         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volLevel failed", NAPI_ERR_INVALID_PARAM);
349     };
350     context->GetCbInfo(env, info, inputParser);
351 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
352     HiviewDFX::ReportXPowerJsStackSysEvent(env, "VOLUME_CHANGE", "SRC=Audio");
353 #endif
354 
355     auto executor = [context]() {
356         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
357         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
358         ObjectRefMap objectGuard(obj);
359         auto *napiAudioManager = objectGuard.GetPtr();
360         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
361             "audio manager state is error.");
362         context->intValue = napiAudioManager->audioMngr_->SetVolume(
363             NapiAudioEnum::GetNativeAudioVolumeType(context->volType), context->volLevel);
364         if (context->intValue != SUCCESS) {
365             context->SignError(context->intValue);
366         }
367     };
368 
369     auto complete = [env](napi_value &output) {
370         output = NapiParamUtils::GetUndefinedValue(env);
371     };
372     return NapiAsyncWork::Enqueue(env, context, "SetVolume", executor, complete);
373 }
374 
GetVolume(napi_env env,napi_callback_info info)375 napi_value NapiAudioManager::GetVolume(napi_env env, napi_callback_info info)
376 {
377     auto context = std::make_shared<AudioManagerAsyncContext>();
378     if (context == nullptr) {
379         AUDIO_ERR_LOG("GetVolume failed : no memory");
380         NapiAudioError::ThrowError(env, "GetVolume failed : no memory", NAPI_ERR_NO_MEMORY);
381         return NapiParamUtils::GetUndefinedValue(env);
382     }
383 
384     auto inputParser = [env, context](size_t argc, napi_value *argv) {
385         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
386         context->status = NapiParamUtils::GetValueInt32(env, context->volType, argv[PARAM0]);
387         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volType failed", NAPI_ERR_INVALID_PARAM);
388         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentVolType(context->volType),
389             "get volType unsupport", NAPI_ERR_UNSUPPORTED);
390     };
391     context->GetCbInfo(env, info, inputParser);
392 
393     auto executor = [context]() {
394         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
395         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
396         ObjectRefMap objectGuard(obj);
397         auto *napiAudioManager = objectGuard.GetPtr();
398         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
399             "audio manager state is error.");
400         context->volLevel = napiAudioManager->audioMngr_->GetVolume(
401             NapiAudioEnum::GetNativeAudioVolumeType(context->volType));
402     };
403 
404     auto complete = [env, context](napi_value &output) {
405         NapiParamUtils::SetValueInt32(env, context->volLevel, output);
406     };
407     return NapiAsyncWork::Enqueue(env, context, "GetVolume", executor, complete);
408 }
409 
GetMaxVolume(napi_env env,napi_callback_info info)410 napi_value NapiAudioManager::GetMaxVolume(napi_env env, napi_callback_info info)
411 {
412     auto context = std::make_shared<AudioManagerAsyncContext>();
413     if (context == nullptr) {
414         AUDIO_ERR_LOG("GetMaxVolume failed : no memory");
415         NapiAudioError::ThrowError(env, "GetMaxVolume failed : no memory", NAPI_ERR_NO_MEMORY);
416         return NapiParamUtils::GetUndefinedValue(env);
417     }
418 
419     auto inputParser = [env, context](size_t argc, napi_value *argv) {
420         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
421         context->status = NapiParamUtils::GetValueInt32(env, context->volType, argv[PARAM0]);
422         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volType failed", NAPI_ERR_INVALID_PARAM);
423         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentVolType(context->volType),
424             "get volType unsupport", NAPI_ERR_UNSUPPORTED);
425     };
426     context->GetCbInfo(env, info, inputParser);
427 
428     auto executor = [context]() {
429         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
430         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
431         ObjectRefMap objectGuard(obj);
432         auto *napiAudioManager = objectGuard.GetPtr();
433         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
434             "audio manager state is error.");
435         context->intValue = napiAudioManager->audioMngr_->GetMaxVolume(
436             NapiAudioEnum::GetNativeAudioVolumeType(context->volType));
437     };
438 
439     auto complete = [env, context](napi_value &output) {
440         NapiParamUtils::SetValueInt32(env, context->intValue, output);
441     };
442     return NapiAsyncWork::Enqueue(env, context, "GetMaxVolume", executor, complete);
443 }
444 
GetMinVolume(napi_env env,napi_callback_info info)445 napi_value NapiAudioManager::GetMinVolume(napi_env env, napi_callback_info info)
446 {
447     auto context = std::make_shared<AudioManagerAsyncContext>();
448     if (context == nullptr) {
449         AUDIO_ERR_LOG("GetMinVolume failed : no memory");
450         NapiAudioError::ThrowError(env, "GetMinVolume failed : no memory", NAPI_ERR_NO_MEMORY);
451         return NapiParamUtils::GetUndefinedValue(env);
452     }
453 
454     auto inputParser = [env, context](size_t argc, napi_value *argv) {
455         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
456         context->status = NapiParamUtils::GetValueInt32(env, context->volType, argv[PARAM0]);
457         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volType failed", NAPI_ERR_INVALID_PARAM);
458         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentVolType(context->volType),
459             "get volType unsupport", NAPI_ERR_UNSUPPORTED);
460     };
461     context->GetCbInfo(env, info, inputParser);
462 
463     auto executor = [context]() {
464         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
465         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
466         ObjectRefMap objectGuard(obj);
467         auto *napiAudioManager = objectGuard.GetPtr();
468         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
469             "audio manager state is error.");
470         context->intValue = napiAudioManager->audioMngr_->GetMinVolume(
471             NapiAudioEnum::GetNativeAudioVolumeType(context->volType));
472     };
473 
474     auto complete = [env, context](napi_value &output) {
475         NapiParamUtils::SetValueInt32(env, context->intValue, output);
476     };
477     return NapiAsyncWork::Enqueue(env, context, "GetMinVolume", executor, complete);
478 }
479 
GetDevices(napi_env env,napi_callback_info info)480 napi_value NapiAudioManager::GetDevices(napi_env env, napi_callback_info info)
481 {
482     auto context = std::make_shared<AudioManagerAsyncContext>();
483     if (context == nullptr) {
484         AUDIO_ERR_LOG("GetDevices failed : no memory");
485         NapiAudioError::ThrowError(env, "GetDevices failed : no memory", NAPI_ERR_NO_MEMORY);
486         return NapiParamUtils::GetUndefinedValue(env);
487     }
488 
489     auto inputParser = [env, context](size_t argc, napi_value *argv) {
490         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
491         context->status = NapiParamUtils::GetValueInt32(env, context->deviceFlag, argv[PARAM0]);
492         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get deviceFlag failed",
493             NAPI_ERR_INVALID_PARAM);
494         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentDeviceFlag(context->deviceFlag),
495             "get deviceFlag unsupport", NAPI_ERR_UNSUPPORTED);
496     };
497     context->GetCbInfo(env, info, inputParser);
498 
499     auto executor = [context]() {
500         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
501         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
502         ObjectRefMap objectGuard(obj);
503         auto *napiAudioManager = objectGuard.GetPtr();
504         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
505             "audio manager state is error.");
506         context->deviceDescriptors = napiAudioManager->audioMngr_->GetDevices(
507             static_cast<DeviceFlag>(context->deviceFlag));
508     };
509 
510     auto complete = [env, context](napi_value &output) {
511         NapiParamUtils::SetDeviceDescriptors(env, context->deviceDescriptors, output);
512     };
513     return NapiAsyncWork::Enqueue(env, context, "GetDevices", executor, complete);
514 }
515 
SetStreamMute(napi_env env,napi_callback_info info)516 napi_value NapiAudioManager::SetStreamMute(napi_env env, napi_callback_info info)
517 {
518     auto context = std::make_shared<AudioManagerAsyncContext>();
519     if (context == nullptr) {
520         AUDIO_ERR_LOG("SetStreamMute failed : no memory");
521         NapiAudioError::ThrowError(env, "SetStreamMute failed : no memory", NAPI_ERR_NO_MEMORY);
522         return NapiParamUtils::GetUndefinedValue(env);
523     }
524 
525     auto inputParser = [env, context](size_t argc, napi_value *argv) {
526         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_TWO, "invalid arguments", NAPI_ERR_INVALID_PARAM);
527         context->status = NapiParamUtils::GetValueInt32(env, context->volType, argv[PARAM0]);
528         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volType failed",
529             NAPI_ERR_INVALID_PARAM);
530         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentVolType(context->volType),
531             "get volType unsupport", NAPI_ERR_UNSUPPORTED);
532         context->status = NapiParamUtils::GetValueBoolean(env, context->isMute, argv[PARAM1]);
533         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get ismute failed", NAPI_ERR_INVALID_PARAM);
534     };
535     context->GetCbInfo(env, info, inputParser);
536 
537     auto executor = [context]() {
538         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
539         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
540         ObjectRefMap objectGuard(obj);
541         auto *napiAudioManager = objectGuard.GetPtr();
542         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
543             "audio manager state is error.");
544         context->intValue = napiAudioManager->audioMngr_->SetMute(
545             NapiAudioEnum::GetNativeAudioVolumeType(context->volType), context->isMute);
546         NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SetMute failed", NAPI_ERR_SYSTEM);
547     };
548 
549     auto complete = [env](napi_value &output) {
550         output = NapiParamUtils::GetUndefinedValue(env);
551     };
552     return NapiAsyncWork::Enqueue(env, context, "SetStreamMute", executor, complete);
553 }
554 
IsStreamMute(napi_env env,napi_callback_info info)555 napi_value NapiAudioManager::IsStreamMute(napi_env env, napi_callback_info info)
556 {
557     auto context = std::make_shared<AudioManagerAsyncContext>();
558     if (context == nullptr) {
559         AUDIO_ERR_LOG("IsStreamMute failed : no memory");
560         NapiAudioError::ThrowError(env, "IsStreamMute failed : no memory", NAPI_ERR_NO_MEMORY);
561         return NapiParamUtils::GetUndefinedValue(env);
562     }
563 
564     auto inputParser = [env, context](size_t argc, napi_value *argv) {
565         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
566         context->status = NapiParamUtils::GetValueInt32(env, context->volType, argv[PARAM0]);
567         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volType failed",
568             NAPI_ERR_INVALID_PARAM);
569         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentVolType(context->volType),
570             "get volType unsupport", NAPI_ERR_UNSUPPORTED);
571     };
572     context->GetCbInfo(env, info, inputParser);
573 
574     auto executor = [context]() {
575         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
576         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
577         ObjectRefMap objectGuard(obj);
578         auto *napiAudioManager = objectGuard.GetPtr();
579         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
580             "audio manager state is error.");
581         context->isMute = napiAudioManager->audioMngr_->IsStreamMute(
582             NapiAudioEnum::GetNativeAudioVolumeType(context->volType));
583     };
584 
585     auto complete = [env, context](napi_value &output) {
586         NapiParamUtils::SetValueBoolean(env, context->isMute, output);
587     };
588     return NapiAsyncWork::Enqueue(env, context, "IsStreamMute", executor, complete);
589 }
590 
IsStreamActive(napi_env env,napi_callback_info info)591 napi_value NapiAudioManager::IsStreamActive(napi_env env, napi_callback_info info)
592 {
593     auto context = std::make_shared<AudioManagerAsyncContext>();
594     if (context == nullptr) {
595         AUDIO_ERR_LOG("IsStreamActive failed : no memory");
596         NapiAudioError::ThrowError(env, "IsStreamActive failed : no memory", NAPI_ERR_NO_MEMORY);
597         return NapiParamUtils::GetUndefinedValue(env);
598     }
599 
600     auto inputParser = [env, context](size_t argc, napi_value *argv) {
601         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
602         context->status = NapiParamUtils::GetValueInt32(env, context->volType, argv[PARAM0]);
603         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volType failed",
604             NAPI_ERR_INVALID_PARAM);
605         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentVolType(context->volType),
606             "get volType unsupport", NAPI_ERR_UNSUPPORTED);
607     };
608     context->GetCbInfo(env, info, inputParser);
609 
610     auto executor = [context]() {
611         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
612         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
613         ObjectRefMap objectGuard(obj);
614         auto *napiAudioManager = objectGuard.GetPtr();
615         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
616             "audio manager state is error.");
617         context->isActive = napiAudioManager->audioMngr_->IsStreamActive(
618             NapiAudioEnum::GetNativeAudioVolumeType(context->volType));
619     };
620 
621     auto complete = [env, context](napi_value &output) {
622         NapiParamUtils::SetValueBoolean(env, context->isActive, output);
623     };
624     return NapiAsyncWork::Enqueue(env, context, "IsStreamActive", executor, complete);
625 }
626 
SetRingerMode(napi_env env,napi_callback_info info)627 napi_value NapiAudioManager::SetRingerMode(napi_env env, napi_callback_info info)
628 {
629     auto context = std::make_shared<AudioManagerAsyncContext>();
630     if (context == nullptr) {
631         AUDIO_ERR_LOG("SetRingerMode failed : no memory");
632         NapiAudioError::ThrowError(env, "SetRingerMode failed : no memory", NAPI_ERR_NO_MEMORY);
633         return NapiParamUtils::GetUndefinedValue(env);
634     }
635 
636     auto inputParser = [env, context](size_t argc, napi_value *argv) {
637         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
638         context->status = NapiParamUtils::GetValueInt32(env, context->ringMode, argv[PARAM0]);
639         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get ringMode failed",
640             NAPI_ERR_INVALID_PARAM);
641         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentRingMode(context->ringMode),
642             "get ringMode unsupport", NAPI_ERR_UNSUPPORTED);
643     };
644     context->GetCbInfo(env, info, inputParser);
645 
646     auto executor = [context]() {
647         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
648         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
649         ObjectRefMap objectGuard(obj);
650         auto *napiAudioManager = objectGuard.GetPtr();
651         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
652             "audio manager state is error.");
653         napiAudioManager->audioMngr_->SetRingerMode(
654             NapiAudioEnum::GetNativeAudioRingerMode(context->ringMode));
655     };
656 
657     auto complete = [env](napi_value &output) {
658         output = NapiParamUtils::GetUndefinedValue(env);
659     };
660     return NapiAsyncWork::Enqueue(env, context, "SetRingerMode", executor, complete);
661 }
662 
GetRingerMode(napi_env env,napi_callback_info info)663 napi_value NapiAudioManager::GetRingerMode(napi_env env, napi_callback_info info)
664 {
665     auto context = std::make_shared<AudioManagerAsyncContext>();
666     if (context == nullptr) {
667         AUDIO_ERR_LOG("SetRingerMode failed : no memory");
668         NapiAudioError::ThrowError(env, "SetRingerMode failed : no memory", NAPI_ERR_NO_MEMORY);
669         return NapiParamUtils::GetUndefinedValue(env);
670     }
671 
672     context->GetCbInfo(env, info);
673 
674     auto executor = [context]() {
675         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
676         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
677         ObjectRefMap objectGuard(obj);
678         auto *napiAudioManager = objectGuard.GetPtr();
679         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
680             "audio manager state is error.");
681         context->ringMode = NapiAudioEnum::GetJsAudioRingMode(napiAudioManager->audioMngr_->GetRingerMode());
682     };
683 
684     auto complete = [env, context](napi_value &output) {
685         NapiParamUtils::SetValueInt32(env, context->ringMode, output);
686     };
687     return NapiAsyncWork::Enqueue(env, context, "GetRingerMode", executor, complete);
688 }
689 
SetAudioScene(napi_env env,napi_callback_info info)690 napi_value NapiAudioManager::SetAudioScene(napi_env env, napi_callback_info info)
691 {
692     auto context = std::make_shared<AudioManagerAsyncContext>();
693     if (context == nullptr) {
694         AUDIO_ERR_LOG("SetAudioScene failed : no memory");
695         NapiAudioError::ThrowError(env, "SetAudioScene failed : no memory", NAPI_ERR_NO_MEMORY);
696         return NapiParamUtils::GetUndefinedValue(env);
697     }
698 
699     auto inputParser = [env, context](size_t argc, napi_value *argv) {
700         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
701         context->status = NapiParamUtils::GetValueInt32(env, context->scene, argv[PARAM0]);
702         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get scene failed",
703             NAPI_ERR_INVALID_PARAM);
704     };
705     context->GetCbInfo(env, info, inputParser);
706 
707     auto executor = [context]() {
708         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
709         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
710         ObjectRefMap objectGuard(obj);
711         auto *napiAudioManager = objectGuard.GetPtr();
712         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
713             "audio manager state is error.");
714         context->intValue = napiAudioManager->audioMngr_->SetAudioScene(static_cast<AudioScene>(context->scene));
715         NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SetAudioScene failed", NAPI_ERR_SYSTEM);
716     };
717 
718     auto complete = [env](napi_value &output) {
719         output = NapiParamUtils::GetUndefinedValue(env);
720     };
721     return NapiAsyncWork::Enqueue(env, context, "SetAudioScene", executor, complete);
722 }
723 
GetAudioScene(napi_env env,napi_callback_info info)724 napi_value NapiAudioManager::GetAudioScene(napi_env env, napi_callback_info info)
725 {
726     auto context = std::make_shared<AudioManagerAsyncContext>();
727     if (context == nullptr) {
728         AUDIO_ERR_LOG("GetAudioScene failed : no memory");
729         NapiAudioError::ThrowError(env, "GetAudioScene failed : no memory", NAPI_ERR_NO_MEMORY);
730         return NapiParamUtils::GetUndefinedValue(env);
731     }
732 
733     context->GetCbInfo(env, info);
734 
735     auto executor = [context]() {
736         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
737         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
738         ObjectRefMap objectGuard(obj);
739         auto *napiAudioManager = objectGuard.GetPtr();
740         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
741             "audio manager state is error.");
742         AudioScene audioScene = napiAudioManager->audioMngr_->GetAudioScene();
743         if (audioScene == AUDIO_SCENE_VOICE_RINGING) {
744             audioScene = AUDIO_SCENE_RINGING;
745         }
746         context->intValue = audioScene;
747     };
748 
749     auto complete = [env, context](napi_value &output) {
750         NapiParamUtils::SetValueInt32(env, context->intValue, output);
751     };
752     return NapiAsyncWork::Enqueue(env, context, "GetAudioScene", executor, complete);
753 }
754 
GetAudioSceneSync(napi_env env,napi_callback_info info)755 napi_value NapiAudioManager::GetAudioSceneSync(napi_env env, napi_callback_info info)
756 {
757     AUDIO_INFO_LOG("GetRenderRateSync");
758     napi_value result = nullptr;
759     size_t argc = PARAM0;
760     auto *napiAudioManager = GetParamWithSync(env, info, argc, nullptr);
761     if (argc > PARAM0) {
762         NapiAudioError::ThrowError(env, NAPI_ERROR_INVALID_PARAM);
763         return result;
764     }
765     CHECK_AND_RETURN_RET_LOG(napiAudioManager != nullptr, result, "napiAudioManager is nullptr");
766     CHECK_AND_RETURN_RET_LOG(napiAudioManager->audioMngr_ != nullptr, result, "audioMngr_ is nullptr");
767     AudioScene audioScene = napiAudioManager->audioMngr_->GetAudioScene();
768     if (audioScene == AUDIO_SCENE_VOICE_RINGING) {
769         audioScene = AUDIO_SCENE_RINGING;
770     }
771     NapiParamUtils::SetValueInt32(env, audioScene, result);
772     return result;
773 }
774 
SetDeviceActive(napi_env env,napi_callback_info info)775 napi_value NapiAudioManager::SetDeviceActive(napi_env env, napi_callback_info info)
776 {
777     auto context = std::make_shared<AudioManagerAsyncContext>();
778     if (context == nullptr) {
779         AUDIO_ERR_LOG("SetDeviceActive failed : no memory");
780         NapiAudioError::ThrowError(env, "SetDeviceActive failed : no memory", NAPI_ERR_NO_MEMORY);
781         return NapiParamUtils::GetUndefinedValue(env);
782     }
783 
784     auto inputParser = [env, context](size_t argc, napi_value *argv) {
785         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_TWO, "invalid arguments", NAPI_ERR_INVALID_PARAM);
786         context->status = NapiParamUtils::GetValueInt32(env, context->deviceType, argv[PARAM0]);
787         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get deviceType failed",
788             NAPI_ERR_INVALID_PARAM);
789         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentActiveDeviceType(context->deviceType),
790             "invaild deviceType", NAPI_ERR_UNSUPPORTED);
791         context->status = NapiParamUtils::GetValueBoolean(env, context->isActive, argv[PARAM1]);
792         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get isActive failed",
793             NAPI_ERR_INVALID_PARAM);
794     };
795     context->GetCbInfo(env, info, inputParser);
796 
797     auto executor = [context]() {
798         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
799         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
800         ObjectRefMap objectGuard(obj);
801         auto *napiAudioManager = objectGuard.GetPtr();
802         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
803             "audio manager state is error.");
804         context->intValue = napiAudioManager->audioMngr_->SetDeviceActive(
805             static_cast<ActiveDeviceType>(context->deviceType), context->isActive);
806         NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SetDeviceActive failed",
807             NAPI_ERR_SYSTEM);
808     };
809 
810     auto complete = [env](napi_value &output) {
811         output = NapiParamUtils::GetUndefinedValue(env);
812     };
813     return NapiAsyncWork::Enqueue(env, context, "SetDeviceActive", executor, complete);
814 }
815 
IsDeviceActive(napi_env env,napi_callback_info info)816 napi_value NapiAudioManager::IsDeviceActive(napi_env env, napi_callback_info info)
817 {
818     auto context = std::make_shared<AudioManagerAsyncContext>();
819     if (context == nullptr) {
820         AUDIO_ERR_LOG("IsDeviceActive failed : no memory");
821         NapiAudioError::ThrowError(env, "IsDeviceActive failed : no memory", NAPI_ERR_NO_MEMORY);
822         return NapiParamUtils::GetUndefinedValue(env);
823     }
824 
825     auto inputParser = [env, context](size_t argc, napi_value *argv) {
826         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
827         context->status = NapiParamUtils::GetValueInt32(env, context->deviceType, argv[PARAM0]);
828         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get deviceType failed",
829             NAPI_ERR_INVALID_PARAM);
830         NAPI_CHECK_ARGS_RETURN_VOID(context, NapiAudioEnum::IsLegalInputArgumentActiveDeviceType(context->deviceType),
831             "invaild deviceType", NAPI_ERR_UNSUPPORTED);
832     };
833     context->GetCbInfo(env, info, inputParser);
834 
835     auto executor = [context]() {
836         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
837         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
838         ObjectRefMap objectGuard(obj);
839         auto *napiAudioManager = objectGuard.GetPtr();
840         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
841             "audio manager state is error.");
842         context->isActive = napiAudioManager->audioMngr_->IsDeviceActive(
843             static_cast<ActiveDeviceType>(context->deviceType));
844     };
845 
846     auto complete = [env, context](napi_value &output) {
847         NapiParamUtils::SetValueBoolean(env, context->isActive, output);
848     };
849     return NapiAsyncWork::Enqueue(env, context, "IsDeviceActive", executor, complete);
850 }
851 
SetAudioParameter(napi_env env,napi_callback_info info)852 napi_value NapiAudioManager::SetAudioParameter(napi_env env, napi_callback_info info)
853 {
854     auto context = std::make_shared<AudioManagerAsyncContext>();
855     if (context == nullptr) {
856         AUDIO_ERR_LOG("SetAudioParameter failed : no memory");
857         NapiAudioError::ThrowError(env, "SetAudioParameter failed : no memory", NAPI_ERR_NO_MEMORY);
858         return NapiParamUtils::GetUndefinedValue(env);
859     }
860 
861     auto inputParser = [env, context](size_t argc, napi_value *argv) {
862         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_TWO, "invalid arguments", NAPI_ERR_INVALID_PARAM);
863         context->key = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
864         NAPI_CHECK_ARGS_RETURN_VOID(context, !context->key.empty(), "get key failed",
865             NAPI_ERR_INVALID_PARAM);
866         context->valueStr = NapiParamUtils::GetStringArgument(env, argv[PARAM1]);
867         NAPI_CHECK_ARGS_RETURN_VOID(context, !context->valueStr.empty(), "get valueStr failed",
868             NAPI_ERR_INVALID_PARAM);
869     };
870     context->GetCbInfo(env, info, inputParser);
871 
872     auto executor = [context]() {
873         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
874         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
875         ObjectRefMap objectGuard(obj);
876         auto *napiAudioManager = objectGuard.GetPtr();
877         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
878             "audio manager state is error.");
879         napiAudioManager->audioMngr_->SetAudioParameter(context->key, context->valueStr);
880     };
881 
882     auto complete = [env](napi_value &output) {
883         output = NapiParamUtils::GetUndefinedValue(env);
884     };
885     return NapiAsyncWork::Enqueue(env, context, "SetAudioParameter", executor, complete);
886 }
887 
GetAudioParameter(napi_env env,napi_callback_info info)888 napi_value NapiAudioManager::GetAudioParameter(napi_env env, napi_callback_info info)
889 {
890     auto context = std::make_shared<AudioManagerAsyncContext>();
891     if (context == nullptr) {
892         AUDIO_ERR_LOG("GetAudioParameter failed : no memory");
893         NapiAudioError::ThrowError(env, "GetAudioParameter failed : no memory", NAPI_ERR_NO_MEMORY);
894         return NapiParamUtils::GetUndefinedValue(env);
895     }
896 
897     auto inputParser = [env, context](size_t argc, napi_value *argv) {
898         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
899         context->key = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
900         NAPI_CHECK_ARGS_RETURN_VOID(context, !context->key.empty(), "get key failed",
901             NAPI_ERR_INVALID_PARAM);
902     };
903     context->GetCbInfo(env, info, inputParser);
904 
905     auto executor = [context]() {
906         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
907         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
908         ObjectRefMap objectGuard(obj);
909         auto *napiAudioManager = objectGuard.GetPtr();
910         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
911             "audio manager state is error.");
912         context->valueStr = napiAudioManager->audioMngr_->GetAudioParameter(context->key);
913     };
914 
915     auto complete = [env, context](napi_value &output) {
916         NapiParamUtils::SetValueString(env, context->valueStr, output);
917     };
918     return NapiAsyncWork::Enqueue(env, context, "GetAudioParameter", executor, complete);
919 }
920 
SetExtraParameters(napi_env env,napi_callback_info info)921 napi_value NapiAudioManager::SetExtraParameters(napi_env env, napi_callback_info info)
922 {
923     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
924         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
925 
926     auto context = std::make_shared<AudioManagerAsyncContext>();
927     if (context == nullptr) {
928         AUDIO_ERR_LOG("set extra parameters failed : no memory");
929         NapiAudioError::ThrowError(env, "SetExtraParameters failed : no memory", NAPI_ERR_NO_MEMORY);
930         return NapiParamUtils::GetUndefinedValue(env);
931     }
932 
933     auto inputParser = [env, context](size_t argc, napi_value *argv) {
934         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_TWO, "mandatory parameters are left unspecified",
935             NAPI_ERR_INPUT_INVALID);
936 
937         napi_valuetype valueType = napi_undefined;
938         napi_typeof(env, argv[PARAM0], &valueType);
939         NAPI_CHECK_ARGS_RETURN_VOID(context, valueType == napi_string,
940             "incorrect parameter types: The type of mainKey must be string", NAPI_ERR_INPUT_INVALID);
941         context->key = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
942 
943         napi_typeof(env, argv[PARAM1], &valueType);
944         NAPI_CHECK_ARGS_RETURN_VOID(context, valueType == napi_object,
945             "incorrect parameter types: The type of kvpairs must be Record<string, string>", NAPI_ERR_INPUT_INVALID);
946         context->status = NapiParamUtils::GetExtraParametersSubKV(env, context->subKvpairs, argv[PARAM1]);
947         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get sub key and value failed",
948             NAPI_ERR_INPUT_INVALID);
949     };
950     context->GetCbInfo(env, info, inputParser);
951     if (context->status != napi_ok) {
952         NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
953         return NapiParamUtils::GetUndefinedValue(env);
954     }
955 
956     auto executor = [context]() {
957         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
958         auto obj = reinterpret_cast<NapiAudioManager *>(context->native);
959         ObjectRefMap objectGuard(obj);
960         auto *napiAudioManager = objectGuard.GetPtr();
961         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context), "audio manager state is error.");
962 
963         NAPI_CHECK_ARGS_RETURN_VOID(context, !context->key.empty(),
964             "parameter verification failed: get main key failed", NAPI_ERR_INVALID_PARAM);
965         NAPI_CHECK_ARGS_RETURN_VOID(context, !context->subKvpairs.empty(),
966             "parameter verification failed: sub key and value is empty", NAPI_ERR_INVALID_PARAM);
967         context->intValue = napiAudioManager->audioMngr_->SetExtraParameters(context->key, context->subKvpairs);
968         NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue != ERR_PERMISSION_DENIED, "permission denied",
969             NAPI_ERR_NO_PERMISSION);
970         NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SetExtraParameters failed",
971             NAPI_ERR_INVALID_PARAM);
972     };
973 
974     auto complete = [env](napi_value &output) {
975         output = NapiParamUtils::GetUndefinedValue(env);
976     };
977     return NapiAsyncWork::Enqueue(env, context, "SetExtraParameters", executor, complete);
978 }
979 
GetExtraParameters(napi_env env,napi_callback_info info)980 napi_value NapiAudioManager::GetExtraParameters(napi_env env, napi_callback_info info)
981 {
982     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
983         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
984 
985     auto context = std::make_shared<AudioManagerAsyncContext>();
986     if (context == nullptr) {
987         AUDIO_ERR_LOG("get extra parameters failed : no memory");
988         NapiAudioError::ThrowError(env, "GetExtraParameters failed : no memory", NAPI_ERR_NO_MEMORY);
989         return NapiParamUtils::GetUndefinedValue(env);
990     }
991 
992     auto inputParser = [env, context](size_t argc, napi_value *argv) {
993         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
994             NAPI_ERR_INPUT_INVALID);
995 
996         napi_valuetype valueType = napi_undefined;
997         napi_typeof(env, argv[PARAM0], &valueType);
998         NAPI_CHECK_ARGS_RETURN_VOID(context, valueType == napi_string,
999             "incorrect parameter types: The type of mainKey must be string", NAPI_ERR_INPUT_INVALID);
1000         context->key = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
1001 
1002         if (argc > ARGS_ONE) {
1003             napi_typeof(env, argv[PARAM1], &valueType);
1004             NAPI_CHECK_ARGS_RETURN_VOID(context, valueType == napi_object,
1005                 "incorrect parameter types: The type of kvpairs must be Record<string, string>",
1006                 NAPI_ERR_INPUT_INVALID);
1007             context->status = NapiParamUtils::GetExtraParametersVector(env, context->subKeys, argv[PARAM1]);
1008             NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
1009                 "parameter verification failed: get sub key and value failed", NAPI_ERR_INVALID_PARAM);
1010         }
1011     };
1012     context->GetCbInfo(env, info, inputParser);
1013     if (context->status != napi_ok) {
1014         NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
1015         return NapiParamUtils::GetUndefinedValue(env);
1016     }
1017 
1018     auto executor = [context]() {
1019         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1020         auto obj = reinterpret_cast<NapiAudioManager *>(context->native);
1021         ObjectRefMap objectGuard(obj);
1022         auto *napiAudioManager = objectGuard.GetPtr();
1023         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context), "audio manager state is error.");
1024 
1025         NAPI_CHECK_ARGS_RETURN_VOID(context, !context->key.empty(),
1026             "parameter verification failed: get main key failed", NAPI_ERR_INVALID_PARAM);
1027         context->intValue = napiAudioManager->audioMngr_->GetExtraParameters(
1028             context->key, context->subKeys, context->subKvpairs);
1029         NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "GetExtraParameters failed",
1030             NAPI_ERR_INVALID_PARAM);
1031     };
1032 
1033     auto complete = [env, context](napi_value &output) {
1034         NapiParamUtils::SetExtraAudioParametersInfo(env, context->subKvpairs, output);
1035     };
1036     return NapiAsyncWork::Enqueue(env, context, "GetExtraParameters", executor, complete);
1037 }
1038 
SetMicrophoneMute(napi_env env,napi_callback_info info)1039 napi_value NapiAudioManager::SetMicrophoneMute(napi_env env, napi_callback_info info)
1040 {
1041     auto context = std::make_shared<AudioManagerAsyncContext>();
1042     if (context == nullptr) {
1043         AUDIO_ERR_LOG("SetMicrophoneMute failed : no memory");
1044         NapiAudioError::ThrowError(env, "SetMicrophoneMute failed : no memory", NAPI_ERR_NO_MEMORY);
1045         return NapiParamUtils::GetUndefinedValue(env);
1046     }
1047 
1048     auto inputParser = [env, context](size_t argc, napi_value *argv) {
1049         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
1050         context->status = NapiParamUtils::GetValueBoolean(env, context->isMute, argv[PARAM0]);
1051         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get isMute failed",
1052             NAPI_ERR_INVALID_PARAM);
1053     };
1054     context->GetCbInfo(env, info, inputParser);
1055 
1056     auto executor = [context]() {
1057         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1058         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
1059         ObjectRefMap objectGuard(obj);
1060         auto *napiAudioManager = objectGuard.GetPtr();
1061         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
1062             "audio manager state is error.");
1063         context->intValue = napiAudioManager->audioMngr_->SetMicrophoneMute(context->isMute);
1064         NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SetMicrophoneMute failed",
1065             NAPI_ERR_SYSTEM);
1066     };
1067 
1068     auto complete = [env](napi_value &output) {
1069         output = NapiParamUtils::GetUndefinedValue(env);
1070     };
1071     return NapiAsyncWork::Enqueue(env, context, "SetMicrophoneMute", executor, complete);
1072 }
1073 
IsMicrophoneMute(napi_env env,napi_callback_info info)1074 napi_value NapiAudioManager::IsMicrophoneMute(napi_env env, napi_callback_info info)
1075 {
1076     auto context = std::make_shared<AudioManagerAsyncContext>();
1077     if (context == nullptr) {
1078         AUDIO_ERR_LOG("IsMicrophoneMute failed : no memory");
1079         NapiAudioError::ThrowError(env, "IsMicrophoneMute failed : no memory", NAPI_ERR_NO_MEMORY);
1080         return NapiParamUtils::GetUndefinedValue(env);
1081     }
1082 
1083     context->GetCbInfo(env, info);
1084 
1085     auto executor = [context]() {
1086         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1087         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
1088         ObjectRefMap objectGuard(obj);
1089         auto *napiAudioManager = objectGuard.GetPtr();
1090         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
1091             "audio manager state is error.");
1092         context->isMute = napiAudioManager->audioMngr_->IsMicrophoneMute();
1093     };
1094 
1095     auto complete = [env, context](napi_value &output) {
1096         NapiParamUtils::SetValueBoolean(env, context->isMute, output);
1097     };
1098     return NapiAsyncWork::Enqueue(env, context, "IsMicrophoneMute", executor, complete);
1099 }
1100 
RequestIndependentInterrupt(napi_env env,napi_callback_info info)1101 napi_value NapiAudioManager::RequestIndependentInterrupt(napi_env env, napi_callback_info info)
1102 {
1103     auto context = std::make_shared<AudioManagerAsyncContext>();
1104     if (context == nullptr) {
1105         AUDIO_ERR_LOG("RequestIndependentInterrupt failed : no memory");
1106         NapiAudioError::ThrowError(env, "RequestIndependentInterrupt failed : no memory", NAPI_ERR_NO_MEMORY);
1107         return NapiParamUtils::GetUndefinedValue(env);
1108     }
1109 
1110     auto inputParser = [env, context](size_t argc, napi_value *argv) {
1111         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
1112         context->status = NapiParamUtils::GetValueInt32(env, context->focusType, argv[PARAM0]);
1113         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get focusType failed",
1114             NAPI_ERR_INVALID_PARAM);
1115     };
1116     context->GetCbInfo(env, info, inputParser);
1117 
1118     auto executor = [context]() {
1119         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1120         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
1121         ObjectRefMap objectGuard(obj);
1122         auto *napiAudioManager = objectGuard.GetPtr();
1123         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
1124             "audio manager state is error.");
1125         context->isTrue = napiAudioManager->audioMngr_->RequestIndependentInterrupt(
1126             NapiAudioEnum::GetNativeFocusType(context->focusType));
1127     };
1128 
1129     auto complete = [env, context](napi_value &output) {
1130         NapiParamUtils::SetValueBoolean(env, context->isTrue, output);
1131     };
1132     return NapiAsyncWork::Enqueue(env, context, "RequestIndependentInterrupt", executor, complete);
1133 }
1134 
AbandonIndependentInterrupt(napi_env env,napi_callback_info info)1135 napi_value NapiAudioManager::AbandonIndependentInterrupt(napi_env env, napi_callback_info info)
1136 {
1137     auto context = std::make_shared<AudioManagerAsyncContext>();
1138     if (context == nullptr) {
1139         AUDIO_ERR_LOG("AbandonIndependentInterrupt failed : no memory");
1140         NapiAudioError::ThrowError(env, "AbandonIndependentInterrupt failed : no memory", NAPI_ERR_NO_MEMORY);
1141         return NapiParamUtils::GetUndefinedValue(env);
1142     }
1143 
1144     auto inputParser = [env, context](size_t argc, napi_value *argv) {
1145         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
1146         context->status = NapiParamUtils::GetValueInt32(env, context->focusType, argv[PARAM0]);
1147         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get focusType failed",
1148             NAPI_ERR_INVALID_PARAM);
1149     };
1150     context->GetCbInfo(env, info, inputParser);
1151 
1152     auto executor = [context]() {
1153         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1154         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
1155         ObjectRefMap objectGuard(obj);
1156         auto *napiAudioManager = objectGuard.GetPtr();
1157         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
1158             "audio manager state is error.");
1159         context->isTrue = napiAudioManager->audioMngr_->AbandonIndependentInterrupt(
1160             NapiAudioEnum::GetNativeFocusType(context->focusType));
1161     };
1162 
1163     auto complete = [env, context](napi_value &output) {
1164         NapiParamUtils::SetValueBoolean(env, context->isTrue, output);
1165     };
1166     return NapiAsyncWork::Enqueue(env, context, "AbandonIndependentInterrupt", executor, complete);
1167 }
1168 
DisableSafeMediaVolume(napi_env env,napi_callback_info info)1169 napi_value NapiAudioManager::DisableSafeMediaVolume(napi_env env, napi_callback_info info)
1170 {
1171     auto context = std::make_shared<AudioManagerAsyncContext>();
1172     if (context == nullptr) {
1173         AUDIO_ERR_LOG("failed : no memory");
1174         NapiAudioError::ThrowError(env, "DisableSafeMediaVolume failed : no memory", NAPI_ERR_NO_MEMORY);
1175         return NapiParamUtils::GetUndefinedValue(env);
1176     }
1177 
1178     context->GetCbInfo(env, info);
1179 
1180     auto executor = [context]() {
1181         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1182         auto obj = reinterpret_cast<NapiAudioManager*>(context->native);
1183         ObjectRefMap objectGuard(obj);
1184         auto *napiAudioManager = objectGuard.GetPtr();
1185         CHECK_AND_RETURN_LOG(CheckAudioManagerStatus(napiAudioManager, context),
1186             "audio manager state is error.");
1187         context->intValue = napiAudioManager->audioMngr_->DisableSafeMediaVolume();
1188         if (context->intValue == ERR_PERMISSION_DENIED) {
1189             context->SignError(NAPI_ERR_NO_PERMISSION);
1190         } else if (context->intValue == ERR_SYSTEM_PERMISSION_DENIED) {
1191             context->SignError(NAPI_ERR_PERMISSION_DENIED);
1192         }
1193     };
1194 
1195     auto complete = [env](napi_value &output) {
1196         output = NapiParamUtils::GetUndefinedValue(env);
1197     };
1198     return NapiAsyncWork::Enqueue(env, context, "DisableSafeMediaVolume", executor, complete);
1199 }
1200 
RegisterCallback(napi_env env,napi_value jsThis,napi_value * argv,const std::string & cbName)1201 napi_value NapiAudioManager::RegisterCallback(napi_env env, napi_value jsThis,
1202     napi_value *argv, const std::string &cbName)
1203 {
1204     napi_value undefinedResult = nullptr;
1205     NapiAudioManager *napiAudioManager = nullptr;
1206     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiAudioManager));
1207     CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM),
1208         "status error");
1209     CHECK_AND_RETURN_RET_LOG(napiAudioManager != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
1210         NAPI_ERR_NO_MEMORY), "napiAudioManager is nullptr");
1211     CHECK_AND_RETURN_RET_LOG(napiAudioManager->audioMngr_ != nullptr, NapiAudioError::ThrowErrorAndReturn(
1212         env, NAPI_ERR_NO_MEMORY), "audioMngr_ is nullptr");
1213 
1214     if (!cbName.compare(INTERRUPT_CALLBACK_NAME)) {
1215         RegisterInterruptCallback(env, argv, napiAudioManager);
1216     } else if (!cbName.compare(RINGERMODE_CALLBACK_NAME)) {
1217         RegisterRingerModeCallback(env, argv, napiAudioManager);
1218     } else if (!cbName.compare(VOLUME_CHANGE_CALLBACK_NAME)) {
1219         AUDIO_INFO_LOG("enter RegisterVolumeChangeCallback");
1220         RegisterVolumeChangeCallback(env, argv, napiAudioManager);
1221     } else if (!cbName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
1222         RegisterDeviceChangeCallback(env, argv, napiAudioManager);
1223     }
1224     return undefinedResult;
1225 }
1226 
RegisterInterruptCallback(napi_env env,const T & argv,NapiAudioManager * napiAudioManager)1227 template<typename T> void NapiAudioManager::RegisterInterruptCallback(napi_env env, const T &argv,
1228     NapiAudioManager *napiAudioManager)
1229 {
1230     napi_valuetype paramArg1 = napi_undefined;
1231     napi_typeof(env, argv[PARAM1], &paramArg1);
1232     napi_valuetype handler = napi_undefined;
1233     if (paramArg1 != napi_object) {
1234         AUDIO_ERR_LOG("NapiAudioManager::On Type mismatch for parameter 2");
1235         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
1236         return;
1237     }
1238     if (napi_typeof(env, argv[PARAM2], &handler) != napi_ok || handler != napi_function) {
1239         AUDIO_ERR_LOG("NapiAudioManager::On type mismatch for parameter 3");
1240         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
1241         return;
1242     }
1243     if (napiAudioManager->interruptCallbackNapi_ == nullptr) {
1244         napiAudioManager->interruptCallbackNapi_ = std::make_shared<NapiAudioManagerInterruptCallback>(env);
1245         int32_t ret = napiAudioManager->audioMngr_->
1246             SetAudioManagerInterruptCallback(napiAudioManager->interruptCallbackNapi_);
1247         CHECK_AND_RETURN_LOG(ret == SUCCESS, "SetAudioManagerInterruptCallback Failed");
1248     }
1249     std::lock_guard<std::mutex> lock(napiAudioManager->interruptCallbackNapi_->cbMutex_);
1250     std::shared_ptr<NapiAudioManagerInterruptCallback> cb =
1251         std::static_pointer_cast<NapiAudioManagerInterruptCallback>(napiAudioManager->interruptCallbackNapi_);
1252     cb->SaveCallbackReference(INTERRUPT_CALLBACK_NAME, argv[PARAM2]);
1253     AudioInterrupt audioInterrupt;
1254     NapiParamUtils::GetAudioInterrupt(env, audioInterrupt, argv[PARAM1]);
1255     int32_t ret = napiAudioManager->audioMngr_->RequestAudioFocus(audioInterrupt);
1256     CHECK_AND_RETURN_LOG(ret == SUCCESS, "RequestAudioFocus Failed");
1257     AUDIO_INFO_LOG("SetAudioManagerInterruptCallback and RequestAudioFocus is successful");
1258 }
1259 
RegisterRingerModeCallback(napi_env env,const T & argv,NapiAudioManager * napiAudioManager)1260 template<typename T> void NapiAudioManager::RegisterRingerModeCallback(napi_env env, const T &argv,
1261     NapiAudioManager *napiAudioManager)
1262 {
1263     if (napiAudioManager->ringerModecallbackNapi_ == nullptr) {
1264         napiAudioManager->ringerModecallbackNapi_ = std::make_shared<NapiAudioRingerModeCallback>(env);
1265         int32_t ret = napiAudioManager->audioMngr_->SetRingerModeCallback(
1266             napiAudioManager->cachedClientId_, napiAudioManager->ringerModecallbackNapi_);
1267         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1268             "SetRingerModeCallback Failed %{public}d", ret);
1269     }
1270 
1271     std::shared_ptr<NapiAudioRingerModeCallback> cb =
1272         std::static_pointer_cast<NapiAudioRingerModeCallback>(napiAudioManager->ringerModecallbackNapi_);
1273     cb->SaveCallbackReference(RINGERMODE_CALLBACK_NAME, argv[PARAM1]);
1274 }
1275 
RegisterVolumeChangeCallback(napi_env env,const T & argv,NapiAudioManager * napiAudioManager)1276 template<typename T> void NapiAudioManager::RegisterVolumeChangeCallback(napi_env env, const T &argv,
1277     NapiAudioManager *napiAudioManager)
1278 {
1279     if (napiAudioManager->volumeKeyEventCallbackNapi_ == nullptr) {
1280         napiAudioManager->volumeKeyEventCallbackNapi_ = std::make_shared<NapiAudioVolumeKeyEvent>(env);
1281         int32_t ret = napiAudioManager->audioMngr_->RegisterVolumeKeyEventCallback(napiAudioManager->cachedClientId_,
1282             napiAudioManager->volumeKeyEventCallbackNapi_, API_8);
1283         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1284             "RegisterVolumeKeyEventCallback Failed %{public}d", ret);
1285     }
1286     std::shared_ptr<NapiAudioVolumeKeyEvent> cb =
1287         std::static_pointer_cast<NapiAudioVolumeKeyEvent>(napiAudioManager->volumeKeyEventCallbackNapi_);
1288     cb->SaveCallbackReference(VOLUME_CHANGE_CALLBACK_NAME, argv[PARAM1]);
1289 }
1290 
RegisterDeviceChangeCallback(napi_env env,const T & argv,NapiAudioManager * napiAudioManager)1291 template<typename T> void NapiAudioManager::RegisterDeviceChangeCallback(napi_env env, const T &argv,
1292     NapiAudioManager *napiAudioManager)
1293 {
1294     if (napiAudioManager->deviceChangeCallbackNapi_ == nullptr) {
1295         napiAudioManager->deviceChangeCallbackNapi_ = std::make_shared<NapiAudioManagerCallback>(env);
1296     }
1297     int32_t ret = napiAudioManager->audioMngr_->SetDeviceChangeCallback(DeviceFlag::ALL_DEVICES_FLAG,
1298         napiAudioManager->deviceChangeCallbackNapi_);
1299     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1300         "NapiAudioManager: SetDeviceChangeCallback Failed %{public}d", ret);
1301     std::shared_ptr<NapiAudioManagerCallback> cb =
1302         std::static_pointer_cast<NapiAudioManagerCallback>(napiAudioManager->deviceChangeCallbackNapi_);
1303     cb->SaveAudioManagerDeviceChangeCbRef(DeviceFlag::ALL_DEVICES_FLAG, argv[PARAM1]);
1304 }
1305 
On(napi_env env,napi_callback_info info)1306 napi_value NapiAudioManager::On(napi_env env, napi_callback_info info)
1307 {
1308     napi_value undefinedResult = nullptr;
1309     NapiParamUtils::GetUndefinedValue(env);
1310 
1311     constexpr size_t minArgCount = ARGS_TWO;
1312     size_t argCount = ARGS_THREE;
1313     napi_value argv[minArgCount + PARAM1] = {nullptr, nullptr, nullptr};
1314     napi_value jsThis = nullptr;
1315     napi_status status = napi_get_cb_info(env, info, &argCount, argv, &jsThis, nullptr);
1316     if (status != napi_ok || argCount < minArgCount) {
1317         AUDIO_ERR_LOG("On fail to napi_get_cb_info/Requires min 2 parameters");
1318         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
1319         return undefinedResult;
1320     }
1321 
1322     napi_valuetype eventType = napi_undefined;
1323     if (napi_typeof(env, argv[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
1324         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
1325         return undefinedResult;
1326     }
1327     std::string callbackName = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
1328     AUDIO_INFO_LOG("On callbackName: %{public}s", callbackName.c_str());
1329 
1330     if (argCount == minArgCount) {
1331         napi_valuetype handler = napi_undefined;
1332         if (napi_typeof(env, argv[PARAM1], &handler) != napi_ok || handler != napi_function) {
1333             AUDIO_ERR_LOG("NapiAudioManager::On type mismatch for parameter 2");
1334             NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
1335             return undefinedResult;
1336         }
1337     }
1338 
1339     return RegisterCallback(env, jsThis, argv, callbackName);
1340 }
1341 
UnregisterInterruptCallback(napi_env env,const T & argv,const size_t argCount,NapiAudioManager * napiAudioManager)1342 template<typename T> void NapiAudioManager::UnregisterInterruptCallback(napi_env env, const T &argv,
1343     const size_t argCount, NapiAudioManager *napiAudioManager)
1344 {
1345     napi_valuetype paramArg1 = napi_undefined;
1346     napi_valuetype handler = napi_undefined;
1347     if (napi_typeof(env, argv[PARAM1], &paramArg1) != napi_ok || paramArg1 != napi_object) {
1348         AUDIO_ERR_LOG("Off type mismatch for parameter 2");
1349         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
1350         return;
1351     }
1352     if ((argCount == ARGS_THREE) &&
1353         (napi_typeof(env, argv[PARAM2], &handler) != napi_ok || handler != napi_function)) {
1354         AUDIO_ERR_LOG("Off type mismatch for parameter 3");
1355         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
1356         return;
1357     }
1358     int32_t callbackCount = PARAM0;
1359     if (napiAudioManager->interruptCallbackNapi_ != nullptr) {
1360         std::shared_ptr<NapiAudioManagerInterruptCallback> cb =
1361             std::static_pointer_cast<NapiAudioManagerInterruptCallback>(napiAudioManager->interruptCallbackNapi_);
1362         if (argCount == ARGS_TWO) {
1363             cb->RemoveAllCallbackReferences(INTERRUPT_CALLBACK_NAME);
1364         } else if (argCount == ARGS_THREE) {
1365             cb->RemoveCallbackReference(INTERRUPT_CALLBACK_NAME, argv[PARAM2]);
1366         }
1367         callbackCount = cb->GetInterruptCallbackListSize();
1368     }
1369     AUDIO_INFO_LOG("Remove Callback Reference success");
1370     if (callbackCount == PARAM0) {
1371         AudioInterrupt audioInterrupt;
1372         NapiParamUtils::GetAudioInterrupt(env, audioInterrupt, argv[PARAM1]);
1373         int32_t ret = napiAudioManager->audioMngr_->AbandonAudioFocus(audioInterrupt);
1374         if (ret) {
1375             AUDIO_ERR_LOG("Off AbandonAudioFocus Failed");
1376         }
1377         ret = napiAudioManager->audioMngr_->UnsetAudioManagerInterruptCallback();
1378         CHECK_AND_RETURN_LOG(ret == SUCCESS,
1379             "Off UnsetAudioManagerInterruptCallback Failed");
1380         if (napiAudioManager->interruptCallbackNapi_ != nullptr) {
1381             std::lock_guard<std::mutex> lock(napiAudioManager->interruptCallbackNapi_->cbMutex_);
1382             napiAudioManager->interruptCallbackNapi_.reset();
1383             napiAudioManager->interruptCallbackNapi_ = nullptr;
1384         }
1385         AUDIO_INFO_LOG("Off Abandon Focus and UnsetAudioInterruptCallback success");
1386     }
1387 }
1388 
UnregisterDeviceChangeCallback(napi_env env,napi_value callback,NapiAudioManager * audioMgrNapi)1389 void NapiAudioManager::UnregisterDeviceChangeCallback(napi_env env, napi_value callback,
1390     NapiAudioManager *audioMgrNapi)
1391 {
1392     if (audioMgrNapi == nullptr) {
1393         AUDIO_ERR_LOG("audioMgrNapi is nullptr");
1394         return;
1395     }
1396     CHECK_AND_RETURN_LOG(audioMgrNapi->deviceChangeCallbackNapi_ != nullptr,
1397         "UnregisterDeviceChangeCallback: audio manager deviceChangeCallbackNapi_ is null");
1398     std::shared_ptr<NapiAudioManagerCallback> cb =
1399         std::static_pointer_cast<NapiAudioManagerCallback>(audioMgrNapi->deviceChangeCallbackNapi_);
1400     if (callback != nullptr) {
1401         cb->RemoveAudioManagerDeviceChangeCbRef(env, callback);
1402     }
1403     if (callback == nullptr || cb->GetAudioManagerDeviceChangeCbListSize() == 0) {
1404         int32_t ret = audioMgrNapi->audioMngr_->UnsetDeviceChangeCallback(DeviceFlag::ALL_DEVICES_FLAG);
1405         CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetDeviceChangeCallback Failed");
1406         audioMgrNapi->deviceChangeCallbackNapi_.reset();
1407         audioMgrNapi->deviceChangeCallbackNapi_ = nullptr;
1408         cb->RemoveAllAudioManagerDeviceChangeCb();
1409     }
1410 }
1411 
Off(napi_env env,napi_callback_info info)1412 napi_value NapiAudioManager::Off(napi_env env, napi_callback_info info)
1413 {
1414     napi_value undefinedResult = nullptr;
1415     NapiParamUtils::GetUndefinedValue(env);
1416 
1417     constexpr size_t minArgCount = ARGS_ONE;
1418     size_t argCount = ARGS_THREE;
1419     napi_value argv[minArgCount + PARAM2] = {nullptr, nullptr, nullptr};
1420     napi_value jsThis = nullptr;
1421     napi_status status = napi_get_cb_info(env, info, &argCount, argv, &jsThis, nullptr);
1422     if (status != napi_ok || argCount < minArgCount) {
1423         AUDIO_ERR_LOG("Off fail to napi_get_cb_info/Requires min 1 parameters");
1424         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
1425         return undefinedResult;
1426     }
1427 
1428     napi_valuetype eventType = napi_undefined;
1429     if (napi_typeof(env, argv[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
1430         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
1431         return undefinedResult;
1432     }
1433     std::string callbackName = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
1434     AUDIO_INFO_LOG("Off callbackName: %{public}s", callbackName.c_str());
1435 
1436     NapiAudioManager *napiAudioManager = nullptr;
1437     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiAudioManager));
1438 
1439     if (!callbackName.compare(INTERRUPT_CALLBACK_NAME) && argCount > ARGS_ONE) {
1440         UnregisterInterruptCallback(env, argv, argCount, napiAudioManager);
1441     } else if (!callbackName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
1442         UnregisterDeviceChangeCallback(env, argv[PARAM1], napiAudioManager);
1443     } else {
1444         NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM);
1445     }
1446     return undefinedResult;
1447 }
1448 }  // namespace AudioStandard
1449 }  // namespace OHOS