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