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