• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_volume_group_manager_napi.h"
17 #include "audio_common_napi.h"
18 #include "audio_errors.h"
19 #include "hilog/log.h"
20 #include "audio_log.h"
21 
22 using namespace std;
23 using OHOS::HiviewDFX::HiLog;
24 using OHOS::HiviewDFX::HiLogLabel;
25 
26 namespace OHOS {
27 namespace AudioStandard {
28 static __thread napi_ref g_groupmanagerConstructor = nullptr;
29 int32_t AudioVolumeGroupManagerNapi::isConstructSuccess_ = SUCCESS;
30 #define GET_PARAMS(env, info, num) \
31     size_t argc = num;             \
32     napi_value argv[num] = {0};    \
33     napi_value thisVar = nullptr;  \
34     void *data;                    \
35     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)
36 
37 struct AudioVolumeGroupManagerAsyncContext {
38     napi_env env;
39     napi_async_work work;
40     napi_deferred deferred;
41     napi_ref callbackRef = nullptr;
42     int32_t volType;
43     int32_t volLevel;
44     int32_t deviceType;
45     int32_t ringMode;
46     int32_t scene;
47     int32_t deviceFlag;
48     int32_t intValue;
49     int32_t status = SUCCESS;
50     int32_t groupId;
51     bool isMute;
52     bool isActive;
53     bool isTrue;
54     std::string key;
55     std::string valueStr;
56     int32_t networkId;
57     AudioVolumeGroupManagerNapi *objectInfo;
58 };
59 namespace {
60     const int ARGS_ONE = 1;
61     const int ARGS_TWO = 2;
62     const int ARGS_THREE = 3;
63     const int PARAM0 = 0;
64     const int PARAM1 = 1;
65     const int PARAM2 = 2;
66     constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AudioVolumeGroupManagerNapi"};
67     const std::string RINGERMODE_CALLBACK_NAME = "ringerModeChange";
68 }
69 
GetNativeAudioVolumeType(int32_t volumeType)70 static AudioVolumeType GetNativeAudioVolumeType(int32_t volumeType)
71 {
72     AudioVolumeType result = STREAM_MUSIC;
73 
74     switch (volumeType) {
75         case AudioCommonNapi::RINGTONE:
76             result = STREAM_RING;
77             break;
78         case AudioCommonNapi::MEDIA:
79             result = STREAM_MUSIC;
80             break;
81         case AudioCommonNapi::VOICE_CALL:
82             result = STREAM_VOICE_CALL;
83             break;
84         case AudioCommonNapi::VOICE_ASSISTANT:
85             result = STREAM_VOICE_ASSISTANT;
86             break;
87 
88         default:
89             result = STREAM_MUSIC;
90             HiLog::Error(LABEL, "Unknown volume type, Set it to default MEDIA!");
91             break;
92     }
93     return result;
94 }
95 
GetNativeAudioRingerMode(int32_t ringMode)96 static AudioRingerMode GetNativeAudioRingerMode(int32_t ringMode)
97 {
98     AudioRingerMode result = RINGER_MODE_NORMAL;
99 
100     switch (ringMode) {
101         case AudioVolumeGroupManagerNapi::RINGER_MODE_SILENT:
102             result = RINGER_MODE_SILENT;
103             break;
104         case AudioVolumeGroupManagerNapi::RINGER_MODE_VIBRATE:
105             result = RINGER_MODE_VIBRATE;
106             break;
107         case AudioVolumeGroupManagerNapi::RINGER_MODE_NORMAL:
108             result = RINGER_MODE_NORMAL;
109             break;
110         default:
111             result = RINGER_MODE_NORMAL;
112             HiLog::Error(LABEL, "Unknown ringer mode requested by JS, Set it to default RINGER_MODE_NORMAL!");
113             break;
114     }
115 
116     return result;
117 }
118 
GetJsAudioRingMode(int32_t ringerMode)119 static AudioVolumeGroupManagerNapi::AudioRingMode GetJsAudioRingMode(int32_t ringerMode)
120 {
121     AudioVolumeGroupManagerNapi::AudioRingMode result = AudioVolumeGroupManagerNapi::RINGER_MODE_NORMAL;
122 
123     switch (ringerMode) {
124         case RINGER_MODE_SILENT:
125             result = AudioVolumeGroupManagerNapi::RINGER_MODE_SILENT;
126             break;
127         case RINGER_MODE_VIBRATE:
128             result = AudioVolumeGroupManagerNapi::RINGER_MODE_VIBRATE;
129             break;
130         case RINGER_MODE_NORMAL:
131             result = AudioVolumeGroupManagerNapi::RINGER_MODE_NORMAL;
132             break;
133         default:
134             result = AudioVolumeGroupManagerNapi::RINGER_MODE_NORMAL;
135             HiLog::Error(LABEL, "Unknown ringer mode returned from native, Set it to default RINGER_MODE_NORMAL!");
136             break;
137     }
138 
139     return result;
140 }
CommonCallbackRoutine(napi_env env,AudioVolumeGroupManagerAsyncContext * & asyncContext,const napi_value & valueParam)141 static void CommonCallbackRoutine(napi_env env, AudioVolumeGroupManagerAsyncContext* &asyncContext,
142     const napi_value &valueParam)
143 {
144     napi_value result[ARGS_TWO] = {0};
145     napi_value retVal;
146 
147     if (!asyncContext->status) {
148         napi_get_undefined(env, &result[PARAM0]);
149         result[PARAM1] = valueParam;
150     } else {
151         napi_value message = nullptr;
152         std::string messageValue = AudioCommonNapi::getMessageByCode(asyncContext->status);
153         napi_create_string_utf8(env, messageValue.c_str(), NAPI_AUTO_LENGTH, &message);
154 
155         napi_value code = nullptr;
156         napi_create_string_utf8(env, (std::to_string(asyncContext->status)).c_str(), NAPI_AUTO_LENGTH, &code);
157 
158         napi_create_error(env, code, message, &result[PARAM0]);
159         napi_get_undefined(env, &result[PARAM1]);
160     }
161 
162     if (asyncContext->deferred) {
163         if (!asyncContext->status) {
164             napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]);
165         } else {
166             napi_reject_deferred(env, asyncContext->deferred, result[PARAM0]);
167         }
168     } else {
169         napi_value callback = nullptr;
170         napi_get_reference_value(env, asyncContext->callbackRef, &callback);
171         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
172         napi_delete_reference(env, asyncContext->callbackRef);
173     }
174     napi_delete_async_work(env, asyncContext->work);
175 
176     delete asyncContext;
177     asyncContext = nullptr;
178 }
179 
GetIntValueAsyncCallbackComplete(napi_env env,napi_status status,void * data)180 static void GetIntValueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
181 {
182     auto asyncContext = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
183     napi_value valueParam = nullptr;
184 
185     if (asyncContext != nullptr) {
186         if (!asyncContext->status) {
187             napi_create_int32(env, asyncContext->intValue, &valueParam);
188         }
189         CommonCallbackRoutine(env, asyncContext, valueParam);
190     } else {
191         HiLog::Error(LABEL, "ERROR: AudioVolumeGroupManagerAsyncContext* is Null!");
192     }
193 }
194 
SetFunctionAsyncCallbackComplete(napi_env env,napi_status status,void * data)195 static void SetFunctionAsyncCallbackComplete(napi_env env, napi_status status, void *data)
196 {
197     auto asyncContext = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
198     napi_value valueParam = nullptr;
199 
200     if (asyncContext != nullptr) {
201         if (!asyncContext->status) {
202             napi_get_undefined(env, &valueParam);
203         }
204         CommonCallbackRoutine(env, asyncContext, valueParam);
205     } else {
206         HiLog::Error(LABEL, "ERROR: AudioManagerAsyncContext* is Null!");
207     }
208 }
209 
IsTrueAsyncCallbackComplete(napi_env env,napi_status status,void * data)210 static void IsTrueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
211 {
212     auto asyncContext = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
213     napi_value valueParam = nullptr;
214 
215     if (asyncContext != nullptr) {
216         if (!asyncContext->status) {
217             napi_get_boolean(env, asyncContext->isTrue, &valueParam);
218         }
219         CommonCallbackRoutine(env, asyncContext, valueParam);
220     } else {
221         HiLog::Error(LABEL, "ERROR: AudioManagerAsyncContext* is Null!");
222     }
223 }
224 
225 // Constructor callback
Construct(napi_env env,napi_callback_info info)226 napi_value AudioVolumeGroupManagerNapi::Construct(napi_env env, napi_callback_info info)
227 {
228     napi_status status;
229     napi_value jsThis;
230     napi_value undefinedResult = nullptr;
231     napi_get_undefined(env, &undefinedResult);
232     size_t argCount = 1;
233     int32_t groupId = 0;
234 
235     napi_value args[1] = { nullptr};
236     status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
237     napi_get_value_int32(env, args[0], &groupId);
238     HiLog::Info(LABEL, "Construct() %{public}d", groupId);
239 
240     if (status == napi_ok) {
241         unique_ptr<AudioVolumeGroupManagerNapi> groupmanagerNapi = make_unique<AudioVolumeGroupManagerNapi>();
242         if (groupmanagerNapi != nullptr) {
243             groupmanagerNapi->audioGroupMngr_ = AudioSystemManager::GetInstance()->GetGroupManager(groupId);
244             if (groupmanagerNapi->audioGroupMngr_ == nullptr) {
245                 HiLog::Error(LABEL, "Failed in AudioVolumeGroupManagerNapi::Construct()!");
246                 AudioVolumeGroupManagerNapi::isConstructSuccess_ = NAPI_ERR_SYSTEM;
247             }
248             groupmanagerNapi->cachedClientId_ = getpid();
249             status = napi_wrap(env, jsThis, static_cast<void*>(groupmanagerNapi.get()),
250                 AudioVolumeGroupManagerNapi::Destructor, nullptr, nullptr);
251             if (status == napi_ok) {
252                 groupmanagerNapi.release();
253                 return jsThis;
254             }
255         }
256     }
257 
258     HiLog::Error(LABEL, "Failed in AudioVolumeGroupManagerNapi::Construct()!");
259 
260     return undefinedResult;
261 }
262 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)263 void AudioVolumeGroupManagerNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
264 {
265     if (nativeObject != nullptr) {
266         auto obj = static_cast<AudioVolumeGroupManagerNapi*>(nativeObject);
267         delete obj;
268         obj = nullptr;
269         AUDIO_DEBUG_LOG("AudioVolumeGroupManagerNapi::Destructor delete AudioVolumeGroupManagerNapi obj done");
270     }
271 }
272 
CreateAudioVolumeGroupManagerWrapper(napi_env env,int32_t groupId)273 napi_value AudioVolumeGroupManagerNapi::CreateAudioVolumeGroupManagerWrapper(napi_env env, int32_t groupId)
274 {
275     napi_status status;
276     napi_value result = nullptr;
277     napi_value constructor;
278     napi_value groupId_;
279     napi_create_int64(env, groupId, &groupId_);
280     napi_value args[PARAM1] = {groupId_};
281     status = napi_get_reference_value(env, g_groupmanagerConstructor, &constructor);
282     if (status == napi_ok) {
283         status = napi_new_instance(env, constructor, PARAM1, args, &result);
284         if (status == napi_ok) {
285             return result;
286         }
287     }
288 
289     HiLog::Error(LABEL, "Failed in AudioVolumeGroupManagerNapi::CreateaudioMngrWrapper!");
290     napi_get_undefined(env, &result);
291 
292     return result;
293 }
294 
GetVolume(napi_env env,napi_callback_info info)295 napi_value AudioVolumeGroupManagerNapi::GetVolume(napi_env env, napi_callback_info info)
296 {
297     napi_status status;
298     const int32_t refCount = 1;
299     napi_value result = nullptr;
300 
301     GET_PARAMS(env, info, ARGS_TWO);
302 
303     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
304 
305     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
306     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
307         if (argc < ARGS_ONE) {
308             asyncContext->status = NAPI_ERR_INVALID_PARAM;
309         }
310         for (size_t i = PARAM0; i < argc; i++) {
311             napi_valuetype valueType = napi_undefined;
312             napi_typeof(env, argv[i], &valueType);
313 
314             if (i == PARAM0 && valueType == napi_number) {
315                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
316                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
317                     asyncContext->status = (asyncContext->status ==
318                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
319                 }
320             } else if (i == PARAM1) {
321                 if (valueType == napi_function) {
322                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
323                 }
324                 break;
325             } else {
326                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
327             }
328         }
329 
330         if (asyncContext->callbackRef == nullptr) {
331             napi_create_promise(env, &asyncContext->deferred, &result);
332         } else {
333             napi_get_undefined(env, &result);
334         }
335 
336         napi_value resource = nullptr;
337         napi_create_string_utf8(env, "GetVolume", NAPI_AUTO_LENGTH, &resource);
338 
339         status = napi_create_async_work(
340             env, nullptr, resource,
341             [](napi_env env, void *data) {
342                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
343                 if (context->status == SUCCESS) {
344                     context->volLevel = context->objectInfo->audioGroupMngr_->GetVolume(
345                         GetNativeAudioVolumeType(context->volType));
346                     context->intValue = context->volLevel;
347                     context->status = 0;
348                 }
349             }, GetIntValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
350         if (status != napi_ok) {
351             result = nullptr;
352         } else {
353             status = napi_queue_async_work(env, asyncContext->work);
354             if (status == napi_ok) {
355                 asyncContext.release();
356             } else {
357                 result = nullptr;
358             }
359         }
360     }
361 
362     return result;
363 }
364 
SetVolume(napi_env env,napi_callback_info info)365 napi_value AudioVolumeGroupManagerNapi::SetVolume(napi_env env, napi_callback_info info)
366 {
367     napi_status status;
368     const int32_t refCount = 1;
369     napi_value result = nullptr;
370 
371     GET_PARAMS(env, info, ARGS_THREE);
372 
373     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
374 
375     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
376     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
377         if (argc < ARGS_TWO) {
378             asyncContext->status = NAPI_ERR_INVALID_PARAM;
379         }
380         for (size_t i = PARAM0; i < argc; i++) {
381             napi_valuetype valueType = napi_undefined;
382             napi_typeof(env, argv[i], &valueType);
383 
384             if (i == PARAM0 && valueType == napi_number) {
385                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
386                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
387                     asyncContext->status = (asyncContext->status ==
388                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
389                 }
390             } else if (i == PARAM1 && valueType == napi_number) {
391                 napi_get_value_int32(env, argv[i], &asyncContext->volLevel);
392                 if (!AudioCommonNapi::IsLegalInputArgumentVolLevel(asyncContext->volLevel)) {
393                     asyncContext->status = (asyncContext->status ==
394                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
395                 }
396             } else if (i == PARAM2) {
397                 if (valueType == napi_function) {
398                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
399                 }
400                 break;
401             } else {
402                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
403             }
404         }
405 
406         if (asyncContext->callbackRef == nullptr) {
407             napi_create_promise(env, &asyncContext->deferred, &result);
408         } else {
409             napi_get_undefined(env, &result);
410         }
411 
412         napi_value resource = nullptr;
413         napi_create_string_utf8(env, "SetVolume", NAPI_AUTO_LENGTH, &resource);
414 
415         status = napi_create_async_work(
416             env, nullptr, resource,
417             [](napi_env env, void *data) {
418                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
419                 if (context->status == SUCCESS) {
420                     context->status = context->objectInfo->audioGroupMngr_->SetVolume(GetNativeAudioVolumeType(
421                         context->volType), context->volLevel);
422                 }
423             }, SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
424         if (status != napi_ok) {
425             result = nullptr;
426         } else {
427             status = napi_queue_async_work(env, asyncContext->work);
428             if (status == napi_ok) {
429                 asyncContext.release();
430             } else {
431                 result = nullptr;
432             }
433         }
434     }
435 
436     return result;
437 }
438 
GetMaxVolume(napi_env env,napi_callback_info info)439 napi_value AudioVolumeGroupManagerNapi::GetMaxVolume(napi_env env, napi_callback_info info)
440 {
441     napi_status status;
442     const int32_t refCount = 1;
443     napi_value result = nullptr;
444 
445     GET_PARAMS(env, info, ARGS_TWO);
446 
447     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
448     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
449     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
450         if (argc < ARGS_ONE) {
451             asyncContext->status = NAPI_ERR_INVALID_PARAM;
452         }
453         for (size_t i = PARAM0; i < argc; i++) {
454             napi_valuetype valueType = napi_undefined;
455             napi_typeof(env, argv[i], &valueType);
456 
457             if (i == PARAM0 && valueType == napi_number) {
458                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
459                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
460                     asyncContext->status = (asyncContext->status ==
461                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
462                 }
463             } else if (i == PARAM1) {
464                 if (valueType == napi_function) {
465                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
466                 }
467                 break;
468             } else {
469                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
470             }
471         }
472 
473         if (asyncContext->callbackRef == nullptr) {
474             napi_create_promise(env, &asyncContext->deferred, &result);
475         } else {
476             napi_get_undefined(env, &result);
477         }
478 
479         napi_value resource = nullptr;
480         napi_create_string_utf8(env, "GetMaxVolume", NAPI_AUTO_LENGTH, &resource);
481 
482         status = napi_create_async_work(
483             env, nullptr, resource,
484             [](napi_env env, void *data) {
485                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
486                 if (context->status == SUCCESS) {
487                     context->volLevel = context->objectInfo->audioGroupMngr_->GetMaxVolume(
488                         GetNativeAudioVolumeType(context->volType));
489                     context->intValue = context->volLevel;
490                     context->status = 0;
491                 }
492             },
493             GetIntValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
494         if (status != napi_ok) {
495             result = nullptr;
496         } else {
497             status = napi_queue_async_work(env, asyncContext->work);
498             if (status == napi_ok) {
499                 asyncContext.release();
500             } else {
501                 result = nullptr;
502             }
503         }
504     }
505 
506     return result;
507 }
508 
GetMinVolume(napi_env env,napi_callback_info info)509 napi_value AudioVolumeGroupManagerNapi::GetMinVolume(napi_env env, napi_callback_info info)
510 {
511     napi_status status;
512     const int32_t refCount = 1;
513     napi_value result = nullptr;
514 
515     GET_PARAMS(env, info, ARGS_TWO);
516 
517     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
518     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
519     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
520         if (argc < ARGS_ONE) {
521             asyncContext->status = NAPI_ERR_INVALID_PARAM;
522         }
523         for (size_t i = PARAM0; i < argc; i++) {
524             napi_valuetype valueType = napi_undefined;
525             napi_typeof(env, argv[i], &valueType);
526 
527             if (i == PARAM0 && valueType == napi_number) {
528                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
529                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
530                     asyncContext->status = (asyncContext->status ==
531                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
532                 }
533             } else if (i == PARAM1) {
534                 if (valueType == napi_function) {
535                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
536                 }
537                 break;
538             } else {
539                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
540             }
541         }
542 
543         if (asyncContext->callbackRef == nullptr) {
544             napi_create_promise(env, &asyncContext->deferred, &result);
545         } else {
546             napi_get_undefined(env, &result);
547         }
548 
549         napi_value resource = nullptr;
550         napi_create_string_utf8(env, "GetMinVolume", NAPI_AUTO_LENGTH, &resource);
551 
552         status = napi_create_async_work(
553             env, nullptr, resource,
554             [](napi_env env, void *data) {
555                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
556                 if (context->status == SUCCESS) {
557                     context->volLevel = context->objectInfo->audioGroupMngr_->GetMinVolume(
558                         GetNativeAudioVolumeType(context->volType));
559                     context->intValue = context->volLevel;
560                     context->status = 0;
561                 }
562             },
563             GetIntValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
564         if (status != napi_ok) {
565             result = nullptr;
566         } else {
567             status = napi_queue_async_work(env, asyncContext->work);
568             if (status == napi_ok) {
569                 asyncContext.release();
570             } else {
571                 result = nullptr;
572             }
573         }
574     }
575 
576     return result;
577 }
578 
SetMute(napi_env env,napi_callback_info info)579 napi_value AudioVolumeGroupManagerNapi::SetMute(napi_env env, napi_callback_info info)
580 {
581     napi_status status;
582     const int32_t refCount = 1;
583     napi_value result = nullptr;
584 
585     GET_PARAMS(env, info, ARGS_THREE);
586 
587     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
588     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
589     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
590         if (argc < ARGS_ONE) {
591             asyncContext->status = NAPI_ERR_INVALID_PARAM;
592         }
593         for (size_t i = PARAM0; i < argc; i++) {
594             napi_valuetype valueType = napi_undefined;
595             napi_typeof(env, argv[i], &valueType);
596 
597             if (i == PARAM0 && valueType == napi_number) {
598                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
599                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
600                     asyncContext->status = (asyncContext->status ==
601                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
602                 }
603             } else if (i == PARAM1 && valueType == napi_boolean) {
604                 napi_get_value_bool(env, argv[i], &asyncContext->isMute);
605             } else if (i == PARAM2) {
606                 if (valueType == napi_function) {
607                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
608                 }
609                 break;
610             } else {
611                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
612             }
613         }
614 
615         if (asyncContext->callbackRef == nullptr) {
616             napi_create_promise(env, &asyncContext->deferred, &result);
617         } else {
618             napi_get_undefined(env, &result);
619         }
620 
621         napi_value resource = nullptr;
622         napi_create_string_utf8(env, "SetStreamMute", NAPI_AUTO_LENGTH, &resource);
623 
624         status = napi_create_async_work(
625             env, nullptr, resource,
626             [](napi_env env, void *data) {
627                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
628                 if (context->status == SUCCESS) {
629                     context->status = context->objectInfo->audioGroupMngr_->SetMute(GetNativeAudioVolumeType(
630                         context->volType), context->isMute);
631                 }
632             },
633             SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
634         if (status != napi_ok) {
635             result = nullptr;
636         } else {
637             status = napi_queue_async_work(env, asyncContext->work);
638             if (status == napi_ok) {
639                 asyncContext.release();
640             } else {
641                 result = nullptr;
642             }
643         }
644     }
645 
646     return result;
647 }
648 
IsStreamMute(napi_env env,napi_callback_info info)649 napi_value AudioVolumeGroupManagerNapi::IsStreamMute(napi_env env, napi_callback_info info)
650 {
651     napi_status status;
652     const int32_t refCount = 1;
653     napi_value result = nullptr;
654 
655     GET_PARAMS(env, info, ARGS_TWO);
656 
657     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
658 
659     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
660     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
661         if (argc < ARGS_ONE) {
662             asyncContext->status = NAPI_ERR_INVALID_PARAM;
663         }
664         for (size_t i = PARAM0; i < argc; i++) {
665             napi_valuetype valueType = napi_undefined;
666             napi_typeof(env, argv[i], &valueType);
667 
668             if (i == PARAM0 && valueType == napi_number) {
669                 napi_get_value_int32(env, argv[i], &asyncContext->volType);
670                 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
671                     asyncContext->status = (asyncContext->status ==
672                         NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
673                 }
674             } else if (i == PARAM1) {
675                 if (valueType == napi_function) {
676                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
677                 }
678                 break;
679             } else {
680                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
681             }
682         }
683 
684         if (asyncContext->callbackRef == nullptr) {
685             napi_create_promise(env, &asyncContext->deferred, &result);
686         } else {
687             napi_get_undefined(env, &result);
688         }
689 
690         napi_value resource = nullptr;
691         napi_create_string_utf8(env, "IsStreamMute", NAPI_AUTO_LENGTH, &resource);
692 
693         status = napi_create_async_work(
694             env, nullptr, resource,
695             [](napi_env env, void *data) {
696                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
697                 if (context->status == SUCCESS) {
698                     context->isMute =
699                         context->objectInfo->audioGroupMngr_->IsStreamMute(GetNativeAudioVolumeType(context->volType));
700                     context->isTrue = context->isMute;
701                     context->status = 0;
702                 }
703             },
704             IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
705         if (status != napi_ok) {
706             result = nullptr;
707         } else {
708             status = napi_queue_async_work(env, asyncContext->work);
709             if (status == napi_ok) {
710                 asyncContext.release();
711             } else {
712                 result = nullptr;
713             }
714         }
715     }
716 
717     return result;
718 }
719 
SetRingerMode(napi_env env,napi_callback_info info)720 napi_value AudioVolumeGroupManagerNapi::SetRingerMode(napi_env env, napi_callback_info info)
721 {
722     HiLog::Info(LABEL, " %{public}s IN", __func__);
723     napi_status status;
724     const int32_t refCount = 1;
725     napi_value result = nullptr;
726 
727     GET_PARAMS(env, info, ARGS_TWO);
728 
729     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
730 
731     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
732     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
733         if (argc < ARGS_ONE) {
734             asyncContext->status = NAPI_ERR_INVALID_PARAM;
735         }
736         for (size_t i = PARAM0; i < argc; i++) {
737             napi_valuetype valueType = napi_undefined;
738             napi_typeof(env, argv[i], &valueType);
739 
740             if (i == PARAM0 && valueType == napi_number) {
741                 napi_get_value_int32(env, argv[i], &asyncContext->ringMode);
742                 if (!AudioCommonNapi::IsLegalInputArgumentRingMode(asyncContext->ringMode)) {
743                     asyncContext->status = asyncContext->status ==
744                         NAPI_ERR_INVALID_PARAM ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
745                 }
746             } else if (i == PARAM1) {
747                 if (valueType == napi_function) {
748                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
749                 }
750                 break;
751             } else {
752                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
753             }
754         }
755 
756         if (asyncContext->callbackRef == nullptr) {
757             napi_create_promise(env, &asyncContext->deferred, &result);
758         } else {
759             napi_get_undefined(env, &result);
760         }
761 
762         napi_value resource = nullptr;
763         napi_create_string_utf8(env, "SetRingerMode", NAPI_AUTO_LENGTH, &resource);
764 
765         status = napi_create_async_work(
766             env, nullptr, resource,
767             [](napi_env env, void *data) {
768                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
769                 if (context->status == SUCCESS) {
770                     context->status =
771                     context->objectInfo->audioGroupMngr_->SetRingerMode(GetNativeAudioRingerMode(context->ringMode));
772                 }
773             },
774             SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
775         if (status != napi_ok) {
776             result = nullptr;
777         } else {
778             status = napi_queue_async_work(env, asyncContext->work);
779             if (status == napi_ok) {
780                 asyncContext.release();
781             } else {
782                 result = nullptr;
783             }
784         }
785     }
786 
787     return result;
788 }
789 
GetRingerMode(napi_env env,napi_callback_info info)790 napi_value AudioVolumeGroupManagerNapi::GetRingerMode(napi_env env, napi_callback_info info)
791 {
792     HiLog::Info(LABEL, " %{public}s IN", __func__);
793     napi_status status;
794     const int32_t refCount = 1;
795     napi_value result = nullptr;
796 
797     GET_PARAMS(env, info, ARGS_ONE);
798 
799     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
800 
801     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
802     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
803         if (argc > PARAM0) {
804             napi_valuetype valueType = napi_undefined;
805             napi_typeof(env, argv[PARAM0], &valueType);
806             if (valueType == napi_function) {
807                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
808             }
809         }
810 
811         if (asyncContext->callbackRef == nullptr) {
812             napi_create_promise(env, &asyncContext->deferred, &result);
813         } else {
814             napi_get_undefined(env, &result);
815         }
816 
817         napi_value resource = nullptr;
818         napi_create_string_utf8(env, "GetRingerMode", NAPI_AUTO_LENGTH, &resource);
819 
820         status = napi_create_async_work(
821             env, nullptr, resource,
822             [](napi_env env, void *data) {
823                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
824                 if (context->status == SUCCESS) {
825                     context->ringMode = GetJsAudioRingMode(context->objectInfo->audioGroupMngr_->GetRingerMode());
826                     context->intValue = context->ringMode;
827                     context->status = 0;
828                 }
829             },
830             GetIntValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
831         if (status != napi_ok) {
832             result = nullptr;
833         } else {
834             status = napi_queue_async_work(env, asyncContext->work);
835             if (status == napi_ok) {
836                 asyncContext.release();
837             } else {
838                 result = nullptr;
839             }
840         }
841     }
842 
843     return result;
844 }
845 
846 
SetMicrophoneMute(napi_env env,napi_callback_info info)847 napi_value AudioVolumeGroupManagerNapi::SetMicrophoneMute(napi_env env, napi_callback_info info)
848 {
849     napi_status status;
850     const int32_t refCount = 1;
851     napi_value result = nullptr;
852 
853     GET_PARAMS(env, info, ARGS_TWO);
854 
855     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
856 
857     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
858     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
859         if (argc < ARGS_ONE) {
860             asyncContext->status = NAPI_ERR_INVALID_PARAM;
861         }
862         for (size_t i = PARAM0; i < argc; i++) {
863             napi_valuetype valueType = napi_undefined;
864             napi_typeof(env, argv[i], &valueType);
865 
866             if (i == PARAM0 && valueType == napi_boolean) {
867                 napi_get_value_bool(env, argv[i], &asyncContext->isMute);
868             } else if (i == PARAM1) {
869                 if (valueType == napi_function) {
870                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
871                 }
872                 break;
873             } else {
874                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
875             }
876         }
877 
878         if (asyncContext->callbackRef == nullptr) {
879             napi_create_promise(env, &asyncContext->deferred, &result);
880         } else {
881             napi_get_undefined(env, &result);
882         }
883 
884         napi_value resource = nullptr;
885         napi_create_string_utf8(env, "SetMicrophoneMute", NAPI_AUTO_LENGTH, &resource);
886 
887         status = napi_create_async_work(
888             env, nullptr, resource,
889             [](napi_env env, void *data) {
890                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
891                 if (context->status == SUCCESS) {
892                     context->status = context->objectInfo->audioGroupMngr_->SetMicrophoneMute(context->isMute);
893                 }
894             },
895             SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
896         if (status != napi_ok) {
897             result = nullptr;
898         } else {
899             status = napi_queue_async_work(env, asyncContext->work);
900             if (status == napi_ok) {
901                 asyncContext.release();
902             } else {
903                 result = nullptr;
904             }
905         }
906     }
907 
908     return result;
909 }
910 
IsMicrophoneMute(napi_env env,napi_callback_info info)911 napi_value AudioVolumeGroupManagerNapi::IsMicrophoneMute(napi_env env, napi_callback_info info)
912 {
913     napi_status status;
914     const int32_t refCount = 1;
915     napi_value result = nullptr;
916 
917     GET_PARAMS(env, info, ARGS_ONE);
918 
919     unique_ptr<AudioVolumeGroupManagerAsyncContext> asyncContext = make_unique<AudioVolumeGroupManagerAsyncContext>();
920 
921     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
922     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
923         if (argc > PARAM0) {
924             napi_valuetype valueType = napi_undefined;
925             napi_typeof(env, argv[PARAM0], &valueType);
926             if (valueType == napi_function) {
927                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
928             }
929         }
930 
931         if (asyncContext->callbackRef == nullptr) {
932             napi_create_promise(env, &asyncContext->deferred, &result);
933         } else {
934             napi_get_undefined(env, &result);
935         }
936 
937         napi_value resource = nullptr;
938         napi_create_string_utf8(env, "IsMicrophoneMute", NAPI_AUTO_LENGTH, &resource);
939 
940         status = napi_create_async_work(
941             env, nullptr, resource,
942             [](napi_env env, void *data) {
943                 auto context = static_cast<AudioVolumeGroupManagerAsyncContext*>(data);
944                 if (context->status == SUCCESS) {
945                     context->isMute = context->objectInfo->audioGroupMngr_->IsMicrophoneMute();
946                     context->isTrue = context->isMute;
947                 }
948             },
949             IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
950         if (status != napi_ok) {
951             result = nullptr;
952         } else {
953             status = napi_queue_async_work(env, asyncContext->work);
954             if (status == napi_ok) {
955                 asyncContext.release();
956             } else {
957                 result = nullptr;
958             }
959         }
960     }
961 
962     return result;
963 }
964 
On(napi_env env,napi_callback_info info)965 napi_value AudioVolumeGroupManagerNapi::On(napi_env env, napi_callback_info info)
966 {
967     napi_value undefinedResult = nullptr;
968     napi_get_undefined(env, &undefinedResult);
969 
970     const size_t minArgCount = 2;
971     size_t argCount = 3;
972     napi_value args[minArgCount + 1] = {nullptr, nullptr, nullptr};
973     napi_value jsThis = nullptr;
974     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
975     if (status != napi_ok || argCount < minArgCount) {
976         AUDIO_ERR_LOG("On fail to napi_get_cb_info/Requires min 2 parameters");
977         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
978     }
979 
980     napi_valuetype eventType = napi_undefined;
981     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
982         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
983         return undefinedResult;
984     }
985     std::string callbackName = AudioCommonNapi::GetStringArgument(env, args[0]);
986     AUDIO_INFO_LOG("AudioVolumeGroupManagerNapi::On callbackName: %{public}s", callbackName.c_str());
987 
988     AudioVolumeGroupManagerNapi *volumeGroupManagerNapi = nullptr;
989     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&volumeGroupManagerNapi));
990 
991     napi_valuetype handler = napi_undefined;
992     if (napi_typeof(env, args[PARAM1], &handler) != napi_ok || handler != napi_function) {
993         AUDIO_ERR_LOG("AudioVolumeGroupManagerNapi::On type mismatch for parameter 2");
994         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
995         return undefinedResult;
996     }
997 
998     if (!callbackName.compare(RINGERMODE_CALLBACK_NAME)) {
999         if (volumeGroupManagerNapi->ringerModecallbackNapi_ == nullptr) {
1000             volumeGroupManagerNapi->ringerModecallbackNapi_ = std::make_shared<AudioRingerModeCallbackNapi>(env);
1001             int32_t ret = volumeGroupManagerNapi->audioGroupMngr_->SetRingerModeCallback(
1002                 volumeGroupManagerNapi->cachedClientId_, volumeGroupManagerNapi->ringerModecallbackNapi_);
1003             if (ret) {
1004                 AUDIO_ERR_LOG("AudioVolumeGroupManagerNapi:: SetRingerModeCallback Failed");
1005                 return undefinedResult;
1006             } else {
1007                 AUDIO_INFO_LOG("AudioVolumeGroupManagerNapi:: SetRingerModeCallback Success");
1008             }
1009         }
1010 
1011         std::shared_ptr<AudioRingerModeCallbackNapi> cb =
1012             std::static_pointer_cast<AudioRingerModeCallbackNapi>(volumeGroupManagerNapi->ringerModecallbackNapi_);
1013         cb->SaveCallbackReference(callbackName, args[PARAM1]);
1014     } else if (!callbackName.compare(MIC_STATE_CHANGE_CALLBACK_NAME)) {
1015         if (!volumeGroupManagerNapi->micStateChangeCallbackNapi_) {
1016             volumeGroupManagerNapi->micStateChangeCallbackNapi_=
1017                 std::make_shared<AudioManagerMicStateChangeCallbackNapi>(env);
1018             if (!volumeGroupManagerNapi->micStateChangeCallbackNapi_) {
1019                 AUDIO_ERR_LOG("AudioVolumeGroupManagerNapi:: Memory Allocation Failed !!");
1020             }
1021 
1022             int32_t ret = volumeGroupManagerNapi->audioGroupMngr_->SetMicStateChangeCallback(
1023                 volumeGroupManagerNapi->micStateChangeCallbackNapi_);
1024             if (ret) {
1025                 AUDIO_ERR_LOG("AudioVolumeGroupManagerNapi:: Registering Microphone Change Callback Failed");
1026             }
1027         }
1028 
1029         std::shared_ptr<AudioManagerMicStateChangeCallbackNapi> cb =
1030             std::static_pointer_cast<AudioManagerMicStateChangeCallbackNapi>(volumeGroupManagerNapi->
1031                 micStateChangeCallbackNapi_);
1032         cb->SaveCallbackReference(callbackName, args[PARAM1]);
1033 
1034         AUDIO_INFO_LOG("AudioVolumeGroupManagerNapi::On SetMicStateChangeCallback is successful");
1035     } else {
1036         AUDIO_ERR_LOG("AudioVolumeGroupManagerNapi::No such callback supported");
1037         AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
1038     }
1039     return undefinedResult;
1040 }
1041 
Init(napi_env env,napi_value exports)1042 napi_value AudioVolumeGroupManagerNapi::Init(napi_env env, napi_value exports)
1043 {
1044     AUDIO_INFO_LOG("AudioVolumeGroupManagerNapi::Init");
1045     napi_status status;
1046     napi_value constructor;
1047     napi_value result = nullptr;
1048     const int32_t refCount = 1;
1049     napi_get_undefined(env, &result);
1050 
1051     napi_property_descriptor audio_svc_group_mngr_properties[] = {
1052         DECLARE_NAPI_FUNCTION("setVolume", AudioVolumeGroupManagerNapi::SetVolume),
1053         DECLARE_NAPI_FUNCTION("getVolume", AudioVolumeGroupManagerNapi::GetVolume),
1054         DECLARE_NAPI_FUNCTION("getMaxVolume", AudioVolumeGroupManagerNapi::GetMaxVolume),
1055         DECLARE_NAPI_FUNCTION("getMinVolume", AudioVolumeGroupManagerNapi::GetMinVolume),
1056         DECLARE_NAPI_FUNCTION("mute", AudioVolumeGroupManagerNapi::SetMute),
1057         DECLARE_NAPI_FUNCTION("isMute", AudioVolumeGroupManagerNapi::IsStreamMute),
1058         DECLARE_NAPI_FUNCTION("setRingerMode", SetRingerMode),
1059         DECLARE_NAPI_FUNCTION("getRingerMode", GetRingerMode),
1060         DECLARE_NAPI_FUNCTION("setMicrophoneMute", SetMicrophoneMute),
1061         DECLARE_NAPI_FUNCTION("isMicrophoneMute", IsMicrophoneMute),
1062         DECLARE_NAPI_FUNCTION("on", On),
1063 
1064     };
1065 
1066     status = napi_define_class(env, AUDIO_VOLUME_GROUP_MNGR_NAPI_CLASS_NAME.c_str(),
1067         NAPI_AUTO_LENGTH, Construct, nullptr,
1068         sizeof(audio_svc_group_mngr_properties) / sizeof(audio_svc_group_mngr_properties[PARAM0]),
1069         audio_svc_group_mngr_properties, &constructor);
1070     if (status != napi_ok) {
1071         return result;
1072     }
1073     status = napi_create_reference(env, constructor, refCount, &g_groupmanagerConstructor);
1074     if (status == napi_ok) {
1075         status = napi_set_named_property(env, exports, AUDIO_VOLUME_GROUP_MNGR_NAPI_CLASS_NAME.c_str(), constructor);
1076         if (status == napi_ok) {
1077             return exports;
1078         }
1079     }
1080 
1081     HiLog::Error(LABEL, "Failure in AudioVolumeGroupManagerNapi::Init()");
1082     return result;
1083 }
1084 } // namespace AudioStandard
1085 } // namespace OHOS
1086