• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "audio_manager_napi.h"
17 
18 #include "audio_capturer_napi.h"
19 #include "audio_common_napi.h"
20 #include "audio_errors.h"
21 #include "audio_parameters_napi.h"
22 #include "audio_renderer_info_napi.h"
23 #include "audio_renderer_napi.h"
24 #include "audio_ringermode_callback_napi.h"
25 #include "audio_manager_callback_napi.h"
26 #include "audio_manager_interrupt_callback_napi.h"
27 #include "audio_volume_key_event_napi.h"
28 #include "audio_common_napi.h"
29 #include "audio_volume_manager_napi.h"
30 #include "audio_volume_group_manager_napi.h"
31 #include "audio_interrupt_manager_napi.h"
32 #include "hilog/log.h"
33 #include "audio_log.h"
34 #include "toneplayer_napi.h"
35 
36 using namespace std;
37 using OHOS::HiviewDFX::HiLog;
38 using OHOS::HiviewDFX::HiLogLabel;
39 
40 namespace {
41     const std::string RINGERMODE_CALLBACK_NAME = "ringerModeChange";
42     const std::string VOLUME_CHANGE_CALLBACK_NAME = "volumeChange";
43     const std::string INTERRUPT_CALLBACK_NAME = "interrupt";
44 }
45 
46 namespace OHOS {
47 namespace AudioStandard {
48 static __thread napi_ref g_managerConstructor = nullptr;
49 napi_ref AudioManagerNapi::audioVolumeTypeRef_ = nullptr;
50 napi_ref AudioManagerNapi::deviceFlagRef_ = nullptr;
51 napi_ref AudioManagerNapi::deviceRoleRef_ = nullptr;
52 napi_ref AudioManagerNapi::deviceTypeRef_ = nullptr;
53 napi_ref AudioManagerNapi::activeDeviceTypeRef_ = nullptr;
54 napi_ref AudioManagerNapi::connectTypeRef_ = nullptr;
55 napi_ref AudioManagerNapi::audioRingModeRef_ = nullptr;
56 napi_ref AudioManagerNapi::deviceChangeType_ = nullptr;
57 napi_ref AudioManagerNapi::interruptActionType_ = nullptr;
58 napi_ref AudioManagerNapi::interruptHint_ = nullptr;
59 napi_ref AudioManagerNapi::interruptType_ = nullptr;
60 napi_ref AudioManagerNapi::audioScene_ = nullptr;
61 napi_ref AudioManagerNapi::interruptMode_ = nullptr;
62 napi_ref AudioManagerNapi::focusType_ = nullptr;
63 napi_ref AudioManagerNapi::audioErrors_ = nullptr;
64 napi_ref AudioManagerNapi::communicationDeviceType_ = nullptr;
65 napi_ref AudioManagerNapi::interruptRequestType_ = nullptr;
66 napi_ref AudioManagerNapi::interruptRequestResultType_ = nullptr;
67 
68 
69 #define GET_PARAMS(env, info, num) \
70     size_t argc = num;             \
71     napi_value argv[num] = {0};    \
72     napi_value thisVar = nullptr;  \
73     void *data;                    \
74     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)
75 
76 struct AudioManagerAsyncContext {
77     napi_env env;
78     napi_async_work work;
79     napi_deferred deferred;
80     napi_ref callbackRef = nullptr;
81     int32_t volType;
82     int32_t volLevel;
83     int32_t deviceType;
84     int32_t ringMode;
85     int32_t scene;
86     int32_t deviceFlag;
87     int32_t intValue;
88     int32_t status = 0;
89     int32_t focusType;
90     int32_t groupId;
91     bool isMute;
92     bool isActive;
93     bool isTrue;
94     string key;
95     string valueStr;
96     string networkId;
97     AudioManagerNapi *objectInfo;
98     vector<sptr<AudioDeviceDescriptor>> deviceDescriptors;
99     vector<sptr<VolumeGroupInfo>> volumeGroupInfos;
100 };
101 
102 namespace {
103     const int ARGS_ONE = 1;
104     const int ARGS_TWO = 2;
105     const int ARGS_THREE = 3;
106     const int PARAM0 = 0;
107     const int PARAM1 = 1;
108     const int PARAM2 = 2;
109     constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AudioManagerNapi"};
110 }
111 
AudioManagerNapi()112 AudioManagerNapi::AudioManagerNapi()
113     : audioMngr_(nullptr), env_(nullptr) {}
114 
~AudioManagerNapi()115 AudioManagerNapi::~AudioManagerNapi()
116 {
117     AUDIO_DEBUG_LOG("AudioManagerNapi::~AudioManagerNapi()");
118 }
119 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)120 void AudioManagerNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
121 {
122     if (nativeObject != nullptr) {
123         auto obj = static_cast<AudioManagerNapi*>(nativeObject);
124         delete obj;
125         obj = nullptr;
126         AUDIO_DEBUG_LOG("AudioManagerNapi::Destructor delete AudioManagerNapi obj done");
127     }
128 }
129 
GetNativeAudioVolumeType(int32_t volumeType)130 static AudioVolumeType GetNativeAudioVolumeType(int32_t volumeType)
131 {
132     AudioVolumeType result = STREAM_MUSIC;
133 
134     switch (volumeType) {
135         case AudioManagerNapi::RINGTONE:
136             result = STREAM_RING;
137             break;
138         case AudioManagerNapi::MEDIA:
139             result = STREAM_MUSIC;
140             break;
141         case AudioManagerNapi::VOICE_CALL:
142             result = STREAM_VOICE_CALL;
143             break;
144         case AudioManagerNapi::VOICE_ASSISTANT:
145             result = STREAM_VOICE_ASSISTANT;
146             break;
147         case AudioManagerNapi::ALL:
148             result = STREAM_ALL;
149             break;
150         default:
151             result = STREAM_MUSIC;
152             HiLog::Error(LABEL, "Unknown volume type, Set it to default MEDIA!");
153             break;
154     }
155 
156     return result;
157 }
158 
GetNativeFocusType(int32_t focusType)159 static AudioStandard::FocusType GetNativeFocusType(int32_t focusType)
160 {
161     AudioStandard::FocusType result = AudioStandard::FocusType::FOCUS_TYPE_RECORDING;
162     switch (focusType) {
163         case AudioManagerNapi::FocusType::FOCUS_TYPE_RECORDING:
164             result =  AudioStandard::FocusType::FOCUS_TYPE_RECORDING;
165             break;
166         default:
167             HiLog::Error(LABEL, "Unknown focusType type, Set it to default FOCUS_TYPE_RECORDING!");
168             break;
169     }
170 
171     return result;
172 }
173 
GetNativeAudioRingerMode(int32_t ringMode)174 static AudioRingerMode GetNativeAudioRingerMode(int32_t ringMode)
175 {
176     AudioRingerMode result = RINGER_MODE_NORMAL;
177 
178     switch (ringMode) {
179         case AudioManagerNapi::RINGER_MODE_SILENT:
180             result = RINGER_MODE_SILENT;
181             break;
182         case AudioManagerNapi::RINGER_MODE_VIBRATE:
183             result = RINGER_MODE_VIBRATE;
184             break;
185         case AudioManagerNapi::RINGER_MODE_NORMAL:
186             result = RINGER_MODE_NORMAL;
187             break;
188         default:
189             result = RINGER_MODE_NORMAL;
190             HiLog::Error(LABEL, "Unknown ringer mode requested by JS, Set it to default RINGER_MODE_NORMAL!");
191             break;
192     }
193 
194     return result;
195 }
196 
GetJsAudioRingMode(int32_t ringerMode)197 static AudioManagerNapi::AudioRingMode GetJsAudioRingMode(int32_t ringerMode)
198 {
199     AudioManagerNapi::AudioRingMode result = AudioManagerNapi::RINGER_MODE_NORMAL;
200 
201     switch (ringerMode) {
202         case RINGER_MODE_SILENT:
203             result = AudioManagerNapi::RINGER_MODE_SILENT;
204             break;
205         case RINGER_MODE_VIBRATE:
206             result = AudioManagerNapi::RINGER_MODE_VIBRATE;
207             break;
208         case RINGER_MODE_NORMAL:
209             result = AudioManagerNapi::RINGER_MODE_NORMAL;
210             break;
211         default:
212             result = AudioManagerNapi::RINGER_MODE_NORMAL;
213             HiLog::Error(LABEL, "Unknown ringer mode returned from native, Set it to default RINGER_MODE_NORMAL!");
214             break;
215     }
216 
217     return result;
218 }
219 
AddNamedProperty(napi_env env,napi_value object,const string name,int32_t enumValue)220 napi_status AudioManagerNapi::AddNamedProperty(napi_env env, napi_value object, const string name, int32_t enumValue)
221 {
222     napi_status status;
223     napi_value enumNapiValue;
224 
225     status = napi_create_int32(env, enumValue, &enumNapiValue);
226     if (status == napi_ok) {
227         status = napi_set_named_property(env, object, name.c_str(), enumNapiValue);
228     }
229 
230     return status;
231 }
232 
CreateDeviceChangeTypeObject(napi_env env)233 napi_value AudioManagerNapi::CreateDeviceChangeTypeObject(napi_env env)
234 {
235     napi_value result = nullptr;
236     napi_status status;
237     int32_t refCount = 1;
238 
239     status = napi_create_object(env, &result);
240     if (status == napi_ok) {
241         for (auto &iter: DEVICE_CHANGE_TYPE_MAP) {
242             status = AddNamedProperty(env, result, iter.first, iter.second);
243             if (status != napi_ok) {
244                 HiLog::Error(LABEL, "Failed to add named prop in CreateDeviceChangeTypeObject!");
245                 break;
246             }
247         }
248         if (status == napi_ok) {
249             status = napi_create_reference(env, result, refCount, &deviceChangeType_);
250             if (status == napi_ok) {
251                 return result;
252             }
253         }
254     }
255     HiLog::Error(LABEL, "CreateDeviceChangeTypeObject is Failed!");
256     napi_get_undefined(env, &result);
257 
258     return result;
259 }
260 
CreateInterruptActionTypeObject(napi_env env)261 napi_value AudioManagerNapi::CreateInterruptActionTypeObject(napi_env env)
262 {
263     napi_value result = nullptr;
264     napi_status status;
265     int32_t refCount = 1;
266 
267     status = napi_create_object(env, &result);
268     if (status == napi_ok) {
269         for (auto &iter: INTERRUPT_ACTION_TYPE_MAP) {
270             status = AddNamedProperty(env, result, iter.first, iter.second);
271             if (status != napi_ok) {
272                 HiLog::Error(LABEL, "Failed to add named prop in CreateInterruptActionTypeObject!");
273                 break;
274             }
275         }
276         if (status == napi_ok) {
277             status = napi_create_reference(env, result, refCount, &interruptActionType_);
278             if (status == napi_ok) {
279                 return result;
280             }
281         }
282     }
283     HiLog::Error(LABEL, "CreateInterruptActionTypeObject is Failed!");
284     napi_get_undefined(env, &result);
285 
286     return result;
287 }
288 
CreateAudioSceneObject(napi_env env)289 napi_value AudioManagerNapi::CreateAudioSceneObject(napi_env env)
290 {
291     napi_value result = nullptr;
292     napi_status status;
293     int32_t refCount = 1;
294 
295     status = napi_create_object(env, &result);
296     if (status == napi_ok) {
297         for (auto &iter: AUDIO_SCENE_MAP) {
298             status = AddNamedProperty(env, result, iter.first, iter.second);
299             if (status != napi_ok) {
300                 HiLog::Error(LABEL, "Failed to add named prop in CreateAudioSceneObject!");
301                 break;
302             }
303         }
304         if (status == napi_ok) {
305             status = napi_create_reference(env, result, refCount, &audioScene_);
306             if (status == napi_ok) {
307                 return result;
308             }
309         }
310     }
311     HiLog::Error(LABEL, "CreateAudioSceneObject is Failed!");
312     napi_get_undefined(env, &result);
313     return result;
314 }
315 
CreateAudioVolumeTypeObject(napi_env env)316 napi_value AudioManagerNapi::CreateAudioVolumeTypeObject(napi_env env)
317 {
318     napi_value result = nullptr;
319     napi_status status;
320     int32_t refCount = 1;
321 
322     status = napi_create_object(env, &result);
323     if (status == napi_ok) {
324         for (auto &iter: VOLUME_TYPE_MAP) {
325             status = AddNamedProperty(env, result, iter.first, iter.second);
326             if (status != napi_ok) {
327                 HiLog::Error(LABEL, "Failed to add named prop in CreateAudioVolumeTypeObject!");
328                 break;
329             }
330         }
331         status = AddNamedProperty(env, result, "ALL", AudioManagerNapi::ALL);
332         if (status == napi_ok) {
333             status = napi_create_reference(env, result, refCount, &audioVolumeTypeRef_);
334             if (status == napi_ok) {
335                 return result;
336             }
337         } else {
338             HiLog::Error(LABEL, "Failed to add named prop for AudioManagerNapi.ALL!");
339         }
340     }
341     HiLog::Error(LABEL, "CreateAudioVolumeTypeObject is Failed!");
342     napi_get_undefined(env, &result);
343 
344     return result;
345 }
346 
CreateDeviceFlagObject(napi_env env)347 napi_value AudioManagerNapi::CreateDeviceFlagObject(napi_env env)
348 {
349     napi_value result = nullptr;
350     napi_status status;
351     int32_t refCount = 1;
352     string propName;
353 
354     status = napi_create_object(env, &result);
355     if (status == napi_ok) {
356         AddPropName(propName, status, env, result);
357         if (status == napi_ok) {
358             status = napi_create_reference(env, result, refCount, &deviceFlagRef_);
359             if (status == napi_ok) {
360                 return result;
361             }
362         }
363     }
364     HiLog::Error(LABEL, "CreateDeviceFlagObject is Failed!");
365     napi_get_undefined(env, &result);
366 
367     return result;
368 }
369 
CreateActiveDeviceTypeObject(napi_env env)370 napi_value AudioManagerNapi::CreateActiveDeviceTypeObject(napi_env env)
371 {
372     napi_value result = nullptr;
373     napi_status status;
374     int32_t refCount = 1;
375 
376     status = napi_create_object(env, &result);
377     if (status == napi_ok) {
378         for (auto &iter: ACTIVE_DEVICE_TYPE) {
379             status = AddNamedProperty(env, result, iter.first, iter.second);
380             if (status != napi_ok) {
381                 HiLog::Error(LABEL, "Failed to add named prop in CreateActiveDeviceTypeObject!");
382                 break;
383             }
384         }
385         if (status == napi_ok) {
386             status = napi_create_reference(env, result, refCount, &activeDeviceTypeRef_);
387             if (status == napi_ok) {
388                 return result;
389             }
390         }
391     }
392     HiLog::Error(LABEL, "CreateActiveDeviceTypeObject is Failed!");
393     napi_get_undefined(env, &result);
394 
395     return result;
396 }
397 
CreateConnectTypeObject(napi_env env)398 napi_value AudioManagerNapi::CreateConnectTypeObject(napi_env env)
399 {
400     napi_value result = nullptr;
401     napi_status status;
402     int32_t refCount = 1;
403     string propName;
404     status = napi_create_object(env, &result);
405     if (status == napi_ok) {
406         for (int i = CONNECT_TYPE_LOCAL ; i < CONNECT_TYPE_DISTRIBUTED + 1; i++) {
407             switch (i) {
408                 case CONNECT_TYPE_LOCAL:
409                     propName = "CONNECT_TYPE_LOCAL";
410                     break;
411                 case CONNECT_TYPE_DISTRIBUTED:
412                     propName = "CONNECT_TYPE_DISTRIBUTED";
413                     break;
414                 default:
415                     continue;
416             }
417             status = AddNamedProperty(env, result, propName, i);
418             if (status != napi_ok) {
419                 HiLog::Error(LABEL, "Failed to add named prop!");
420                 break;
421             }
422             propName.clear();
423         }
424         if (status == napi_ok) {
425             status = napi_create_reference(env, result, refCount, &connectTypeRef_);
426             if (status == napi_ok) {
427                 return result;
428             }
429         }
430     }
431     HiLog::Error(LABEL, "CreateConnectTypeObject is Failed!");
432     napi_get_undefined(env, &result);
433 
434     return result;
435 }
436 
CreateAudioRingModeObject(napi_env env)437 napi_value AudioManagerNapi::CreateAudioRingModeObject(napi_env env)
438 {
439     napi_value result = nullptr;
440     napi_status status;
441     int32_t refCount = 1;
442     string propName;
443 
444     status = napi_create_object(env, &result);
445     if (status == napi_ok) {
446         for (int i = AudioManagerNapi::RINGER_MODE_SILENT; i <= AudioManagerNapi::RINGER_MODE_NORMAL; i++) {
447             switch (i) {
448                 case AudioManagerNapi::RINGER_MODE_SILENT:
449                     propName = "RINGER_MODE_SILENT";
450                     break;
451                 case AudioManagerNapi::RINGER_MODE_VIBRATE:
452                     propName = "RINGER_MODE_VIBRATE";
453                     break;
454                 case AudioManagerNapi::RINGER_MODE_NORMAL:
455                     propName = "RINGER_MODE_NORMAL";
456                     break;
457                 default:
458                     continue;
459             }
460             status = AddNamedProperty(env, result, propName, i);
461             if (status != napi_ok) {
462                 HiLog::Error(LABEL, "Failed to add named prop!");
463                 break;
464             }
465             propName.clear();
466         }
467         if (status == napi_ok) {
468             status = napi_create_reference(env, result, refCount, &audioRingModeRef_);
469             if (status == napi_ok) {
470                 return result;
471             }
472         }
473     }
474     HiLog::Error(LABEL, "CreateAudioRingModeObject is Failed!");
475     napi_get_undefined(env, &result);
476 
477     return result;
478 }
479 
CreatePropertyBase(napi_env env,T & t_map,napi_ref ref)480 template<typename T> napi_value AudioManagerNapi::CreatePropertyBase(napi_env env, T& t_map, napi_ref ref)
481 {
482     napi_value result = nullptr;
483     napi_status status;
484     std::string propName;
485     int32_t refCount = 1;
486 
487     status = napi_create_object(env, &result);
488     if (status == napi_ok) {
489         for (auto &iter: t_map) {
490             propName = iter.first;
491             status = AddNamedProperty(env, result, propName, iter.second);
492             if (status != napi_ok) {
493                 HiLog::Error(LABEL, "Failed to add named prop in CreatePropertyBase!");
494                 break;
495             }
496             propName.clear();
497         }
498         if (status == napi_ok) {
499             status = napi_create_reference(env, result, refCount, &ref);
500             if (status == napi_ok) {
501                 return result;
502             }
503         }
504     }
505     HiLog::Error(LABEL, "CreatePropertyBase is Failed!");
506     napi_get_undefined(env, &result);
507 
508     return result;
509 }
510 
Init(napi_env env,napi_value exports)511 napi_value AudioManagerNapi::Init(napi_env env, napi_value exports)
512 {
513     AUDIO_INFO_LOG("AudioManagerNapi::Init");
514     napi_status status;
515     napi_value constructor;
516     napi_value result = nullptr;
517     const int32_t refCount = 1;
518     napi_value localNetworkId;
519     napi_create_string_utf8(env, LOCAL_NETWORK_ID.c_str(), NAPI_AUTO_LENGTH, &localNetworkId);
520     napi_value defaultVolumeGroupId;
521     napi_create_int32(env, DEFAULT_VOLUME_GROUP_ID, &defaultVolumeGroupId);
522     napi_value defaultInterruptId;
523     napi_create_int32(env, DEFAULT_VOLUME_INTERRUPT_ID, &defaultInterruptId);
524 
525     napi_property_descriptor audio_svc_mngr_properties[] = {
526         DECLARE_NAPI_FUNCTION("setVolume", SetVolume),
527         DECLARE_NAPI_FUNCTION("getVolume", GetVolume),
528         DECLARE_NAPI_FUNCTION("getMaxVolume", GetMaxVolume),
529         DECLARE_NAPI_FUNCTION("getMinVolume", GetMinVolume),
530         DECLARE_NAPI_FUNCTION("getDevices", GetDevices),
531         DECLARE_NAPI_FUNCTION("mute", SetStreamMute),
532         DECLARE_NAPI_FUNCTION("isMute", IsStreamMute),
533         DECLARE_NAPI_FUNCTION("isActive", IsStreamActive),
534         DECLARE_NAPI_FUNCTION("setRingerMode", SetRingerMode),
535         DECLARE_NAPI_FUNCTION("getRingerMode", GetRingerMode),
536         DECLARE_NAPI_FUNCTION("setDeviceActive", SetDeviceActive),
537         DECLARE_NAPI_FUNCTION("isDeviceActive", IsDeviceActive),
538         DECLARE_NAPI_FUNCTION("setAudioParameter", SetAudioParameter),
539         DECLARE_NAPI_FUNCTION("getAudioParameter", GetAudioParameter),
540         DECLARE_NAPI_FUNCTION("setMicrophoneMute", SetMicrophoneMute),
541         DECLARE_NAPI_FUNCTION("isMicrophoneMute", IsMicrophoneMute),
542         DECLARE_NAPI_FUNCTION("setAudioScene", SetAudioScene),
543         DECLARE_NAPI_FUNCTION("getAudioScene", GetAudioScene),
544         DECLARE_NAPI_FUNCTION("on", On),
545         DECLARE_NAPI_FUNCTION("off", Off),
546         DECLARE_NAPI_FUNCTION("requestIndependentInterrupt", RequestIndependentInterrupt),
547         DECLARE_NAPI_FUNCTION("abandonIndependentInterrupt", AbandonIndependentInterrupt),
548         DECLARE_NAPI_FUNCTION("getStreamManager", GetStreamManager),
549         DECLARE_NAPI_FUNCTION("getRoutingManager", GetRoutingManager),
550         DECLARE_NAPI_FUNCTION("getVolumeManager", GetVolumeManager),
551         DECLARE_NAPI_FUNCTION("getInterruptManager", GetInterruptManager),
552     };
553 
554     napi_property_descriptor static_prop[] = {
555         DECLARE_NAPI_STATIC_FUNCTION("getAudioManager", GetAudioManager),
556         DECLARE_NAPI_PROPERTY("AudioVolumeType", CreateAudioVolumeTypeObject(env)),
557         DECLARE_NAPI_PROPERTY("DeviceFlag", CreateDeviceFlagObject(env)),
558         DECLARE_NAPI_PROPERTY("ActiveDeviceType", CreateActiveDeviceTypeObject(env)),
559         DECLARE_NAPI_PROPERTY("ConnectType", CreateConnectTypeObject(env)),
560         DECLARE_NAPI_PROPERTY("AudioRingMode", CreateAudioRingModeObject(env)),
561         DECLARE_NAPI_PROPERTY("AudioScene", CreateAudioSceneObject(env)),
562         DECLARE_NAPI_PROPERTY("DeviceChangeType", CreateDeviceChangeTypeObject(env)),
563         DECLARE_NAPI_PROPERTY("InterruptActionType", CreateInterruptActionTypeObject(env)),
564         DECLARE_NAPI_PROPERTY("InterruptMode", CreatePropertyBase(env, INTERRUPT_MODE_MAP, interruptMode_)),
565         DECLARE_NAPI_PROPERTY("FocusType", CreatePropertyBase(env, FOCUS_TYPE_MAP, focusType_)),
566         DECLARE_NAPI_PROPERTY("LOCAL_NETWORK_ID", localNetworkId),
567         DECLARE_NAPI_PROPERTY("DEFAULT_VOLUME_GROUP_ID", defaultVolumeGroupId),
568         DECLARE_NAPI_PROPERTY("DEFAULT_INTERRUPT_GROUP_ID", defaultInterruptId),
569         DECLARE_NAPI_PROPERTY("AudioErrors", CreatePropertyBase(env, AUDIO_ERRORS_MAP, audioErrors_)),
570         DECLARE_NAPI_PROPERTY("CommunicationDeviceType",
571             CreatePropertyBase(env, COMMUNICATION_DEVICE_TYPE_MAP, communicationDeviceType_)),
572         DECLARE_NAPI_PROPERTY("InterruptRequestType",
573             CreatePropertyBase(env, INTERRUPT_REQUEST_TYPE_MAP, interruptRequestType_)),
574         DECLARE_NAPI_PROPERTY("InterruptRequestResultType",
575             CreatePropertyBase(env, INTERRUPT_REQUEST_RESULT_TYPE_MAP, interruptRequestResultType_)),
576     };
577 
578     status = napi_define_class(env, AUDIO_MNGR_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct, nullptr,
579         sizeof(audio_svc_mngr_properties) / sizeof(audio_svc_mngr_properties[PARAM0]),
580         audio_svc_mngr_properties, &constructor);
581     if (status == napi_ok) {
582         status = napi_create_reference(env, constructor, refCount, &g_managerConstructor);
583         if (status == napi_ok) {
584             status = napi_set_named_property(env, exports, AUDIO_MNGR_NAPI_CLASS_NAME.c_str(), constructor);
585             if (status == napi_ok) {
586                 status = napi_define_properties(env, exports,
587                                                 sizeof(static_prop) / sizeof(static_prop[PARAM0]), static_prop);
588                 if (status == napi_ok) {
589                     return exports;
590                 }
591             }
592         }
593     }
594     HiLog::Error(LABEL, "Failure in AudioManagerNapi::Init()");
595     napi_get_undefined(env, &result);
596 
597     return result;
598 }
599 
600 // Constructor callback
Construct(napi_env env,napi_callback_info info)601 napi_value AudioManagerNapi::Construct(napi_env env, napi_callback_info info)
602 {
603     napi_status status;
604     napi_value jsThis;
605     napi_value undefinedResult = nullptr;
606     napi_get_undefined(env, &undefinedResult);
607     size_t argCount = 0;
608     int32_t ret = 0;
609 
610     status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
611     if (status == napi_ok) {
612         unique_ptr<AudioManagerNapi> managerNapi = make_unique<AudioManagerNapi>();
613         if (managerNapi != nullptr) {
614             managerNapi->env_ = env;
615             managerNapi->audioMngr_ = AudioSystemManager::GetInstance();
616             managerNapi->cachedClientId_ = getpid();
617 
618             managerNapi->volumeKeyEventCallbackNapi_ = std::make_shared<AudioVolumeKeyEventNapi>(env);
619             ret = managerNapi->audioMngr_->RegisterVolumeKeyEventCallback(managerNapi->cachedClientId_,
620                                                                           managerNapi->volumeKeyEventCallbackNapi_);
621             if (ret) {
622                 AUDIO_ERR_LOG("AudioManagerNapi: RegisterVolumeKeyEventCallback Failed");
623             } else {
624                 AUDIO_DEBUG_LOG("AudioManagerNapi: RegisterVolumeKeyEventCallback Success");
625             }
626 
627             status = napi_wrap(env, jsThis, static_cast<void*>(managerNapi.get()),
628                                AudioManagerNapi::Destructor, nullptr, nullptr);
629             if (status == napi_ok) {
630                 managerNapi.release();
631                 return jsThis;
632             }
633         }
634     }
635     HiLog::Error(LABEL, "Failed in AudioManagerNapi::Construct()!");
636 
637     return undefinedResult;
638 }
639 
CreateAudioManagerWrapper(napi_env env)640 napi_value AudioManagerNapi::CreateAudioManagerWrapper(napi_env env)
641 {
642     napi_status status;
643     napi_value result = nullptr;
644     napi_value constructor;
645 
646     status = napi_get_reference_value(env, g_managerConstructor, &constructor);
647     if (status == napi_ok) {
648         status = napi_new_instance(env, constructor, 0, nullptr, &result);
649         if (status == napi_ok) {
650             return result;
651         }
652     }
653     HiLog::Error(LABEL, "Failed in AudioManagerNapi::CreateaudioMngrWrapper!");
654     napi_get_undefined(env, &result);
655 
656     return result;
657 }
658 
GetAudioManager(napi_env env,napi_callback_info info)659 napi_value AudioManagerNapi::GetAudioManager(napi_env env, napi_callback_info info)
660 {
661     napi_status status;
662     size_t argCount = 0;
663 
664     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
665     if (status != napi_ok || argCount != 0) {
666         HiLog::Error(LABEL, "Invalid arguments!");
667         return nullptr;
668     }
669 
670     return AudioManagerNapi::CreateAudioManagerWrapper(env);
671 }
672 
CommonCallbackRoutine(napi_env env,AudioManagerAsyncContext * & asyncContext,const napi_value & valueParam)673 static void CommonCallbackRoutine(napi_env env, AudioManagerAsyncContext* &asyncContext, const napi_value &valueParam)
674 {
675     napi_value result[ARGS_TWO] = {0};
676     napi_value retVal;
677 
678     if (!asyncContext->status) {
679         napi_get_undefined(env, &result[PARAM0]);
680         result[PARAM1] = valueParam;
681     } else {
682         napi_value message = nullptr;
683         std::string messageValue = AudioCommonNapi::getMessageByCode(asyncContext->status);
684         napi_create_string_utf8(env, messageValue.c_str(), NAPI_AUTO_LENGTH, &message);
685 
686         napi_value code = nullptr;
687         napi_create_string_utf8(env, (std::to_string(asyncContext->status)).c_str(), NAPI_AUTO_LENGTH, &code);
688 
689         napi_create_error(env, code, message, &result[PARAM0]);
690         napi_get_undefined(env, &result[PARAM1]);
691     }
692 
693     if (asyncContext->deferred) {
694         if (!asyncContext->status) {
695             napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]);
696         } else {
697             napi_reject_deferred(env, asyncContext->deferred, result[PARAM0]);
698         }
699     } else {
700         napi_value callback = nullptr;
701         napi_get_reference_value(env, asyncContext->callbackRef, &callback);
702         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
703         napi_delete_reference(env, asyncContext->callbackRef);
704     }
705     napi_delete_async_work(env, asyncContext->work);
706 
707     delete asyncContext;
708     asyncContext = nullptr;
709 }
710 
SetFunctionAsyncCallbackComplete(napi_env env,napi_status status,void * data)711 static void SetFunctionAsyncCallbackComplete(napi_env env, napi_status status, void *data)
712 {
713     auto asyncContext = static_cast<AudioManagerAsyncContext*>(data);
714     napi_value valueParam = nullptr;
715 
716     if (asyncContext != nullptr) {
717         if (!asyncContext->status) {
718             napi_get_undefined(env, &valueParam);
719         }
720         CommonCallbackRoutine(env, asyncContext, valueParam);
721     } else {
722         HiLog::Error(LABEL, "ERROR: AudioManagerAsyncContext* is Null!");
723     }
724 }
725 
IsTrueAsyncCallbackComplete(napi_env env,napi_status status,void * data)726 static void IsTrueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
727 {
728     auto asyncContext = static_cast<AudioManagerAsyncContext*>(data);
729     napi_value valueParam = nullptr;
730 
731     if (asyncContext != nullptr) {
732         if (!asyncContext->status) {
733             napi_get_boolean(env, asyncContext->isTrue, &valueParam);
734         }
735         CommonCallbackRoutine(env, asyncContext, valueParam);
736     } else {
737         HiLog::Error(LABEL, "ERROR: AudioManagerAsyncContext* is Null!");
738     }
739 }
740 
GetStringValueAsyncCallbackComplete(napi_env env,napi_status status,void * data)741 static void GetStringValueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
742 {
743     auto asyncContext = static_cast<AudioManagerAsyncContext*>(data);
744     napi_value valueParam = nullptr;
745 
746     if (asyncContext != nullptr) {
747         if (!asyncContext->status) {
748             napi_create_string_utf8(env, asyncContext->valueStr.c_str(), NAPI_AUTO_LENGTH, &valueParam);
749         }
750         CommonCallbackRoutine(env, asyncContext, valueParam);
751     } else {
752         HiLog::Error(LABEL, "ERROR: AudioManagerAsyncContext* is Null!");
753     }
754 }
755 
GetIntValueAsyncCallbackComplete(napi_env env,napi_status status,void * data)756 static void GetIntValueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
757 {
758     auto asyncContext = static_cast<AudioManagerAsyncContext*>(data);
759     napi_value valueParam = nullptr;
760 
761     if (asyncContext != nullptr) {
762         if (!asyncContext->status) {
763             napi_create_int32(env, asyncContext->intValue, &valueParam);
764         }
765         CommonCallbackRoutine(env, asyncContext, valueParam);
766     } else {
767         HiLog::Error(LABEL, "ERROR: AudioManagerAsyncContext* is Null!");
768     }
769 }
770 
RequestIndependentInterrupt(napi_env env,napi_callback_info info)771 napi_value AudioManagerNapi::RequestIndependentInterrupt(napi_env env, napi_callback_info info)
772 {
773     AUDIO_INFO_LOG("AudioManagerNapi: RequestIndependentInterrupt");
774     napi_status status;
775     const int32_t refCount = 1;
776     napi_value result = nullptr;
777 
778     GET_PARAMS(env, info, ARGS_TWO);
779 
780     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
781     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
782     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
783         if (argc < ARGS_ONE) {
784             asyncContext->status = NAPI_ERR_INVALID_PARAM;
785         }
786         for (size_t i = PARAM0; i < argc; i++) {
787             napi_valuetype valueType = napi_undefined;
788             napi_typeof(env, argv[i], &valueType);
789 
790             if (i == PARAM0 && valueType == napi_number) {
791                 napi_get_value_int32(env, argv[i], &asyncContext->focusType);
792             } else if (i == PARAM1) {
793                 if (valueType == napi_function) {
794                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
795                 }
796                 break;
797             } else {
798                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
799             }
800         }
801 
802         if (asyncContext->callbackRef == nullptr) {
803             napi_create_promise(env, &asyncContext->deferred, &result);
804         } else {
805             napi_get_undefined(env, &result);
806         }
807 
808         napi_value resource = nullptr;
809         napi_create_string_utf8(env, "RequestIndependentInterrupt", NAPI_AUTO_LENGTH, &resource);
810 
811         status = napi_create_async_work(
812             env, nullptr, resource,
813             [](napi_env env, void *data) {
814                 auto context = static_cast<AudioManagerAsyncContext*>(data);
815                 AudioStandard::FocusType focusType_ = GetNativeFocusType(context->focusType);
816                 context->isTrue =
817                     context->objectInfo->audioMngr_->RequestIndependentInterrupt(focusType_);
818                 context->status = SUCCESS;
819             },
820             IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
821         if (status != napi_ok) {
822             result = nullptr;
823         } else {
824             status = napi_queue_async_work(env, asyncContext->work);
825             if (status == napi_ok) {
826                 asyncContext.release();
827             } else {
828                 result = nullptr;
829             }
830         }
831     }
832     return result;
833 }
834 
AbandonIndependentInterrupt(napi_env env,napi_callback_info info)835 napi_value AudioManagerNapi::AbandonIndependentInterrupt(napi_env env, napi_callback_info info)
836 {
837     AUDIO_INFO_LOG("AudioManagerNapi: AbandonIndependentInterrupt");
838     napi_status status;
839     const int32_t refCount = 1;
840     napi_value result = nullptr;
841 
842     GET_PARAMS(env, info, ARGS_TWO);
843 
844     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
845     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
846     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
847         if (argc < ARGS_ONE) {
848             asyncContext->status = NAPI_ERR_INVALID_PARAM;
849         }
850         for (size_t i = PARAM0; i < argc; i++) {
851             napi_valuetype valueType = napi_undefined;
852             napi_typeof(env, argv[i], &valueType);
853             if (i == PARAM0 && valueType == napi_number) {
854                 napi_get_value_int32(env, argv[i], &asyncContext->focusType);
855             } else if (i == PARAM1) {
856                 if (valueType == napi_function) {
857                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
858                 }
859                 break;
860             } else {
861                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
862             }
863         }
864 
865         if (asyncContext->callbackRef == nullptr) {
866             napi_create_promise(env, &asyncContext->deferred, &result);
867         } else {
868             napi_get_undefined(env, &result);
869         }
870 
871         napi_value resource = nullptr;
872         napi_create_string_utf8(env, "AbandonIndependentInterrupt", NAPI_AUTO_LENGTH, &resource);
873 
874         status = napi_create_async_work(
875             env, nullptr, resource,
876             [](napi_env env, void *data) {
877                 auto context = static_cast<AudioManagerAsyncContext*>(data);
878                 AudioStandard::FocusType focusType_ = GetNativeFocusType(context->focusType);
879                 context->isTrue =
880                     context->objectInfo->audioMngr_->AbandonIndependentInterrupt(focusType_);
881                 context->status = SUCCESS;
882             },
883             IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
884         if (status != napi_ok) {
885             result = nullptr;
886         } else {
887             status = napi_queue_async_work(env, asyncContext->work);
888             if (status == napi_ok) {
889                 asyncContext.release();
890             } else {
891                 result = nullptr;
892             }
893         }
894     }
895 
896     return result;
897 }
898 
SetMicrophoneMute(napi_env env,napi_callback_info info)899 napi_value AudioManagerNapi::SetMicrophoneMute(napi_env env, napi_callback_info info)
900 {
901     napi_status status;
902     const int32_t refCount = 1;
903     napi_value result = nullptr;
904 
905     GET_PARAMS(env, info, ARGS_TWO);
906 
907     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
908 
909     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
910     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
911         if (argc < ARGS_ONE) {
912             asyncContext->status = NAPI_ERR_INVALID_PARAM;
913         }
914         for (size_t i = PARAM0; i < argc; i++) {
915             napi_valuetype valueType = napi_undefined;
916             napi_typeof(env, argv[i], &valueType);
917 
918             if (i == PARAM0 && valueType == napi_boolean) {
919                 napi_get_value_bool(env, argv[i], &asyncContext->isMute);
920             } else if (i == PARAM1) {
921                 if (valueType == napi_function) {
922                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
923                 }
924                 break;
925             } else {
926                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
927             }
928         }
929 
930         if (asyncContext->callbackRef == nullptr) {
931             napi_create_promise(env, &asyncContext->deferred, &result);
932         } else {
933             napi_get_undefined(env, &result);
934         }
935 
936         napi_value resource = nullptr;
937         napi_create_string_utf8(env, "SetMicrophoneMute", NAPI_AUTO_LENGTH, &resource);
938 
939         status = napi_create_async_work(
940             env, nullptr, resource,
941             [](napi_env env, void *data) {
942                 auto context = static_cast<AudioManagerAsyncContext*>(data);
943                 if (context->status == SUCCESS) {
944                     context->status = context->objectInfo->audioMngr_->SetMicrophoneMute(context->isMute);
945                 }
946             },
947             SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
948         if (status != napi_ok) {
949             result = nullptr;
950         } else {
951             status = napi_queue_async_work(env, asyncContext->work);
952             if (status == napi_ok) {
953                 asyncContext.release();
954             } else {
955                 result = nullptr;
956             }
957         }
958     }
959 
960     return result;
961 }
962 
IsMicrophoneMute(napi_env env,napi_callback_info info)963 napi_value AudioManagerNapi::IsMicrophoneMute(napi_env env, napi_callback_info info)
964 {
965     napi_status status;
966     const int32_t refCount = 1;
967     napi_value result = nullptr;
968 
969     GET_PARAMS(env, info, ARGS_ONE);
970 
971     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
972 
973     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
974     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
975         if (argc > PARAM0) {
976             napi_valuetype valueType = napi_undefined;
977             napi_typeof(env, argv[PARAM0], &valueType);
978             if (valueType == napi_function) {
979                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
980             }
981         }
982 
983         if (asyncContext->callbackRef == nullptr) {
984             napi_create_promise(env, &asyncContext->deferred, &result);
985         } else {
986             napi_get_undefined(env, &result);
987         }
988 
989         napi_value resource = nullptr;
990         napi_create_string_utf8(env, "IsMicrophoneMute", NAPI_AUTO_LENGTH, &resource);
991 
992         status = napi_create_async_work(
993             env, nullptr, resource,
994             [](napi_env env, void *data) {
995                 auto context = static_cast<AudioManagerAsyncContext*>(data);
996                 if (context->status == SUCCESS) {
997                     context->isMute = context->objectInfo->audioMngr_->IsMicrophoneMute();
998                     context->isTrue = context->isMute;
999                 }
1000             },
1001             IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1002         if (status != napi_ok) {
1003             result = nullptr;
1004         } else {
1005             status = napi_queue_async_work(env, asyncContext->work);
1006             if (status == napi_ok) {
1007                 asyncContext.release();
1008             } else {
1009                 result = nullptr;
1010             }
1011         }
1012     }
1013 
1014     return result;
1015 }
1016 
SetRingerMode(napi_env env,napi_callback_info info)1017 napi_value AudioManagerNapi::SetRingerMode(napi_env env, napi_callback_info info)
1018 {
1019     napi_status status;
1020     const int32_t refCount = 1;
1021     napi_value result = nullptr;
1022 
1023     GET_PARAMS(env, info, ARGS_TWO);
1024 
1025     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1026 
1027     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1028     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1029         if (argc < ARGS_ONE) {
1030             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1031         }
1032         for (size_t i = PARAM0; i < argc; i++) {
1033             napi_valuetype valueType = napi_undefined;
1034             napi_typeof(env, argv[i], &valueType);
1035 
1036             if (i == PARAM0 && valueType == napi_number) {
1037                 napi_get_value_int32(env, argv[i], &asyncContext->ringMode);
1038                 if (!AudioCommonNapi::IsLegalInputArgumentRingMode(asyncContext->ringMode)) {
1039                     asyncContext->status = asyncContext->status ==
1040                         NAPI_ERR_INVALID_PARAM ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1041                 }
1042             } else if (i == PARAM1) {
1043                 if (valueType == napi_function) {
1044                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1045                 }
1046                 break;
1047             } else {
1048                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1049             }
1050         }
1051 
1052         if (asyncContext->callbackRef == nullptr) {
1053             napi_create_promise(env, &asyncContext->deferred, &result);
1054         } else {
1055             napi_get_undefined(env, &result);
1056         }
1057 
1058         napi_value resource = nullptr;
1059         napi_create_string_utf8(env, "SetRingerMode", NAPI_AUTO_LENGTH, &resource);
1060 
1061         status = napi_create_async_work(
1062             env, nullptr, resource,
1063             [](napi_env env, void *data) {
1064                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1065                 if (context->status == SUCCESS) {
1066                     context->status =
1067                         context->objectInfo->audioMngr_->SetRingerMode(GetNativeAudioRingerMode(context->ringMode));
1068                 }
1069             },
1070             SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1071         if (status != napi_ok) {
1072             result = nullptr;
1073         } else {
1074             status = napi_queue_async_work(env, asyncContext->work);
1075             if (status == napi_ok) {
1076                 asyncContext.release();
1077             } else {
1078                 result = nullptr;
1079             }
1080         }
1081     }
1082 
1083     return result;
1084 }
1085 
GetRingerMode(napi_env env,napi_callback_info info)1086 napi_value AudioManagerNapi::GetRingerMode(napi_env env, napi_callback_info info)
1087 {
1088     napi_status status;
1089     const int32_t refCount = 1;
1090     napi_value result = nullptr;
1091 
1092     GET_PARAMS(env, info, ARGS_ONE);
1093 
1094     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1095 
1096     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1097     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1098         if (argc > PARAM0) {
1099             napi_valuetype valueType = napi_undefined;
1100             napi_typeof(env, argv[PARAM0], &valueType);
1101             if (valueType == napi_function) {
1102                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
1103             }
1104         }
1105 
1106         if (asyncContext->callbackRef == nullptr) {
1107             napi_create_promise(env, &asyncContext->deferred, &result);
1108         } else {
1109             napi_get_undefined(env, &result);
1110         }
1111 
1112         napi_value resource = nullptr;
1113         napi_create_string_utf8(env, "GetRingerMode", NAPI_AUTO_LENGTH, &resource);
1114 
1115         status = napi_create_async_work(
1116             env, nullptr, resource,
1117             [](napi_env env, void *data) {
1118                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1119                 if (context->status == SUCCESS) {
1120                     context->ringMode = GetJsAudioRingMode(context->objectInfo->audioMngr_->GetRingerMode());
1121                     context->intValue = context->ringMode;
1122                     context->status = 0;
1123                 }
1124             },
1125             GetIntValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1126         if (status != napi_ok) {
1127             result = nullptr;
1128         } else {
1129             status = napi_queue_async_work(env, asyncContext->work);
1130             if (status == napi_ok) {
1131                 asyncContext.release();
1132             } else {
1133                 result = nullptr;
1134             }
1135         }
1136     }
1137 
1138     return result;
1139 }
1140 
SetAudioScene(napi_env env,napi_callback_info info)1141 napi_value AudioManagerNapi::SetAudioScene(napi_env env, napi_callback_info info)
1142 {
1143     HiLog::Info(LABEL, "Enter SetAudioScene!");
1144     napi_status status;
1145     const int32_t refCount = 1;
1146     napi_value result = nullptr;
1147 
1148     GET_PARAMS(env, info, ARGS_TWO);
1149 
1150     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1151 
1152     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1153     if (status != napi_ok || asyncContext->objectInfo == nullptr) {
1154         return result;
1155     }
1156     if (argc < ARGS_ONE) {
1157         asyncContext->status = NAPI_ERR_INVALID_PARAM;
1158     }
1159     for (size_t i = PARAM0; i < argc; i++) {
1160         napi_valuetype valueType = napi_undefined;
1161         napi_typeof(env, argv[i], &valueType);
1162 
1163         if (i == PARAM0 && valueType == napi_number) {
1164             napi_get_value_int32(env, argv[i], &asyncContext->scene);
1165             if ((asyncContext->scene < AUDIO_SCENE_DEFAULT) || (asyncContext->scene > AUDIO_SCENE_PHONE_CHAT)) {
1166                 asyncContext->status = NAPI_ERR_UNSUPPORTED;
1167             }
1168         } else if (i == PARAM1) {
1169             if (valueType == napi_function) {
1170                 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1171             }
1172             break;
1173         } else {
1174             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1175         }
1176     }
1177 
1178     if (asyncContext->callbackRef == nullptr) {
1179         napi_create_promise(env, &asyncContext->deferred, &result);
1180     } else {
1181         napi_get_undefined(env, &result);
1182     }
1183 
1184     napi_value resource = nullptr;
1185     napi_create_string_utf8(env, "SetAudioScene", NAPI_AUTO_LENGTH, &resource);
1186 
1187     status = napi_create_async_work(
1188         env, nullptr, resource,
1189         [](napi_env env, void *data) {
1190             auto context = static_cast<AudioManagerAsyncContext*>(data);
1191             if (context->status == SUCCESS) {
1192                 context->status =
1193                     context->objectInfo->audioMngr_->SetAudioScene(static_cast<AudioScene>(context->scene));
1194                 context->status = SUCCESS;
1195             }
1196         },
1197         SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1198     if (status != napi_ok) {
1199         result = nullptr;
1200     } else {
1201         status = napi_queue_async_work(env, asyncContext->work);
1202         if (status == napi_ok) {
1203             asyncContext.release();
1204         } else {
1205             result = nullptr;
1206         }
1207     }
1208     return result;
1209 }
1210 
GetAudioScene(napi_env env,napi_callback_info info)1211 napi_value AudioManagerNapi::GetAudioScene(napi_env env, napi_callback_info info)
1212 {
1213     napi_status status;
1214     const int32_t refCount = 1;
1215     napi_value result = nullptr;
1216 
1217     GET_PARAMS(env, info, ARGS_ONE);
1218 
1219     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1220 
1221     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1222     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1223         if (argc > PARAM0) {
1224             napi_valuetype valueType = napi_undefined;
1225             napi_typeof(env, argv[PARAM0], &valueType);
1226 
1227             if (valueType == napi_function) {
1228                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
1229             }
1230         }
1231 
1232         if (asyncContext->callbackRef == nullptr) {
1233             napi_create_promise(env, &asyncContext->deferred, &result);
1234         } else {
1235             napi_get_undefined(env, &result);
1236         }
1237 
1238         napi_value resource = nullptr;
1239         napi_create_string_utf8(env, "GetAudioScene", NAPI_AUTO_LENGTH, &resource);
1240 
1241         status = napi_create_async_work(
1242             env, nullptr, resource,
1243             [](napi_env env, void *data) {
1244                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1245                 if (context->status == SUCCESS) {
1246                     context->intValue = context->objectInfo->audioMngr_->GetAudioScene();
1247                     context->status = 0;
1248                 }
1249             },
1250             GetIntValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1251         if (status != napi_ok) {
1252             result = nullptr;
1253         } else {
1254             status = napi_queue_async_work(env, asyncContext->work);
1255             if (status == napi_ok) {
1256                 asyncContext.release();
1257             } else {
1258                 result = nullptr;
1259             }
1260         }
1261     }
1262 
1263     return result;
1264 }
1265 
SetStreamMute(napi_env env,napi_callback_info info)1266 napi_value AudioManagerNapi::SetStreamMute(napi_env env, napi_callback_info info)
1267 {
1268     napi_status status;
1269     const int32_t refCount = 1;
1270     napi_value result = nullptr;
1271 
1272     GET_PARAMS(env, info, ARGS_THREE);
1273 
1274     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1275 
1276     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1277     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1278         if (argc < ARGS_TWO) {
1279             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1280         }
1281         for (size_t i = PARAM0; i < argc; i++) {
1282             napi_valuetype valueType = napi_undefined;
1283             napi_typeof(env, argv[i], &valueType);
1284 
1285             if (i == PARAM0 && valueType == napi_number) {
1286                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
1287                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
1288                     asyncContext->status = (asyncContext->status ==
1289                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1290                 }
1291             } else if (i == PARAM1 && valueType == napi_boolean) {
1292                 napi_get_value_bool(env, argv[i], &asyncContext->isMute);
1293             } else if (i == PARAM2) {
1294                 if (valueType == napi_function) {
1295                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1296                 }
1297                 break;
1298             } else {
1299                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1300             }
1301         }
1302 
1303         if (asyncContext->callbackRef == nullptr) {
1304             napi_create_promise(env, &asyncContext->deferred, &result);
1305         } else {
1306             napi_get_undefined(env, &result);
1307         }
1308 
1309         napi_value resource = nullptr;
1310         napi_create_string_utf8(env, "SetStreamMute", NAPI_AUTO_LENGTH, &resource);
1311 
1312         status = napi_create_async_work(
1313             env, nullptr, resource,
1314             [](napi_env env, void *data) {
1315                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1316                 if (context->status == SUCCESS) {
1317                     context->status = context->objectInfo->audioMngr_->
1318                         SetMute(GetNativeAudioVolumeType(context->volType), context->isMute);
1319                 }
1320             },
1321             SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1322         if (status != napi_ok) {
1323             result = nullptr;
1324         } else {
1325             status = napi_queue_async_work(env, asyncContext->work);
1326             if (status == napi_ok) {
1327                 asyncContext.release();
1328             } else {
1329                 result = nullptr;
1330             }
1331         }
1332     }
1333 
1334     return result;
1335 }
1336 
IsStreamMute(napi_env env,napi_callback_info info)1337 napi_value AudioManagerNapi::IsStreamMute(napi_env env, napi_callback_info info)
1338 {
1339     napi_status status;
1340     const int32_t refCount = 1;
1341     napi_value result = nullptr;
1342 
1343     GET_PARAMS(env, info, ARGS_TWO);
1344 
1345     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1346 
1347     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1348     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1349         if (argc < ARGS_ONE) {
1350             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1351         }
1352         for (size_t i = PARAM0; i < argc; i++) {
1353             napi_valuetype valueType = napi_undefined;
1354             napi_typeof(env, argv[i], &valueType);
1355 
1356             if (i == PARAM0 && valueType == napi_number) {
1357                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
1358                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
1359                     asyncContext->status = (asyncContext->status ==
1360                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1361                 }
1362             } else if (i == PARAM1) {
1363                 if (valueType == napi_function) {
1364                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1365                 }
1366                 break;
1367             } else {
1368                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1369             }
1370         }
1371 
1372         if (asyncContext->callbackRef == nullptr) {
1373             napi_create_promise(env, &asyncContext->deferred, &result);
1374         } else {
1375             napi_get_undefined(env, &result);
1376         }
1377 
1378         napi_value resource = nullptr;
1379         napi_create_string_utf8(env, "IsStreamMute", NAPI_AUTO_LENGTH, &resource);
1380 
1381         status = napi_create_async_work(
1382             env, nullptr, resource,
1383             [](napi_env env, void *data) {
1384                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1385                 if (context->status == SUCCESS) {
1386                     context->isMute =
1387                         context->objectInfo->audioMngr_->IsStreamMute(GetNativeAudioVolumeType(context->volType));
1388                     context->isTrue = context->isMute;
1389                     context->status = 0;
1390                 }
1391             },
1392             IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1393         if (status != napi_ok) {
1394             result = nullptr;
1395         } else {
1396             status = napi_queue_async_work(env, asyncContext->work);
1397             if (status == napi_ok) {
1398                 asyncContext.release();
1399             } else {
1400                 result = nullptr;
1401             }
1402         }
1403     }
1404 
1405     return result;
1406 }
1407 
IsStreamActive(napi_env env,napi_callback_info info)1408 napi_value AudioManagerNapi::IsStreamActive(napi_env env, napi_callback_info info)
1409 {
1410     napi_status status;
1411     const int32_t refCount = 1;
1412     napi_value result = nullptr;
1413 
1414     GET_PARAMS(env, info, ARGS_TWO);
1415 
1416     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1417 
1418     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1419     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1420         if (argc < ARGS_ONE) {
1421             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1422         }
1423         for (size_t i = PARAM0; i < argc; i++) {
1424             napi_valuetype valueType = napi_undefined;
1425             napi_typeof(env, argv[i], &valueType);
1426 
1427             if (i == PARAM0 && valueType == napi_number) {
1428                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
1429                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
1430                     asyncContext->status = (asyncContext->status ==
1431                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1432                 }
1433             } else if (i == PARAM1) {
1434                 if (valueType == napi_function) {
1435                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1436                 }
1437                 break;
1438             } else {
1439                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1440             }
1441         }
1442 
1443         if (asyncContext->callbackRef == nullptr) {
1444             napi_create_promise(env, &asyncContext->deferred, &result);
1445         } else {
1446             napi_get_undefined(env, &result);
1447         }
1448 
1449         napi_value resource = nullptr;
1450         napi_create_string_utf8(env, "IsStreamActive", NAPI_AUTO_LENGTH, &resource);
1451 
1452         status = napi_create_async_work(
1453             env, nullptr, resource,
1454             [](napi_env edeviceTypenv, void *data) {
1455                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1456                 if (context->status == SUCCESS) {
1457                     context->isActive =
1458                         context->objectInfo->audioMngr_->IsStreamActive(GetNativeAudioVolumeType(context->volType));
1459                     context->isTrue = context->isActive;
1460                     context->status = SUCCESS;
1461                 }
1462             },
1463             IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1464         if (status != napi_ok) {
1465             result = nullptr;
1466         } else {
1467             status = napi_queue_async_work(env, asyncContext->work);
1468             if (status == napi_ok) {
1469                 asyncContext.release();
1470             } else {
1471                 result = nullptr;
1472             }
1473         }
1474     }
1475 
1476     return result;
1477 }
1478 
SetDeviceActive(napi_env env,napi_callback_info info)1479 napi_value AudioManagerNapi::SetDeviceActive(napi_env env, napi_callback_info info)
1480 {
1481     napi_status status;
1482     const int32_t refCount = 1;
1483     napi_value result = nullptr;
1484 
1485     GET_PARAMS(env, info, ARGS_THREE);
1486 
1487     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1488 
1489     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1490     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1491         if (argc < ARGS_TWO) {
1492             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1493         }
1494         for (size_t i = PARAM0; i < argc; i++) {
1495             napi_valuetype valueType = napi_undefined;
1496             napi_typeof(env, argv[i], &valueType);
1497 
1498             if (i == PARAM0 && valueType == napi_number) {
1499                 napi_get_value_int32(env, argv[i], &asyncContext->deviceType);
1500                 if (!AudioCommonNapi::IsLegalInputArgumentActiveDeviceType(asyncContext->deviceType)) {
1501                     asyncContext->status = asyncContext->status ==
1502                         NAPI_ERR_INVALID_PARAM? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1503                 }
1504             } else if (i == PARAM1 && valueType == napi_boolean) {
1505                 napi_get_value_bool(env, argv[i], &asyncContext->isActive);
1506             } else if (i == PARAM2) {
1507                 if (valueType == napi_function) {
1508                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1509                 }
1510                 break;
1511             } else {
1512                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1513             }
1514         }
1515 
1516         if (asyncContext->callbackRef == nullptr) {
1517             napi_create_promise(env, &asyncContext->deferred, &result);
1518         } else {
1519             napi_get_undefined(env, &result);
1520         }
1521 
1522         napi_value resource = nullptr;
1523         napi_create_string_utf8(env, "SetDeviceActive", NAPI_AUTO_LENGTH, &resource);
1524 
1525         status = napi_create_async_work(
1526             env, nullptr, resource,
1527             [](napi_env env, void *data) {
1528                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1529                 if (context->status == 0) {
1530                     context->status = context->objectInfo->audioMngr_->SetDeviceActive(
1531                         static_cast<ActiveDeviceType>(context->deviceType), context->isActive);
1532                 }
1533             },
1534             SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1535         if (status != napi_ok) {
1536             result = nullptr;
1537         } else {
1538             status = napi_queue_async_work(env, asyncContext->work);
1539             if (status == napi_ok) {
1540                 asyncContext.release();
1541             } else {
1542                 result = nullptr;
1543             }
1544         }
1545     }
1546 
1547     return result;
1548 }
1549 
IsDeviceActive(napi_env env,napi_callback_info info)1550 napi_value AudioManagerNapi::IsDeviceActive(napi_env env, napi_callback_info info)
1551 {
1552     napi_status status;
1553     const int32_t refCount = 1;
1554     napi_value result = nullptr;
1555 
1556     GET_PARAMS(env, info, ARGS_TWO);
1557 
1558     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1559 
1560     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1561     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1562         if (argc < ARGS_ONE) {
1563             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1564         }
1565         for (size_t i = PARAM0; i < argc; i++) {
1566             napi_valuetype valueType = napi_undefined;
1567             napi_typeof(env, argv[i], &valueType);
1568 
1569             if (i == PARAM0 && valueType == napi_number) {
1570                 napi_get_value_int32(env, argv[i], &asyncContext->deviceType);
1571                 if (!AudioCommonNapi::IsLegalInputArgumentActiveDeviceType(asyncContext->deviceType)) {
1572                     asyncContext->status = asyncContext->status ==
1573                         NAPI_ERR_INVALID_PARAM? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1574                 }
1575             } else if (i == PARAM1) {
1576                 if (valueType == napi_function) {
1577                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1578                 }
1579                 break;
1580             } else {
1581                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1582             }
1583         }
1584 
1585         if (asyncContext->callbackRef == nullptr) {
1586             napi_create_promise(env, &asyncContext->deferred, &result);
1587         } else {
1588             napi_get_undefined(env, &result);
1589         }
1590 
1591         napi_value resource = nullptr;
1592         napi_create_string_utf8(env, "IsDeviceActive", NAPI_AUTO_LENGTH, &resource);
1593 
1594         status = napi_create_async_work(
1595             env, nullptr, resource,
1596             [](napi_env env, void *data) {
1597                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1598                 if (context->status == SUCCESS) {
1599                     context->isActive = context->objectInfo->audioMngr_->
1600                         IsDeviceActive(static_cast<ActiveDeviceType>(context->deviceType));
1601                     context->isTrue = context->isActive;
1602                     context->status = 0;
1603                 }
1604             },
1605             IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1606         if (status != napi_ok) {
1607             result = nullptr;
1608         } else {
1609             status = napi_queue_async_work(env, asyncContext->work);
1610             if (status == napi_ok) {
1611                 asyncContext.release();
1612             } else {
1613                 result = nullptr;
1614             }
1615         }
1616     }
1617 
1618     return result;
1619 }
1620 
SetAudioParameter(napi_env env,napi_callback_info info)1621 napi_value AudioManagerNapi::SetAudioParameter(napi_env env, napi_callback_info info)
1622 {
1623     napi_status status;
1624     const int32_t refCount = 1;
1625     napi_value result = nullptr;
1626 
1627     GET_PARAMS(env, info, ARGS_THREE);
1628 
1629     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1630 
1631     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1632     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1633         if (argc < ARGS_TWO) {
1634             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1635         }
1636         for (size_t i = PARAM0; i < argc; i++) {
1637             napi_valuetype valueType = napi_undefined;
1638             napi_typeof(env, argv[i], &valueType);
1639 
1640             if (i == PARAM0 && valueType == napi_string) {
1641                 asyncContext->key = AudioCommonNapi::GetStringArgument(env, argv[i]);
1642             } else if (i == PARAM1 && valueType == napi_string) {
1643                 asyncContext->valueStr = AudioCommonNapi::GetStringArgument(env, argv[i]);
1644             } else if (i == PARAM2) {
1645                 if (valueType == napi_function) {
1646                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1647                 }
1648                 break;
1649             } else {
1650                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1651             }
1652         }
1653 
1654         if (asyncContext->callbackRef == nullptr) {
1655             napi_create_promise(env, &asyncContext->deferred, &result);
1656         } else {
1657             napi_get_undefined(env, &result);
1658         }
1659 
1660         napi_value resource = nullptr;
1661         napi_create_string_utf8(env, "SetAudioParameter", NAPI_AUTO_LENGTH, &resource);
1662 
1663         status = napi_create_async_work(
1664             env, nullptr, resource,
1665             [](napi_env env, void *data) {
1666                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1667                 if (context->status == SUCCESS) {
1668                     context->objectInfo->audioMngr_->SetAudioParameter(context->key, context->valueStr);
1669                     context->status = 0;
1670                 }
1671             },
1672             SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1673         if (status != napi_ok) {
1674             result = nullptr;
1675         } else {
1676             status = napi_queue_async_work(env, asyncContext->work);
1677             if (status == napi_ok) {
1678                 asyncContext.release();
1679             } else {
1680                 result = nullptr;
1681             }
1682         }
1683     }
1684 
1685     return result;
1686 }
1687 
GetAudioParameter(napi_env env,napi_callback_info info)1688 napi_value AudioManagerNapi::GetAudioParameter(napi_env env, napi_callback_info info)
1689 {
1690     napi_status status;
1691     const int32_t refCount = 1;
1692     napi_value result = nullptr;
1693 
1694     GET_PARAMS(env, info, ARGS_TWO);
1695 
1696     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1697 
1698     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1699     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1700         if (argc < ARGS_ONE) {
1701             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1702         }
1703         for (size_t i = PARAM0; i < argc; i++) {
1704             napi_valuetype valueType = napi_undefined;
1705             napi_typeof(env, argv[i], &valueType);
1706 
1707             if (i == PARAM0 && valueType == napi_string) {
1708                 asyncContext->key = AudioCommonNapi::GetStringArgument(env, argv[i]);
1709             } else if (i == PARAM1) {
1710                 if (valueType == napi_function) {
1711                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1712                 }
1713                 break;
1714             } else {
1715                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1716             }
1717         }
1718 
1719         if (asyncContext->callbackRef == nullptr) {
1720             napi_create_promise(env, &asyncContext->deferred, &result);
1721         } else {
1722             napi_get_undefined(env, &result);
1723         }
1724 
1725         napi_value resource = nullptr;
1726         napi_create_string_utf8(env, "GetAudioParameter", NAPI_AUTO_LENGTH, &resource);
1727         status = napi_create_async_work(
1728             env, nullptr, resource,
1729             [](napi_env env, void *data) {
1730                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1731                 if (context->status == SUCCESS) {
1732                     context->valueStr = context->objectInfo->audioMngr_->GetAudioParameter(context->key);
1733                     context->status = 0;
1734                 }
1735             },
1736             GetStringValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1737         if (status != napi_ok) {
1738             result = nullptr;
1739         } else {
1740             status = napi_queue_async_work(env, asyncContext->work);
1741             if (status == napi_ok) {
1742                 asyncContext.release();
1743             } else {
1744                 result = nullptr;
1745             }
1746         }
1747     }
1748 
1749     return result;
1750 }
1751 
SetVolume(napi_env env,napi_callback_info info)1752 napi_value AudioManagerNapi::SetVolume(napi_env env, napi_callback_info info)
1753 {
1754     napi_status status;
1755     const int32_t refCount = 1;
1756     napi_value result = nullptr;
1757 
1758     GET_PARAMS(env, info, ARGS_THREE);
1759 
1760     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1761 
1762     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1763     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1764         if (argc < ARGS_TWO) {
1765             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1766         }
1767         for (size_t i = PARAM0; i < argc; i++) {
1768             napi_valuetype valueType = napi_undefined;
1769             napi_typeof(env, argv[i], &valueType);
1770 
1771             if (i == PARAM0 && valueType == napi_number) {
1772                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
1773                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
1774                     asyncContext->status = (asyncContext->status ==
1775                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1776                 }
1777             } else if (i == PARAM1 && valueType == napi_number) {
1778                 napi_get_value_int32(env, argv[i], &asyncContext->volLevel);
1779                 if (!AudioCommonNapi::IsLegalInputArgumentVolLevel(asyncContext->volLevel)) {
1780                     asyncContext->status = (asyncContext->status ==
1781                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1782                 }
1783             } else if (i == PARAM2) {
1784                 if (valueType == napi_function) {
1785                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1786                 }
1787                 break;
1788             } else {
1789                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1790             }
1791         }
1792 
1793         if (asyncContext->callbackRef == nullptr) {
1794             napi_create_promise(env, &asyncContext->deferred, &result);
1795         } else {
1796             napi_get_undefined(env, &result);
1797         }
1798 
1799         napi_value resource = nullptr;
1800         napi_create_string_utf8(env, "SetVolume", NAPI_AUTO_LENGTH, &resource);
1801 
1802         status = napi_create_async_work(
1803             env, nullptr, resource,
1804             [](napi_env env, void *data) {
1805                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1806                 if (context->status == SUCCESS) {
1807                     context->status = context->objectInfo->audioMngr_->
1808                         SetVolume(GetNativeAudioVolumeType(context->volType), context->volLevel);
1809                 }
1810             },
1811             SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1812         if (status != napi_ok) {
1813             result = nullptr;
1814         } else {
1815             status = napi_queue_async_work(env, asyncContext->work);
1816             if (status == napi_ok) {
1817                 asyncContext.release();
1818             } else {
1819                 result = nullptr;
1820             }
1821         }
1822     }
1823 
1824     return result;
1825 }
1826 
GetVolume(napi_env env,napi_callback_info info)1827 napi_value AudioManagerNapi::GetVolume(napi_env env, napi_callback_info info)
1828 {
1829     napi_status status;
1830     const int32_t refCount = 1;
1831     napi_value result = nullptr;
1832 
1833     GET_PARAMS(env, info, ARGS_TWO);
1834 
1835     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1836 
1837     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1838     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1839         if (argc < ARGS_ONE) {
1840             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1841         }
1842         for (size_t i = PARAM0; i < argc; i++) {
1843             napi_valuetype valueType = napi_undefined;
1844             napi_typeof(env, argv[i], &valueType);
1845 
1846             if (i == PARAM0 && valueType == napi_number) {
1847                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
1848                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
1849                     asyncContext->status = (asyncContext->status ==
1850                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1851                 }
1852             } else if (i == PARAM1) {
1853                 if (valueType == napi_function) {
1854                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1855                 }
1856                 break;
1857             } else {
1858                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1859             }
1860         }
1861 
1862         if (asyncContext->callbackRef == nullptr) {
1863             napi_create_promise(env, &asyncContext->deferred, &result);
1864         } else {
1865             napi_get_undefined(env, &result);
1866         }
1867 
1868         napi_value resource = nullptr;
1869         napi_create_string_utf8(env, "GetVolume", NAPI_AUTO_LENGTH, &resource);
1870 
1871         status = napi_create_async_work(
1872             env, nullptr, resource,
1873             [](napi_env env, void *data) {
1874                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1875                     if (context->status == SUCCESS) {
1876                         context->volLevel = context->objectInfo->audioMngr_->GetVolume(
1877                             GetNativeAudioVolumeType(context->volType));
1878                         context->intValue = context->volLevel;
1879                         context->status = 0;
1880                     }
1881             },
1882             GetIntValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1883         if (status != napi_ok) {
1884             result = nullptr;
1885         } else {
1886             status = napi_queue_async_work(env, asyncContext->work);
1887             if (status == napi_ok) {
1888                 asyncContext.release();
1889             } else {
1890                 result = nullptr;
1891             }
1892         }
1893     }
1894 
1895     return result;
1896 }
1897 
GetMaxVolume(napi_env env,napi_callback_info info)1898 napi_value AudioManagerNapi::GetMaxVolume(napi_env env, napi_callback_info info)
1899 {
1900     napi_status status;
1901     const int32_t refCount = 1;
1902     napi_value result = nullptr;
1903 
1904     GET_PARAMS(env, info, ARGS_TWO);
1905 
1906     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1907 
1908     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1909     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1910         if (argc < ARGS_ONE) {
1911             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1912         }
1913         for (size_t i = PARAM0; i < argc; i++) {
1914             napi_valuetype valueType = napi_undefined;
1915             napi_typeof(env, argv[i], &valueType);
1916 
1917             if (i == PARAM0 && valueType == napi_number) {
1918                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
1919                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
1920                     asyncContext->status = (asyncContext->status ==
1921                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1922                 }
1923             } else if (i == PARAM1) {
1924                 if (valueType == napi_function) {
1925                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1926                 }
1927                 break;
1928             } else {
1929                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1930             }
1931         }
1932 
1933         if (asyncContext->callbackRef == nullptr) {
1934             napi_create_promise(env, &asyncContext->deferred, &result);
1935         } else {
1936             napi_get_undefined(env, &result);
1937         }
1938 
1939         napi_value resource = nullptr;
1940         napi_create_string_utf8(env, "GetMaxVolume", NAPI_AUTO_LENGTH, &resource);
1941 
1942         status = napi_create_async_work(
1943             env, nullptr, resource,
1944             [](napi_env env, void *data) {
1945                 auto context = static_cast<AudioManagerAsyncContext*>(data);
1946                 if (context->status == SUCCESS) {
1947                     context->volLevel = context->objectInfo->audioMngr_->GetMaxVolume(
1948                         GetNativeAudioVolumeType(context->volType));
1949                     context->intValue = context->volLevel;
1950                     context->status = 0;
1951                 }
1952             },
1953             GetIntValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1954         if (status != napi_ok) {
1955             result = nullptr;
1956         } else {
1957             status = napi_queue_async_work(env, asyncContext->work);
1958             if (status == napi_ok) {
1959                 asyncContext.release();
1960             } else {
1961                 result = nullptr;
1962             }
1963         }
1964     }
1965 
1966     return result;
1967 }
1968 
GetMinVolume(napi_env env,napi_callback_info info)1969 napi_value AudioManagerNapi::GetMinVolume(napi_env env, napi_callback_info info)
1970 {
1971     napi_status status;
1972     const int32_t refCount = 1;
1973     napi_value result = nullptr;
1974 
1975     GET_PARAMS(env, info, ARGS_TWO);
1976 
1977     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
1978 
1979     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1980     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1981         if (argc < ARGS_ONE) {
1982             asyncContext->status = NAPI_ERR_INVALID_PARAM;
1983         }
1984         for (size_t i = PARAM0; i < argc; i++) {
1985             napi_valuetype valueType = napi_undefined;
1986             napi_typeof(env, argv[i], &valueType);
1987 
1988             if (i == PARAM0 && valueType == napi_number) {
1989                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
1990                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
1991                     asyncContext->status = (asyncContext->status ==
1992                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1993                 }
1994             } else if (i == PARAM1) {
1995                 if (valueType == napi_function) {
1996                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1997                 }
1998                 break;
1999             } else {
2000                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
2001             }
2002         }
2003 
2004         if (asyncContext->callbackRef == nullptr) {
2005             napi_create_promise(env, &asyncContext->deferred, &result);
2006         } else {
2007             napi_get_undefined(env, &result);
2008         }
2009 
2010         napi_value resource = nullptr;
2011         napi_create_string_utf8(env, "GetMinVolume", NAPI_AUTO_LENGTH, &resource);
2012 
2013         status = napi_create_async_work(
2014             env, nullptr, resource,
2015             [](napi_env env, void *data) {
2016                 auto context = static_cast<AudioManagerAsyncContext*>(data);
2017                 if (context->status == SUCCESS) {
2018                     context->volLevel = context->objectInfo->audioMngr_->GetMinVolume(
2019                         GetNativeAudioVolumeType(context->volType));
2020                     context->intValue = context->volLevel;
2021                     context->status = 0;
2022                 }
2023             },
2024             GetIntValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
2025         if (status != napi_ok) {
2026             result = nullptr;
2027         } else {
2028             status = napi_queue_async_work(env, asyncContext->work);
2029             if (status == napi_ok) {
2030                 asyncContext.release();
2031             } else {
2032                 result = nullptr;
2033             }
2034         }
2035     }
2036 
2037     return result;
2038 }
2039 
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int intValue,napi_value & result)2040 static void SetValueInt32(const napi_env& env, const std::string& fieldStr, const int intValue, napi_value &result)
2041 {
2042     napi_value value = nullptr;
2043     napi_create_int32(env, intValue, &value);
2044     napi_set_named_property(env, result, fieldStr.c_str(), value);
2045 }
2046 
SetValueString(const napi_env & env,const std::string & fieldStr,const std::string stringValue,napi_value & result)2047 static void SetValueString(const napi_env &env, const std::string &fieldStr, const std::string stringValue,
2048     napi_value &result)
2049 {
2050     napi_value value = nullptr;
2051     napi_create_string_utf8(env, stringValue.c_str(), NAPI_AUTO_LENGTH, &value);
2052     napi_set_named_property(env, result, fieldStr.c_str(), value);
2053 }
2054 
GetDevicesAsyncCallbackComplete(napi_env env,napi_status status,void * data)2055 static void GetDevicesAsyncCallbackComplete(napi_env env, napi_status status, void *data)
2056 {
2057     auto asyncContext = static_cast<AudioManagerAsyncContext*>(data);
2058     if (asyncContext == nullptr) {
2059         HiLog::Error(LABEL, "ERROR: AudioRoutingManagerAsyncContext* is Null!");
2060         return;
2061     }
2062     napi_value result[ARGS_TWO] = {0};
2063     napi_value valueParam = nullptr;
2064     size_t size = asyncContext->deviceDescriptors.size();
2065     HiLog::Info(LABEL, "number of devices = %{public}zu", size);
2066 
2067     napi_create_array_with_length(env, size, &result[PARAM1]);
2068     for (size_t i = 0; i < size; i++) {
2069         if (asyncContext->deviceDescriptors[i] != nullptr) {
2070             (void)napi_create_object(env, &valueParam);
2071             SetValueInt32(env, "deviceRole", static_cast<int32_t>(
2072                 asyncContext->deviceDescriptors[i]->deviceRole_), valueParam);
2073             SetValueInt32(env, "deviceType", static_cast<int32_t>(
2074                 asyncContext->deviceDescriptors[i]->deviceType_), valueParam);
2075             SetValueInt32(env, "id", static_cast<int32_t>(
2076                 asyncContext->deviceDescriptors[i]->deviceId_), valueParam);
2077             SetValueString(env, "name", asyncContext->deviceDescriptors[i]->deviceName_, valueParam);
2078             SetValueString(env, "address", asyncContext->deviceDescriptors[i]->macAddress_, valueParam);
2079 
2080             napi_value value = nullptr;
2081             napi_value sampleRates;
2082             napi_create_array_with_length(env, 1, &sampleRates);
2083             napi_create_int32(env, asyncContext->deviceDescriptors[i]->audioStreamInfo_.samplingRate, &value);
2084             napi_set_element(env, sampleRates, 0, value);
2085             napi_set_named_property(env, valueParam, "sampleRates", sampleRates);
2086 
2087             napi_value channelCounts;
2088             napi_create_array_with_length(env, 1, &channelCounts);
2089             napi_create_int32(env, asyncContext->deviceDescriptors[i]->audioStreamInfo_.channels, &value);
2090             napi_set_element(env, channelCounts, 0, value);
2091             napi_set_named_property(env, valueParam, "channelCounts", channelCounts);
2092 
2093             napi_value channelMasks;
2094             napi_create_array_with_length(env, 1, &channelMasks);
2095             napi_create_int32(env, asyncContext->deviceDescriptors[i]->channelMasks_, &value);
2096             napi_set_element(env, channelMasks, 0, value);
2097             napi_set_named_property(env, valueParam, "channelMasks", channelMasks);
2098 
2099             napi_set_element(env, result[PARAM1], i, valueParam);
2100         }
2101     }
2102 
2103     napi_get_undefined(env, &result[PARAM0]);
2104     if (!asyncContext->status) {
2105         napi_get_undefined(env, &valueParam);
2106     }
2107     CommonCallbackRoutine(env, asyncContext, result[PARAM1]);
2108 }
2109 
GetDevices(napi_env env,napi_callback_info info)2110 napi_value AudioManagerNapi::GetDevices(napi_env env, napi_callback_info info)
2111 {
2112     napi_status status;
2113     const int32_t refCount = 1;
2114     napi_value result = nullptr;
2115 
2116     GET_PARAMS(env, info, ARGS_TWO);
2117 
2118     unique_ptr<AudioManagerAsyncContext> asyncContext = make_unique<AudioManagerAsyncContext>();
2119 
2120     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
2121     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
2122         if (argc < PARAM1) {
2123             asyncContext->status = NAPI_ERR_INVALID_PARAM;
2124         }
2125         for (size_t i = PARAM0; i < argc; i++) {
2126             napi_valuetype valueType = napi_undefined;
2127             napi_typeof(env, argv[i], &valueType);
2128 
2129             if (i == PARAM0 && valueType == napi_number) {
2130                 napi_get_value_int32(env, argv[i], &asyncContext->deviceFlag);
2131                 if (!AudioCommonNapi::IsLegalInputArgumentDeviceFlag(asyncContext->deviceFlag)) {
2132                     asyncContext->status = asyncContext->status ==
2133                         NAPI_ERR_INVALID_PARAM ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
2134                 }
2135             } else if (i == PARAM1) {
2136                 if (valueType == napi_function) {
2137                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
2138                 }
2139                 break;
2140             } else {
2141                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
2142             }
2143         }
2144 
2145         if (asyncContext->callbackRef == nullptr) {
2146             napi_create_promise(env, &asyncContext->deferred, &result);
2147         } else {
2148             napi_get_undefined(env, &result);
2149         }
2150 
2151         napi_value resource = nullptr;
2152         napi_create_string_utf8(env, "GetDevices", NAPI_AUTO_LENGTH, &resource);
2153 
2154         status = napi_create_async_work(
2155             env, nullptr, resource,
2156             [](napi_env env, void *data) {
2157                 auto context = static_cast<AudioManagerAsyncContext*>(data);
2158                 if (context->status == SUCCESS) {
2159                     context->deviceDescriptors = context->objectInfo->audioMngr_->GetDevices(
2160                         static_cast<DeviceFlag>(context->deviceFlag));
2161                     context->status = 0;
2162                 }
2163             },
2164             GetDevicesAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
2165         if (status != napi_ok) {
2166             result = nullptr;
2167         } else {
2168             status = napi_queue_async_work(env, asyncContext->work);
2169             if (status == napi_ok) {
2170                 asyncContext.release();
2171             } else {
2172                 result = nullptr;
2173             }
2174         }
2175     }
2176 
2177     return result;
2178 }
2179 
UndefinedNapiValue(const napi_env & env)2180 napi_value UndefinedNapiValue(const napi_env& env)
2181 {
2182     napi_value result = nullptr;
2183     napi_get_undefined(env, &result);
2184     return result;
2185 }
2186 
JsObjectToInt(const napi_env & env,const napi_value & object,std::string fieldStr,int32_t & fieldRef)2187 napi_status JsObjectToInt(const napi_env &env, const napi_value &object, std::string fieldStr, int32_t &fieldRef)
2188 {
2189     napi_value tempValue = nullptr;
2190     napi_status status = napi_get_named_property(env, object, fieldStr.c_str(), &tempValue);
2191     if (status != napi_ok) {
2192         AUDIO_ERR_LOG("JsObjectToInt: Failed to retrieve property %{public}s", fieldStr.c_str());
2193         return status;
2194     }
2195     status = napi_get_value_int32(env, tempValue, &fieldRef);
2196     if (status != napi_ok) {
2197         AUDIO_ERR_LOG("JsObjectToInt: Failed to retrieve value for property %{public}s", fieldStr.c_str());
2198     }
2199     return status;
2200 }
2201 
JsObjectToBool(const napi_env & env,const napi_value & object,std::string fieldStr,bool & fieldRef)2202 napi_status JsObjectToBool(const napi_env &env, const napi_value &object, std::string fieldStr, bool &fieldRef)
2203 {
2204     napi_value tempValue = nullptr;
2205     napi_status status = napi_get_named_property(env, object, fieldStr.c_str(), &tempValue);
2206     if (status != napi_ok) {
2207         AUDIO_ERR_LOG("JsObjectToBool: Failed to retrieve property %{public}s", fieldStr.c_str());
2208         return status;
2209     }
2210     status = napi_get_value_bool(env, tempValue, &fieldRef);
2211     if (status != napi_ok) {
2212         AUDIO_ERR_LOG("JsObjectToBool: Failed to retrieve value for property %{public}s", fieldStr.c_str());
2213     }
2214     return status;
2215 }
2216 
JsObjToAudioInterrupt(const napi_env & env,const napi_value & object,AudioInterrupt & audioInterrupt)2217 napi_status JsObjToAudioInterrupt(const napi_env& env, const napi_value& object, AudioInterrupt &audioInterrupt)
2218 {
2219     int32_t propValue = -1;
2220     napi_status status = JsObjectToInt(env, object, "contentType", propValue);
2221     if (status != napi_ok) {
2222         AUDIO_ERR_LOG("JsObjToAudioInterrupt: Failed to retrieve contentType");
2223         return status;
2224     }
2225     audioInterrupt.contentType = static_cast<ContentType>(propValue);
2226 
2227     status = JsObjectToInt(env, object, "streamUsage", propValue);
2228     if (status != napi_ok) {
2229         AUDIO_ERR_LOG("JsObjToAudioInterrupt: Failed to retrieve streamUsage");
2230         return status;
2231     }
2232     audioInterrupt.streamUsage = static_cast<StreamUsage>(propValue);
2233 
2234     status = JsObjectToBool(env, object, "pauseWhenDucked", audioInterrupt.pauseWhenDucked);
2235     if (status != napi_ok) {
2236         AUDIO_ERR_LOG("JsObjToAudioInterrupt: Failed to retrieve pauseWhenDucked");
2237         return status;
2238     }
2239     // Update Stream type based on Content type and Stream Usage type
2240     audioInterrupt.streamType = AudioSystemManager::GetStreamType(audioInterrupt.contentType,
2241         audioInterrupt.streamUsage);
2242     AUDIO_INFO_LOG("JsObjToAudioInterrupt: ContentType %{public}d, streamUsage %{public}d, streamType %{public}d ",
2243         audioInterrupt.contentType, audioInterrupt.streamUsage, audioInterrupt.streamType);
2244     return status;
2245 }
2246 
On(napi_env env,napi_callback_info info)2247 napi_value AudioManagerNapi::On(napi_env env, napi_callback_info info)
2248 {
2249     napi_value undefinedResult = nullptr;
2250     napi_get_undefined(env, &undefinedResult);
2251 
2252     const size_t minArgCount = 2;
2253     size_t argCount = 3;
2254     napi_value args[minArgCount + 1] = {nullptr, nullptr, nullptr};
2255     napi_value jsThis = nullptr;
2256     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
2257     if (status != napi_ok || argCount < minArgCount) {
2258         AUDIO_ERR_LOG("On fail to napi_get_cb_info/Requires min 2 parameters");
2259         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
2260         return undefinedResult;
2261     }
2262 
2263     napi_valuetype eventType = napi_undefined;
2264     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
2265         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
2266         return undefinedResult;
2267     }
2268     std::string callbackName = AudioCommonNapi::GetStringArgument(env, args[0]);
2269     AUDIO_INFO_LOG("AudioManagerNapi::On callbackName: %{public}s", callbackName.c_str());
2270 
2271     AudioManagerNapi *managerNapi = nullptr;
2272     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&managerNapi));
2273     napi_valuetype handler = napi_undefined;
2274     if (argCount == minArgCount) {
2275         napi_valuetype handler = napi_undefined;
2276         if (napi_typeof(env, args[PARAM1], &handler) != napi_ok || handler != napi_function) {
2277             AUDIO_ERR_LOG("AudioManagerNapi::On type mismatch for parameter 2");
2278             AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
2279             return undefinedResult;
2280         }
2281     } else {
2282         napi_valuetype paramArg1 = napi_undefined;
2283         napi_typeof(env, args[PARAM1], &paramArg1);
2284         if (!callbackName.compare(INTERRUPT_CALLBACK_NAME)) {
2285             if (paramArg1 != napi_object) {
2286                 AUDIO_ERR_LOG("AudioManagerNapi::On Type mismatch for parameter 2");
2287                 AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
2288                 return undefinedResult;
2289             }
2290             if (napi_typeof(env, args[PARAM2], &handler) != napi_ok || handler != napi_function) {
2291                 AUDIO_ERR_LOG("AudioManagerNapi::On type mismatch for parameter 3");
2292                 AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
2293                 return undefinedResult;
2294             }
2295         }
2296 
2297         if (managerNapi->interruptCallbackNapi_ == nullptr) {
2298             managerNapi->interruptCallbackNapi_ = std::make_shared<AudioManagerInterruptCallbackNapi>(env);
2299             int32_t ret = managerNapi->audioMngr_->
2300                 SetAudioManagerInterruptCallback(managerNapi->interruptCallbackNapi_);
2301             if (ret) {
2302                 AUDIO_ERR_LOG("AudioManagerNapi: SetAudioManagerInterruptCallback Failed");
2303                 return undefinedResult;
2304             }
2305         }
2306         std::shared_ptr<AudioManagerInterruptCallbackNapi> cb =
2307         std::static_pointer_cast<AudioManagerInterruptCallbackNapi>(managerNapi->interruptCallbackNapi_);
2308         cb->SaveCallbackReference(callbackName, args[PARAM2]);
2309         AudioInterrupt audioInterrupt;
2310         status = JsObjToAudioInterrupt(env, args[PARAM1], audioInterrupt);
2311         int32_t ret = managerNapi->audioMngr_->RequestAudioFocus(audioInterrupt);
2312         if (ret) {
2313             AUDIO_ERR_LOG("AudioManagerNapi: RequestAudioFocus Failed");
2314             return undefinedResult;
2315         }
2316         AUDIO_INFO_LOG("AudioManagerNapi::On SetAudioManagerInterruptCallback and RequestAudioFocus is successful");
2317     }
2318 
2319     if (!callbackName.compare(RINGERMODE_CALLBACK_NAME)) {
2320         if (managerNapi->ringerModecallbackNapi_ == nullptr) {
2321             managerNapi->ringerModecallbackNapi_ = std::make_shared<AudioRingerModeCallbackNapi>(env);
2322             int32_t ret = managerNapi->audioMngr_->SetRingerModeCallback(
2323                 managerNapi->cachedClientId_, managerNapi->ringerModecallbackNapi_);
2324             if (ret) {
2325                 AUDIO_ERR_LOG("AudioManagerNapi: SetRingerModeCallback Failed");
2326                 return undefinedResult;
2327             } else {
2328                 AUDIO_INFO_LOG("AudioManagerNapi: SetRingerModeCallback Success");
2329             }
2330         }
2331 
2332         std::shared_ptr<AudioRingerModeCallbackNapi> cb =
2333             std::static_pointer_cast<AudioRingerModeCallbackNapi>(managerNapi->ringerModecallbackNapi_);
2334         cb->SaveCallbackReference(callbackName, args[PARAM1]);
2335     } else if (!callbackName.compare(VOLUME_CHANGE_CALLBACK_NAME)) {
2336         std::shared_ptr<AudioVolumeKeyEventNapi> cb =
2337             std::static_pointer_cast<AudioVolumeKeyEventNapi>(managerNapi->volumeKeyEventCallbackNapi_);
2338         cb->SaveCallbackReference(callbackName, args[PARAM1]);
2339     } else if (!callbackName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
2340         if (managerNapi->deviceChangeCallbackNapi_ == nullptr) {
2341             managerNapi->deviceChangeCallbackNapi_ = std::make_shared<AudioManagerCallbackNapi>(env);
2342         }
2343         int32_t ret = managerNapi->audioMngr_->SetDeviceChangeCallback(DeviceFlag::ALL_DEVICES_FLAG,
2344             managerNapi->deviceChangeCallbackNapi_);
2345         if (ret) {
2346             AUDIO_ERR_LOG("AudioManagerNapi: SetDeviceChangeCallback Failed");
2347             return undefinedResult;
2348         }
2349         std::shared_ptr<AudioManagerCallbackNapi> cb =
2350         std::static_pointer_cast<AudioManagerCallbackNapi>(managerNapi->deviceChangeCallbackNapi_);
2351         cb->SaveCallbackReference(callbackName, args[PARAM1]);
2352         AUDIO_INFO_LOG("AudioManagerNapi::On SetDeviceChangeCallback is successful");
2353     }
2354     return undefinedResult;
2355 }
2356 
Off(napi_env env,napi_callback_info info)2357 napi_value AudioManagerNapi::Off(napi_env env, napi_callback_info info)
2358 {
2359     napi_value undefinedResult = nullptr;
2360     napi_get_undefined(env, &undefinedResult);
2361 
2362     const size_t minArgCount = 1;
2363     size_t argCount = 3;
2364     napi_value args[minArgCount + 2] = {nullptr, nullptr, nullptr};
2365     napi_value jsThis = nullptr;
2366     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
2367     if (status != napi_ok || argCount < minArgCount) {
2368         AUDIO_ERR_LOG("Off fail to napi_get_cb_info/Requires min 1 parameters");
2369         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
2370         return undefinedResult;
2371     }
2372 
2373     napi_valuetype eventType = napi_undefined;
2374     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
2375         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
2376         return undefinedResult;
2377     }
2378     std::string callbackName = AudioCommonNapi::GetStringArgument(env, args[0]);
2379     AUDIO_INFO_LOG("AudioManagerNapi::Off callbackName: %{public}s", callbackName.c_str());
2380 
2381     AudioManagerNapi *managerNapi = nullptr;
2382     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&managerNapi));
2383 
2384     napi_valuetype handler = napi_undefined;
2385     if (!callbackName.compare(INTERRUPT_CALLBACK_NAME) && argCount > ARGS_ONE) {
2386         napi_valuetype paramArg1 = napi_undefined;
2387         if (napi_typeof(env, args[PARAM1], &paramArg1) != napi_ok || paramArg1 != napi_object) {
2388             AUDIO_ERR_LOG("AudioManagerNapi::Off type mismatch for parameter 2");
2389             AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
2390             return undefinedResult;
2391         }
2392         if (argCount == ARGS_THREE) {
2393             if (napi_typeof(env, args[PARAM2], &handler) != napi_ok || handler != napi_function) {
2394                 AUDIO_ERR_LOG("AudioManagerNapi::Off type mismatch for parameter 3");
2395                 AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
2396                 return undefinedResult;
2397             }
2398         }
2399         AudioInterrupt audioInterrupt;
2400         status = JsObjToAudioInterrupt(env, args[PARAM1], audioInterrupt);
2401         int32_t ret = managerNapi->audioMngr_->AbandonAudioFocus(audioInterrupt);
2402         if (ret) {
2403             AUDIO_ERR_LOG("AudioManagerNapi::Off AbandonAudioFocus Failed");
2404         }
2405         ret = managerNapi->audioMngr_->UnsetAudioManagerInterruptCallback();
2406         if (ret) {
2407             AUDIO_ERR_LOG("AudioManagerNapi::Off UnsetAudioManagerInterruptCallback Failed");
2408             return undefinedResult;
2409         }
2410         if (managerNapi->interruptCallbackNapi_ != nullptr) {
2411             managerNapi->interruptCallbackNapi_.reset();
2412             managerNapi->interruptCallbackNapi_ = nullptr;
2413         }
2414         AUDIO_INFO_LOG("AudioManagerNapi::Off Abandon Focus and UnSetAudioInterruptCallback success");
2415     } else if (!callbackName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
2416         int32_t ret = managerNapi->audioMngr_->UnsetDeviceChangeCallback();
2417         if (ret) {
2418             AUDIO_ERR_LOG("AudioManagerNapi::Off UnsetDeviceChangeCallback Failed");
2419             return undefinedResult;
2420         }
2421         if (managerNapi->deviceChangeCallbackNapi_ != nullptr) {
2422             managerNapi->deviceChangeCallbackNapi_.reset();
2423             managerNapi->deviceChangeCallbackNapi_ = nullptr;
2424         }
2425         AUDIO_INFO_LOG("AudioManagerNapi::Off UnsetDeviceChangeCallback Success");
2426     } else {
2427         AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
2428     }
2429     return undefinedResult;
2430 }
2431 
2432 
GetStreamManager(napi_env env,napi_callback_info info)2433 napi_value AudioManagerNapi::GetStreamManager(napi_env env, napi_callback_info info)
2434 {
2435     napi_status status;
2436     size_t argCount = 0;
2437 
2438     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
2439     if (status != napi_ok || argCount != 0) {
2440         HiLog::Error(LABEL, "Invalid arguments!");
2441         return nullptr;
2442     }
2443 
2444     return AudioStreamMgrNapi::CreateStreamManagerWrapper(env);
2445 }
2446 
2447 
GetRoutingManager(napi_env env,napi_callback_info info)2448 napi_value AudioManagerNapi::GetRoutingManager(napi_env env, napi_callback_info info)
2449 {
2450     napi_status status;
2451     size_t argCount = 0;
2452 
2453     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
2454     if (status != napi_ok || argCount != 0) {
2455         HiLog::Error(LABEL, "Invalid arguments!");
2456         return nullptr;
2457     }
2458 
2459     return AudioRoutingManagerNapi::CreateRoutingManagerWrapper(env);
2460 }
2461 
GetVolumeManager(napi_env env,napi_callback_info info)2462 napi_value AudioManagerNapi::GetVolumeManager(napi_env env, napi_callback_info info)
2463 {
2464     napi_status status;
2465     size_t argCount = 0;
2466 
2467     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
2468     if (status != napi_ok || argCount != 0) {
2469         HiLog::Error(LABEL, "Invalid arguments!");
2470         return nullptr;
2471     }
2472 
2473     return AudioVolumeManagerNapi::CreateVolumeManagerWrapper(env);
2474 }
2475 
GetInterruptManager(napi_env env,napi_callback_info info)2476 napi_value AudioManagerNapi::GetInterruptManager(napi_env env, napi_callback_info info)
2477 {
2478     napi_status status;
2479     size_t argCount = 0;
2480 
2481     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
2482     if (status != napi_ok || argCount != 0) {
2483         HiLog::Error(LABEL, "Invalid arguments!");
2484         return nullptr;
2485     }
2486 
2487     return AudioInterruptManagerNapi::CreateInterruptManagerWrapper(env);
2488 }
2489 
AddPropName(std::string & propName,napi_status & status,napi_env env,napi_value & result)2490 void AudioManagerNapi::AddPropName(std::string& propName, napi_status& status, napi_env env, napi_value& result)
2491 {
2492     for (int i = NONE_DEVICES_FLAG; i < DEVICE_FLAG_MAX; i++) {
2493         switch (i) {
2494             case NONE_DEVICES_FLAG:
2495                 propName = "NONE_DEVICES_FLAG";
2496                 break;
2497             case OUTPUT_DEVICES_FLAG:
2498                 propName = "OUTPUT_DEVICES_FLAG";
2499                 break;
2500             case INPUT_DEVICES_FLAG:
2501                 propName = "INPUT_DEVICES_FLAG";
2502                 break;
2503             case ALL_DEVICES_FLAG:
2504                 propName = "ALL_DEVICES_FLAG";
2505                 break;
2506             case DISTRIBUTED_OUTPUT_DEVICES_FLAG:
2507                 propName = "DISTRIBUTED_OUTPUT_DEVICES_FLAG";
2508                 break;
2509             case DISTRIBUTED_INPUT_DEVICES_FLAG:
2510                 propName = "DISTRIBUTED_INPUT_DEVICES_FLAG";
2511                 break;
2512             case ALL_DISTRIBUTED_DEVICES_FLAG:
2513                 propName = "ALL_DISTRIBUTED_DEVICES_FLAG";
2514                 break;
2515             default:
2516                 continue;
2517         }
2518         status = AddNamedProperty(env, result, propName, i);
2519         if (status != napi_ok) {
2520             HiLog::Error(LABEL, "Failed to add named prop!");
2521             break;
2522         }
2523         propName.clear();
2524     }
2525 }
2526 
Init(napi_env env,napi_value exports)2527 static napi_value Init(napi_env env, napi_value exports)
2528 {
2529     AudioManagerNapi::Init(env, exports);
2530     AudioCapturerNapi::Init(env, exports);
2531     AudioRendererNapi::Init(env, exports);
2532     TonePlayerNapi::Init(env, exports);
2533     AudioParametersNapi::Init(env, exports);
2534     AudioStreamMgrNapi::Init(env, exports);
2535     AudioRoutingManagerNapi::Init(env, exports);
2536     AudioVolumeGroupManagerNapi::Init(env, exports);
2537     AudioVolumeManagerNapi::Init(env, exports);
2538     AudioInterruptManagerNapi::Init(env, exports);
2539 
2540     return exports;
2541 }
2542 
2543 static napi_module g_module = {
2544     .nm_version = 1,
2545     .nm_flags = 0,
2546     .nm_filename = nullptr,
2547     .nm_register_func = Init,
2548     .nm_modname = "multimedia.audio",
2549     .nm_priv = ((void *)0),
2550     .reserved = {0}
2551 };
2552 
RegisterModule(void)2553 extern "C" __attribute__((constructor)) void RegisterModule(void)
2554 {
2555     napi_module_register(&g_module);
2556 }
2557 } // namespace AudioStandard
2558 } // namespace OHOS
2559