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_routing_manager_napi.h"
17
18 #include "audio_common_napi.h"
19 #include "audio_micstatechange_callback_napi.h"
20 #include "audio_errors.h"
21 #include "audio_log.h"
22 #include "hilog/log.h"
23 #include "napi_base_context.h"
24
25 using namespace std;
26 using OHOS::HiviewDFX::HiLog;
27 using OHOS::HiviewDFX::HiLogLabel;
28
29 namespace OHOS {
30 namespace AudioStandard {
31 static __thread napi_ref g_routingManagerConstructor = nullptr;
32
33 namespace {
34 const int ARGS_ONE = 1;
35 const int ARGS_TWO = 2;
36 const int ARGS_THREE = 3;
37 const int SIZE = 100;
38 const int PARAM0 = 0;
39 const int PARAM1 = 1;
40 const int PARAM2 = 2;
41 const int PARAM3 = 3;
42
43 constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AudioRoutingManagerNapi"};
44 }
45
46 struct AudioRoutingManagerAsyncContext {
47 napi_env env;
48 napi_async_work work;
49 napi_deferred deferred;
50 napi_ref callbackRef = nullptr;
51 int32_t deviceFlag;
52 int32_t status = SUCCESS;
53 int32_t deviceType;
54 bool isActive;
55 bool isTrue;
56 bool bArgTransFlag = true;
57 AudioRoutingManagerNapi *objectInfo;
58 sptr<AudioRendererFilter> audioRendererFilter;
59 sptr<AudioCapturerFilter> audioCapturerFilter;
60 vector<sptr<AudioDeviceDescriptor>> deviceDescriptors;
61 vector<sptr<AudioDeviceDescriptor>> outDeviceDescriptors;
62 };
63
AudioRoutingManagerNapi()64 AudioRoutingManagerNapi::AudioRoutingManagerNapi()
65 : audioMngr_(nullptr), env_(nullptr) {}
66
67 AudioRoutingManagerNapi::~AudioRoutingManagerNapi() = default;
68
Destructor(napi_env env,void * nativeObject,void * finalize_hint)69 void AudioRoutingManagerNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
70 {
71 if (nativeObject != nullptr) {
72 auto obj = static_cast<AudioRoutingManagerNapi *>(nativeObject);
73 delete obj;
74 obj = nullptr;
75 }
76 }
77
Init(napi_env env,napi_value exports)78 napi_value AudioRoutingManagerNapi::Init(napi_env env, napi_value exports)
79 {
80 AUDIO_INFO_LOG("AudioRoutingManagerNapi::Init");
81 napi_status status;
82 napi_value constructor;
83 napi_value result = nullptr;
84 const int32_t refCount = 1;
85 napi_get_undefined(env, &result);
86
87 napi_property_descriptor audio_routing_manager_properties[] = {
88 DECLARE_NAPI_FUNCTION("getDevices", GetDevices),
89 DECLARE_NAPI_FUNCTION("on", AudioRoutingManagerNapi::On),
90 DECLARE_NAPI_FUNCTION("off", AudioRoutingManagerNapi::Off),
91 DECLARE_NAPI_FUNCTION("selectOutputDevice", SelectOutputDevice),
92 DECLARE_NAPI_FUNCTION("selectOutputDeviceByFilter", SelectOutputDeviceByFilter),
93 DECLARE_NAPI_FUNCTION("selectInputDevice", SelectInputDevice),
94 DECLARE_NAPI_FUNCTION("selectInputDeviceByFilter", SelectInputDeviceByFilter),
95 DECLARE_NAPI_FUNCTION("setCommunicationDevice", SetCommunicationDevice),
96 DECLARE_NAPI_FUNCTION("isCommunicationDeviceActive", IsCommunicationDeviceActive),
97 DECLARE_NAPI_FUNCTION("getActiveOutputDeviceDescriptors", GetActiveOutputDeviceDescriptors),
98 };
99
100 status = napi_define_class(env, AUDIO_ROUTING_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct, nullptr,
101 sizeof(audio_routing_manager_properties) / sizeof(audio_routing_manager_properties[PARAM0]),
102 audio_routing_manager_properties, &constructor);
103 if (status != napi_ok) {
104 return result;
105 }
106 status = napi_create_reference(env, constructor, refCount, &g_routingManagerConstructor);
107 if (status == napi_ok) {
108 status = napi_set_named_property(env, exports, AUDIO_ROUTING_MANAGER_NAPI_CLASS_NAME.c_str(), constructor);
109 if (status == napi_ok) {
110 return exports;
111 }
112 }
113
114 HiLog::Error(LABEL, "Failure in AudioRoutingManagerNapi::Init()");
115 return result;
116 }
117
CreateRoutingManagerWrapper(napi_env env)118 napi_value AudioRoutingManagerNapi::CreateRoutingManagerWrapper(napi_env env)
119 {
120 napi_status status;
121 napi_value result = nullptr;
122 napi_value constructor;
123
124 status = napi_get_reference_value(env, g_routingManagerConstructor, &constructor);
125 if (status == napi_ok) {
126 status = napi_new_instance(env, constructor, 0, nullptr, &result);
127 if (status == napi_ok) {
128 return result;
129 }
130 }
131 HiLog::Error(LABEL, "Failed in AudioRoutingManagerNapi::CreateRoutingManagerWrapper!");
132 napi_get_undefined(env, &result);
133
134 return result;
135 }
136
Construct(napi_env env,napi_callback_info info)137 napi_value AudioRoutingManagerNapi::Construct(napi_env env, napi_callback_info info)
138 {
139 AUDIO_INFO_LOG("AudioRoutingManagerNapi::Construct");
140 napi_status status;
141 napi_value result = nullptr;
142 napi_get_undefined(env, &result);
143
144 size_t argc = ARGS_TWO;
145 napi_value argv[ARGS_TWO] = {0};
146 napi_value thisVar = nullptr;
147 void *data = nullptr;
148 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
149 unique_ptr<AudioRoutingManagerNapi> audioRoutingManagerNapi = make_unique<AudioRoutingManagerNapi>();
150 CHECK_AND_RETURN_RET_LOG(audioRoutingManagerNapi != nullptr, result, "No memory");
151
152 audioRoutingManagerNapi->audioMngr_ = AudioSystemManager::GetInstance();
153
154 audioRoutingManagerNapi->audioRoutingMngr_ = AudioRoutingManager::GetInstance();
155
156 audioRoutingManagerNapi->env_ = env;
157
158 status = napi_wrap(env, thisVar, static_cast<void*>(audioRoutingManagerNapi.get()),
159 AudioRoutingManagerNapi::Destructor, nullptr, nullptr);
160 if (status == napi_ok) {
161 audioRoutingManagerNapi.release();
162 return thisVar;
163 }
164
165 HiLog::Error(LABEL, "Failed in AudioRoutingManager::Construct()!");
166 return result;
167 }
168
CommonCallbackRoutine(napi_env env,AudioRoutingManagerAsyncContext * & asyncContext,const napi_value & valueParam)169 static void CommonCallbackRoutine(napi_env env, AudioRoutingManagerAsyncContext *&asyncContext,
170 const napi_value &valueParam)
171 {
172 napi_value result[ARGS_TWO] = {0};
173 napi_value retVal;
174
175 if (!asyncContext->status) {
176 napi_get_undefined(env, &result[PARAM0]);
177 result[PARAM1] = valueParam;
178 } else {
179 napi_value message = nullptr;
180 std::string messageValue = AudioCommonNapi::getMessageByCode(asyncContext->status);
181 napi_create_string_utf8(env, messageValue.c_str(), NAPI_AUTO_LENGTH, &message);
182
183 napi_value code = nullptr;
184 napi_create_string_utf8(env, (std::to_string(asyncContext->status)).c_str(), NAPI_AUTO_LENGTH, &code);
185
186 napi_create_error(env, code, message, &result[PARAM0]);
187 napi_get_undefined(env, &result[PARAM1]);
188 }
189
190 if (asyncContext->deferred) {
191 if (!asyncContext->status) {
192 napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]);
193 } else {
194 napi_reject_deferred(env, asyncContext->deferred, result[PARAM0]);
195 }
196 } else {
197 napi_value callback = nullptr;
198 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
199 napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
200 napi_delete_reference(env, asyncContext->callbackRef);
201 }
202 napi_delete_async_work(env, asyncContext->work);
203
204 delete asyncContext;
205 asyncContext = nullptr;
206 }
207
SetFunctionAsyncCallbackComplete(napi_env env,napi_status status,void * data)208 static void SetFunctionAsyncCallbackComplete(napi_env env, napi_status status, void *data)
209 {
210 auto asyncContext = static_cast<AudioRoutingManagerAsyncContext*>(data);
211 napi_value valueParam = nullptr;
212
213 if (asyncContext != nullptr) {
214 if (!asyncContext->status) {
215 napi_get_undefined(env, &valueParam);
216 }
217 CommonCallbackRoutine(env, asyncContext, valueParam);
218 } else {
219 HiLog::Error(LABEL, "ERROR: AudioManagerAsyncContext* is Null!");
220 }
221 }
222
IsTrueAsyncCallbackComplete(napi_env env,napi_status status,void * data)223 static void IsTrueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
224 {
225 auto asyncContext = static_cast<AudioRoutingManagerAsyncContext*>(data);
226 napi_value valueParam = nullptr;
227
228 if (asyncContext != nullptr) {
229 if (!asyncContext->status) {
230 napi_get_boolean(env, asyncContext->isTrue, &valueParam);
231 }
232 CommonCallbackRoutine(env, asyncContext, valueParam);
233 } else {
234 HiLog::Error(LABEL, "ERROR: AudioManagerAsyncContext* is Null!");
235 }
236 }
237
ParseAudioRendererInfo(napi_env env,napi_value root,AudioRendererInfo * rendererInfo)238 static void ParseAudioRendererInfo(napi_env env, napi_value root, AudioRendererInfo *rendererInfo)
239 {
240 napi_value tempValue = nullptr;
241 int32_t intValue = {0};
242
243 if (napi_get_named_property(env, root, "contentType", &tempValue) == napi_ok) {
244 napi_get_value_int32(env, tempValue, &intValue);
245 rendererInfo->contentType = static_cast<ContentType>(intValue);
246 }
247
248 if (napi_get_named_property(env, root, "streamUsage", &tempValue) == napi_ok) {
249 napi_get_value_int32(env, tempValue, &intValue);
250 rendererInfo->streamUsage = static_cast<StreamUsage>(intValue);
251 }
252
253 if (napi_get_named_property(env, root, "rendererFlags", &tempValue) == napi_ok) {
254 napi_get_value_int32(env, tempValue, &(rendererInfo->rendererFlags));
255 }
256 }
257
258
ParseAudioRendererFilter(napi_env env,napi_value root,sptr<AudioRendererFilter> & audioRendererFilter,bool & argTransFlag)259 static void ParseAudioRendererFilter(napi_env env, napi_value root,
260 sptr<AudioRendererFilter> &audioRendererFilter, bool &argTransFlag)
261 {
262 napi_value tempValue = nullptr;
263 int32_t intValue = {0};
264 argTransFlag = true;
265 bool hasUid = true;
266 napi_has_named_property(env, root, "uid", &hasUid);
267
268 if (!hasUid) {
269 argTransFlag = false;
270 return;
271 }
272 audioRendererFilter = new(std::nothrow) AudioRendererFilter();
273
274 if (napi_get_named_property(env, root, "uid", &tempValue) == napi_ok) {
275 napi_get_value_int32(env, tempValue, &intValue);
276 audioRendererFilter->uid = intValue;
277 }
278
279 if (napi_get_named_property(env, root, "rendererInfo", &tempValue) == napi_ok) {
280 ParseAudioRendererInfo(env, tempValue, &(audioRendererFilter->rendererInfo));
281 }
282
283 if (napi_get_named_property(env, root, "rendererId", &tempValue) == napi_ok) {
284 napi_get_value_int32(env, tempValue, &intValue);
285 audioRendererFilter->streamId = intValue;
286 }
287 }
288
ParseAudioDeviceDescriptor(napi_env env,napi_value root,sptr<AudioDeviceDescriptor> & selectedAudioDevice,bool & argTransFlag)289 static void ParseAudioDeviceDescriptor(napi_env env, napi_value root,
290 sptr<AudioDeviceDescriptor> &selectedAudioDevice, bool &argTransFlag)
291 {
292 napi_value tempValue = nullptr;
293 int32_t intValue = {0};
294 char buffer[SIZE];
295 size_t res = 0;
296 argTransFlag = true;
297 bool hasDeviceRole = true;
298 bool hasNetworkId = true;
299 napi_has_named_property(env, root, "deviceRole", &hasDeviceRole);
300 napi_has_named_property(env, root, "networkId", &hasNetworkId);
301
302 if ((!hasDeviceRole) || (!hasNetworkId)) {
303 argTransFlag = false;
304 return;
305 }
306
307 if (napi_get_named_property(env, root, "deviceRole", &tempValue) == napi_ok) {
308 napi_get_value_int32(env, tempValue, &intValue);
309 selectedAudioDevice->deviceRole_ = static_cast<DeviceRole>(intValue);
310 }
311
312 if (napi_get_named_property(env, root, "deviceType", &tempValue) == napi_ok) {
313 napi_get_value_int32(env, tempValue, &intValue);
314 selectedAudioDevice->deviceType_ = static_cast<DeviceType>(intValue);
315 }
316
317 if (napi_get_named_property(env, root, "networkId", &tempValue) == napi_ok) {
318 napi_get_value_string_utf8(env, tempValue, buffer, SIZE, &res);
319 selectedAudioDevice->networkId_ = std::string(buffer);
320 }
321
322 if (napi_get_named_property(env, root, "interruptGroupId", &tempValue) == napi_ok) {
323 napi_get_value_int32(env, tempValue, &intValue);
324 selectedAudioDevice->interruptGroupId_ = intValue;
325 }
326
327 if (napi_get_named_property(env, root, "volumeGroupId", &tempValue) == napi_ok) {
328 napi_get_value_int32(env, tempValue, &intValue);
329 selectedAudioDevice->volumeGroupId_ = intValue;
330 }
331 }
332
ParseAudioDeviceDescriptorVector(napi_env env,napi_value root,vector<sptr<AudioDeviceDescriptor>> & deviceDescriptorsVector,bool & argTransFlag)333 static void ParseAudioDeviceDescriptorVector(napi_env env, napi_value root,
334 vector<sptr<AudioDeviceDescriptor>> &deviceDescriptorsVector, bool &argTransFlag)
335 {
336 uint32_t arrayLen = 0;
337 napi_get_array_length(env, root, &arrayLen);
338 if (arrayLen == 0) {
339 deviceDescriptorsVector = {};
340 AUDIO_INFO_LOG("Error: AudioDeviceDescriptor vector is NULL!");
341 }
342
343 for (size_t i = 0; i < arrayLen; i++) {
344 napi_value element;
345 napi_get_element(env, root, i, &element);
346 sptr<AudioDeviceDescriptor> selectedAudioDevice = new(std::nothrow) AudioDeviceDescriptor();
347 ParseAudioDeviceDescriptor(env, element, selectedAudioDevice, argTransFlag);
348 if (!argTransFlag) {
349 return;
350 }
351 deviceDescriptorsVector.push_back(selectedAudioDevice);
352 }
353 }
354
355
SelectOutputDeviceAsyncCallbackComplete(napi_env env,napi_status status,void * data)356 static void SelectOutputDeviceAsyncCallbackComplete(napi_env env, napi_status status, void *data)
357 {
358 auto asyncContext = static_cast<AudioRoutingManagerAsyncContext*>(data);
359 napi_value valueParam = nullptr;
360
361 if (asyncContext != nullptr) {
362 if (!asyncContext->status) {
363 napi_get_undefined(env, &valueParam);
364 }
365 CommonCallbackRoutine(env, asyncContext, valueParam);
366 } else {
367 HiLog::Error(LABEL, "ERROR: AudioRoutingManagerAsyncContext* is Null!");
368 }
369 }
370
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int intValue,napi_value & result)371 static void SetValueInt32(const napi_env& env, const std::string& fieldStr, const int intValue, napi_value& result)
372 {
373 napi_value value = nullptr;
374 napi_create_int32(env, intValue, &value);
375 napi_set_named_property(env, result, fieldStr.c_str(), value);
376 }
377
SetValueString(const napi_env & env,const std::string & fieldStr,const std::string stringValue,napi_value & result)378 static void SetValueString(const napi_env& env, const std::string& fieldStr, const std::string stringValue,
379 napi_value& result)
380 {
381 napi_value value = nullptr;
382 napi_create_string_utf8(env, stringValue.c_str(), NAPI_AUTO_LENGTH, &value);
383 napi_set_named_property(env, result, fieldStr.c_str(), value);
384 }
385
SetDevicesInfo(vector<sptr<AudioDeviceDescriptor>> deviceDescriptors,napi_env env,napi_value * result,napi_value valueParam)386 static void SetDevicesInfo(vector<sptr<AudioDeviceDescriptor>> deviceDescriptors, napi_env env, napi_value* result,
387 napi_value valueParam)
388 {
389 size_t size = deviceDescriptors.size();
390 HiLog::Info(LABEL, "number of devices = %{public}zu", size);
391
392 napi_create_array_with_length(env, size, &result[PARAM1]);
393 for (size_t i = 0; i < size; i++) {
394 if (deviceDescriptors[i] != nullptr) {
395 (void)napi_create_object(env, &valueParam);
396 SetValueInt32(env, "deviceRole", static_cast<int32_t>(
397 deviceDescriptors[i]->deviceRole_), valueParam);
398 SetValueInt32(env, "deviceType", static_cast<int32_t>(
399 deviceDescriptors[i]->deviceType_), valueParam);
400 SetValueInt32(env, "id", static_cast<int32_t>(
401 deviceDescriptors[i]->deviceId_), valueParam);
402 SetValueString(env, "name", deviceDescriptors[i]->deviceName_, valueParam);
403 SetValueString(env, "address", deviceDescriptors[i]->macAddress_, valueParam);
404 SetValueString(env, "networkId", static_cast<std::string>(
405 deviceDescriptors[i]->networkId_), valueParam);
406 SetValueInt32(env, "interruptGroupId", static_cast<int32_t>(
407 deviceDescriptors[i]->interruptGroupId_), valueParam);
408 SetValueInt32(env, "volumeGroupId", static_cast<int32_t>(
409 deviceDescriptors[i]->volumeGroupId_), valueParam);
410
411 napi_value value = nullptr;
412 napi_value sampleRates;
413 napi_create_array_with_length(env, 1, &sampleRates);
414 napi_create_int32(env, deviceDescriptors[i]->audioStreamInfo_.samplingRate, &value);
415 napi_set_element(env, sampleRates, 0, value);
416 napi_set_named_property(env, valueParam, "sampleRates", sampleRates);
417
418 napi_value channelCounts;
419 napi_create_array_with_length(env, 1, &channelCounts);
420 napi_create_int32(env, deviceDescriptors[i]->audioStreamInfo_.channels, &value);
421 napi_set_element(env, channelCounts, 0, value);
422 napi_set_named_property(env, valueParam, "channelCounts", channelCounts);
423
424 napi_value channelMasks;
425 napi_create_array_with_length(env, 1, &channelMasks);
426 napi_create_int32(env, deviceDescriptors[i]->channelMasks_, &value);
427 napi_set_element(env, channelMasks, 0, value);
428 napi_set_named_property(env, valueParam, "channelMasks", channelMasks);
429 napi_set_element(env, result[PARAM1], i, valueParam);
430 }
431 }
432 }
433
GetDevicesAsyncCallbackComplete(napi_env env,napi_status status,void * data)434 static void GetDevicesAsyncCallbackComplete(napi_env env, napi_status status, void* data)
435 {
436 auto asyncContext = static_cast<AudioRoutingManagerAsyncContext*>(data);
437 if (asyncContext == nullptr) {
438 HiLog::Error(LABEL, "ERROR: AudioRoutingManagerAsyncContext* is Null!");
439 return;
440 }
441 napi_value result[ARGS_TWO] = {0};
442 napi_value valueParam = nullptr;
443 SetDevicesInfo(asyncContext->deviceDescriptors, env, result, valueParam);
444
445 napi_get_undefined(env, &result[PARAM0]);
446 if (!asyncContext->status) {
447 napi_get_undefined(env, &valueParam);
448 }
449 CommonCallbackRoutine(env, asyncContext, result[PARAM1]);
450 }
451
GetDevices(napi_env env,napi_callback_info info)452 napi_value AudioRoutingManagerNapi::GetDevices(napi_env env, napi_callback_info info)
453 {
454 const int32_t refCount = 1;
455 napi_value result = nullptr;
456
457 size_t argc = ARGS_TWO;
458 napi_value argv[ARGS_TWO] = { 0 };
459 napi_value thisVar = nullptr;
460 void* data;
461 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
462
463 unique_ptr<AudioRoutingManagerAsyncContext> asyncContext = make_unique<AudioRoutingManagerAsyncContext>();
464
465 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
466 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
467 CheckParams(argc, env, argv, asyncContext, refCount, result);
468
469 napi_value resource = nullptr;
470 napi_create_string_utf8(env, "GetDevices", NAPI_AUTO_LENGTH, &resource);
471
472 status = napi_create_async_work(
473 env, nullptr, resource, [](napi_env env, void *data) {
474 auto context = static_cast<AudioRoutingManagerAsyncContext*>(data);
475 if (context->status == SUCCESS) {
476 context->deviceDescriptors = context->objectInfo->audioMngr_->GetDevices(
477 static_cast<DeviceFlag>(context->deviceFlag));
478 context->status = 0;
479 }
480 }, GetDevicesAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
481 if (status != napi_ok) {
482 result = nullptr;
483 } else {
484 status = napi_queue_async_work(env, asyncContext->work);
485 if (status == napi_ok) {
486 asyncContext.release();
487 } else {
488 result = nullptr;
489 }
490 }
491 }
492
493 return result;
494 }
495
CheckParams(size_t argc,napi_env env,napi_value * argv,std::unique_ptr<AudioRoutingManagerAsyncContext> & asyncContext,const int32_t refCount,napi_value & result)496 void AudioRoutingManagerNapi::CheckParams(size_t argc, napi_env env, napi_value* argv,
497 std::unique_ptr<AudioRoutingManagerAsyncContext>& asyncContext, const int32_t refCount, napi_value& result)
498 {
499 if (argc < ARGS_ONE) {
500 asyncContext->status = NAPI_ERR_INVALID_PARAM;
501 }
502 for (size_t i = PARAM0; i < argc; i++) {
503 napi_valuetype valueType = napi_undefined;
504 napi_typeof(env, argv[i], &valueType);
505
506 if (i == PARAM0 && valueType == napi_number) {
507 napi_get_value_int32(env, argv[i], &asyncContext->deviceFlag);
508 HiLog::Info(LABEL, " GetDevices deviceFlag = %{public}d", asyncContext->deviceFlag);
509 if (!AudioCommonNapi::IsLegalInputArgumentDeviceFlag(asyncContext->deviceFlag)) {
510 asyncContext->status = asyncContext->status ==
511 NAPI_ERR_INVALID_PARAM? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
512 }
513 } else if (i == PARAM1) {
514 if (valueType == napi_function) {
515 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
516 }
517 break;
518 } else {
519 asyncContext->status = NAPI_ERR_INVALID_PARAM;
520 HiLog::Error(LABEL, "ERROR: type mismatch");
521 }
522 }
523
524 if (asyncContext->callbackRef == nullptr) {
525 napi_create_promise(env, &asyncContext->deferred, &result);
526 } else {
527 napi_get_undefined(env, &result);
528 }
529 }
530
SelectOutputDevice(napi_env env,napi_callback_info info)531 napi_value AudioRoutingManagerNapi::SelectOutputDevice(napi_env env, napi_callback_info info)
532 {
533 napi_status status;
534 const int32_t refCount = 1;
535 napi_value result = nullptr;
536 size_t argc = ARGS_TWO;
537 napi_value argv[ARGS_TWO] = {0};
538 napi_value thisVar = nullptr;
539 void *data = nullptr;
540 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
541
542 unique_ptr<AudioRoutingManagerAsyncContext> asyncContext = make_unique<AudioRoutingManagerAsyncContext>();
543
544 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
545 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
546 if (argc < ARGS_ONE) {
547 asyncContext->status = NAPI_ERR_INVALID_PARAM;
548 }
549 for (size_t i = PARAM0; i < argc; i++) {
550 napi_valuetype valueType = napi_undefined;
551 napi_typeof(env, argv[i], &valueType);
552
553 if (i == PARAM0 && valueType == napi_object) {
554 ParseAudioDeviceDescriptorVector(env, argv[i], asyncContext->deviceDescriptors,
555 asyncContext->bArgTransFlag);
556 } else if (i == PARAM1) {
557 if (valueType == napi_function) {
558 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
559 }
560 break;
561 } else {
562 asyncContext->status = NAPI_ERR_INVALID_PARAM;
563 }
564 }
565
566 if (asyncContext->callbackRef == nullptr) {
567 napi_create_promise(env, &asyncContext->deferred, &result);
568 } else {
569 napi_get_undefined(env, &result);
570 }
571
572 napi_value resource = nullptr;
573 napi_create_string_utf8(env, "SelectOutputDevice", NAPI_AUTO_LENGTH, &resource);
574
575 status = napi_create_async_work(
576 env, nullptr, resource,
577 [](napi_env env, void *data) {
578 auto context = static_cast<AudioRoutingManagerAsyncContext*>(data);
579 if (context->bArgTransFlag) {
580 context->status = context->objectInfo->audioMngr_->SelectOutputDevice(context->deviceDescriptors);
581 } else {
582 context->status = context->status ==
583 NAPI_ERR_INVALID_PARAM? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
584 }
585 },
586 SelectOutputDeviceAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
587 if (status != napi_ok) {
588 result = nullptr;
589 } else {
590 status = napi_queue_async_work(env, asyncContext->work);
591 if (status == napi_ok) {
592 asyncContext.release();
593 } else {
594 result = nullptr;
595 }
596 }
597 }
598 return result;
599 }
600
GetActiveOutputDeviceAsyncCallbackComplete(napi_env env,napi_status status,void * data)601 static void GetActiveOutputDeviceAsyncCallbackComplete(napi_env env, napi_status status, void* data)
602 {
603 auto asyncContext = static_cast<AudioRoutingManagerAsyncContext*>(data);
604 napi_value result[ARGS_TWO] = {0};
605 napi_value valueParam = nullptr;
606 if (asyncContext == nullptr) {
607 HiLog::Error(LABEL, "ERROR: AudioRoutingManagerAsyncContext* is Null!");
608 return;
609 }
610 SetDevicesInfo(asyncContext->outDeviceDescriptors, env, result, valueParam);
611
612 napi_get_undefined(env, &result[PARAM0]);
613 if (!asyncContext->status) {
614 napi_get_undefined(env, &valueParam);
615 }
616 CommonCallbackRoutine(env, asyncContext, result[PARAM1]);
617 }
618
GetActiveOutputDeviceDescriptors(napi_env env,napi_callback_info info)619 napi_value AudioRoutingManagerNapi::GetActiveOutputDeviceDescriptors(napi_env env, napi_callback_info info)
620 {
621 napi_status status;
622 const int32_t refCount = 1;
623 napi_value result = nullptr;
624 size_t argc = ARGS_ONE;
625 napi_value argv[ARGS_ONE] = {0};
626 napi_value thisVar = nullptr;
627 void *data = nullptr;
628 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
629
630 unique_ptr<AudioRoutingManagerAsyncContext> asyncContext = make_unique<AudioRoutingManagerAsyncContext>();
631
632 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
633 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
634 napi_valuetype valueType = napi_undefined;
635 napi_typeof(env, argv[PARAM0], &valueType);
636
637 if (argc == PARAM1 && valueType == napi_function) {
638 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
639 }
640
641 if (asyncContext->callbackRef == nullptr) {
642 napi_create_promise(env, &asyncContext->deferred, &result);
643 } else {
644 napi_get_undefined(env, &result);
645 }
646
647 napi_value resource = nullptr;
648 napi_create_string_utf8(env, "GetActiveOutputDeviceDescriptors", NAPI_AUTO_LENGTH, &resource);
649
650 status = napi_create_async_work(
651 env, nullptr, resource,
652 [](napi_env env, void *data) {
653 auto context = static_cast<AudioRoutingManagerAsyncContext*>(data);
654 if (context->status == SUCCESS) {
655 context->outDeviceDescriptors = context->objectInfo->audioMngr_->GetActiveOutputDeviceDescriptors();
656 context->status = SUCCESS;
657 }
658 },
659 GetActiveOutputDeviceAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
660 if (status != napi_ok) {
661 result = nullptr;
662 } else {
663 status = napi_queue_async_work(env, asyncContext->work);
664 if (status == napi_ok) {
665 asyncContext.release();
666 } else {
667 result = nullptr;
668 }
669 }
670 }
671 return result;
672 }
SelectOutputDeviceByFilter(napi_env env,napi_callback_info info)673 napi_value AudioRoutingManagerNapi::SelectOutputDeviceByFilter(napi_env env, napi_callback_info info)
674 {
675 napi_status status;
676 const int32_t refCount = 1;
677 napi_value result = nullptr;
678 size_t argc = ARGS_THREE;
679 napi_value argv[ARGS_THREE] = {0};
680 napi_value thisVar = nullptr;
681 void *data = nullptr;
682 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
683
684 unique_ptr<AudioRoutingManagerAsyncContext> asyncContext = make_unique<AudioRoutingManagerAsyncContext>();
685
686 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
687 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
688 if (argc < ARGS_TWO) {
689 asyncContext->status = NAPI_ERR_INVALID_PARAM;
690 }
691 for (size_t i = PARAM0; i < argc; i++) {
692 napi_valuetype valueType = napi_undefined;
693 napi_typeof(env, argv[i], &valueType);
694
695 if (i == PARAM0 && valueType == napi_object) {
696 ParseAudioRendererFilter(env, argv[i], asyncContext->audioRendererFilter, asyncContext->bArgTransFlag);
697 } else if (i == PARAM1 && valueType == napi_object) {
698 ParseAudioDeviceDescriptorVector(env, argv[i], asyncContext->deviceDescriptors,
699 asyncContext->bArgTransFlag);
700 } else if (i == PARAM2) {
701 if (valueType == napi_function) {
702 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
703 }
704 break;
705 } else {
706 asyncContext->status = NAPI_ERR_INVALID_PARAM;
707 }
708 }
709
710 if (asyncContext->callbackRef == nullptr) {
711 napi_create_promise(env, &asyncContext->deferred, &result);
712 } else {
713 napi_get_undefined(env, &result);
714 }
715
716 napi_value resource = nullptr;
717 napi_create_string_utf8(env, "SelectOutputDeviceByFilter", NAPI_AUTO_LENGTH, &resource);
718
719 status = napi_create_async_work(
720 env, nullptr, resource,
721 [](napi_env env, void *data) {
722 auto context = static_cast<AudioRoutingManagerAsyncContext*>(data);
723 if (context->bArgTransFlag) {
724 context->status = context->objectInfo->audioMngr_->SelectOutputDevice(
725 context->audioRendererFilter, context->deviceDescriptors);
726 } else {
727 context->status = context->status ==
728 NAPI_ERR_INVALID_PARAM? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
729 }
730 },
731 SelectOutputDeviceAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
732 if (status != napi_ok) {
733 result = nullptr;
734 } else {
735 status = napi_queue_async_work(env, asyncContext->work);
736 if (status == napi_ok) {
737 asyncContext.release();
738 } else {
739 result = nullptr;
740 }
741 }
742 }
743
744 return result;
745 }
746
ParseAudioCapturerFilter(napi_env env,napi_value root,sptr<AudioCapturerFilter> & audioCapturerFilter)747 static void ParseAudioCapturerFilter(napi_env env, napi_value root, sptr<AudioCapturerFilter> &audioCapturerFilter)
748 {
749 napi_value tempValue = nullptr;
750 int32_t intValue = {0};
751
752 audioCapturerFilter = new(std::nothrow) AudioCapturerFilter();
753 if (napi_get_named_property(env, root, "uid", &tempValue) == napi_ok) {
754 napi_get_value_int32(env, tempValue, &intValue);
755 audioCapturerFilter->uid = intValue;
756 }
757 }
758
SelectInputDeviceAsyncCallbackComplete(napi_env env,napi_status status,void * data)759 static void SelectInputDeviceAsyncCallbackComplete(napi_env env, napi_status status, void *data)
760 {
761 auto asyncContext = static_cast<AudioRoutingManagerAsyncContext*>(data);
762 napi_value valueParam = nullptr;
763
764 if (asyncContext != nullptr) {
765 if (!asyncContext->status) {
766 napi_get_undefined(env, &valueParam);
767 }
768 CommonCallbackRoutine(env, asyncContext, valueParam);
769 } else {
770 HiLog::Error(LABEL, "ERROR: AudioRoutingManagerAsyncContext* is Null!");
771 }
772 }
773
SelectInputDevice(napi_env env,napi_callback_info info)774 napi_value AudioRoutingManagerNapi::SelectInputDevice(napi_env env, napi_callback_info info)
775 {
776 napi_status status;
777 const int32_t refCount = 1;
778 napi_value result = nullptr;
779 size_t argc = ARGS_TWO;
780 napi_value argv[ARGS_TWO] = {0};
781 napi_value thisVar = nullptr;
782 void *data = nullptr;
783 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
784
785 unique_ptr<AudioRoutingManagerAsyncContext> asyncContext = make_unique<AudioRoutingManagerAsyncContext>();
786
787 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
788 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
789 if (argc < ARGS_ONE) {
790 asyncContext->status = NAPI_ERR_INVALID_PARAM;
791 }
792 for (size_t i = PARAM0; i < argc; i++) {
793 napi_valuetype valueType = napi_undefined;
794 napi_typeof(env, argv[i], &valueType);
795 if (i == PARAM0 && valueType == napi_object) {
796 ParseAudioDeviceDescriptorVector(env, argv[i], asyncContext->deviceDescriptors,
797 asyncContext->bArgTransFlag);
798 } else if (i == PARAM1) {
799 if (valueType == napi_function) {
800 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
801 }
802 break;
803 } else {
804 asyncContext->status = NAPI_ERR_INVALID_PARAM;
805 }
806
807 if (!asyncContext->bArgTransFlag) {
808 break;
809 }
810 }
811
812 if (asyncContext->callbackRef == nullptr) {
813 napi_create_promise(env, &asyncContext->deferred, &result);
814 } else {
815 napi_get_undefined(env, &result);
816 }
817
818 napi_value resource = nullptr;
819 napi_create_string_utf8(env, "SelectInputDevice", NAPI_AUTO_LENGTH, &resource);
820
821 status = napi_create_async_work(
822 env, nullptr, resource,
823 [](napi_env env, void *data) {
824 auto context = static_cast<AudioRoutingManagerAsyncContext*>(data);
825 if (context->bArgTransFlag) {
826 context->status = context->objectInfo->audioMngr_->SelectInputDevice(context->deviceDescriptors);
827 } else {
828 context->status = ERR_INVALID_PARAM;
829 }
830 },
831 SelectInputDeviceAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
832 if (status != napi_ok) {
833 result = nullptr;
834 } else {
835 status = napi_queue_async_work(env, asyncContext->work);
836 if (status == napi_ok) {
837 asyncContext.release();
838 } else {
839 result = nullptr;
840 }
841 }
842 }
843
844 return result;
845 }
846
SelectInputDeviceByFilter(napi_env env,napi_callback_info info)847 napi_value AudioRoutingManagerNapi::SelectInputDeviceByFilter(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 size_t argc = ARGS_THREE;
854 napi_value argv[ARGS_TWO] = {0};
855 napi_value thisVar = nullptr;
856 void *data = nullptr;
857 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
858 NAPI_ASSERT(env, argc >= ARGS_THREE, "requires 2 parameters minimum");
859
860 unique_ptr<AudioRoutingManagerAsyncContext> asyncContext = make_unique<AudioRoutingManagerAsyncContext>();
861
862 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
863 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
864 if (argc < ARGS_TWO) {
865 asyncContext->status = NAPI_ERR_INVALID_PARAM;
866 }
867 for (size_t i = PARAM0; i < argc; i++) {
868 napi_valuetype valueType = napi_undefined;
869 napi_typeof(env, argv[i], &valueType);
870 if (i == PARAM0 && valueType == napi_object) {
871 ParseAudioCapturerFilter(env, argv[i], asyncContext->audioCapturerFilter);
872 } else if (i == PARAM1 && valueType == napi_object) {
873 ParseAudioDeviceDescriptorVector(env, argv[i], asyncContext->deviceDescriptors,
874 asyncContext->bArgTransFlag);
875 } else if (i == PARAM2) {
876 if (valueType == napi_function) {
877 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
878 }
879 break;
880 } else {
881 asyncContext->status = NAPI_ERR_INVALID_PARAM;
882 }
883
884 if (!asyncContext->bArgTransFlag) {
885 break;
886 }
887 }
888
889 if (asyncContext->callbackRef == nullptr) {
890 napi_create_promise(env, &asyncContext->deferred, &result);
891 } else {
892 napi_get_undefined(env, &result);
893 }
894
895 napi_value resource = nullptr;
896 napi_create_string_utf8(env, "SelectInputDeviceByFilter", NAPI_AUTO_LENGTH, &resource);
897
898 status = napi_create_async_work(
899 env, nullptr, resource,
900 [](napi_env env, void *data) {
901 auto context = static_cast<AudioRoutingManagerAsyncContext*>(data);
902 if (context->bArgTransFlag) {
903 context->status = context->objectInfo->audioMngr_->SelectInputDevice(
904 context->audioCapturerFilter, context->deviceDescriptors);
905 } else {
906 context->status = context->status ==
907 NAPI_ERR_INVALID_PARAM? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
908 }
909 },
910 SelectInputDeviceAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
911 if (status != napi_ok) {
912 result = nullptr;
913 } else {
914 status = napi_queue_async_work(env, asyncContext->work);
915 if (status == napi_ok) {
916 asyncContext.release();
917 } else {
918 result = nullptr;
919 }
920 }
921 }
922
923 return result;
924 }
925
RegisterDeviceChangeCallback(napi_env env,napi_value * args,const std::string & cbName,int32_t flag,AudioRoutingManagerNapi * routingMgrNapi)926 void AudioRoutingManagerNapi::RegisterDeviceChangeCallback(napi_env env, napi_value* args,
927 const std::string& cbName, int32_t flag, AudioRoutingManagerNapi* routingMgrNapi)
928 {
929 if (!routingMgrNapi->deviceChangeCallbackNapi_) {
930 routingMgrNapi->deviceChangeCallbackNapi_= std::make_shared<AudioManagerCallbackNapi>(env);
931 if (!routingMgrNapi->deviceChangeCallbackNapi_) {
932 AUDIO_ERR_LOG("AudioStreamMgrNapi: Memory Allocation Failed !!");
933 return;
934 }
935 DeviceFlag deviceFlag = DeviceFlag(flag);
936
937 int32_t ret = routingMgrNapi->audioMngr_->SetDeviceChangeCallback(deviceFlag,
938 routingMgrNapi->deviceChangeCallbackNapi_);
939 if (ret) {
940 AUDIO_ERR_LOG("AudioRoutingMgrNapi: Registering Device Change Callback Failed");
941 return;
942 }
943 }
944
945 std::shared_ptr<AudioManagerCallbackNapi> cb =
946 std::static_pointer_cast<AudioManagerCallbackNapi>(routingMgrNapi->deviceChangeCallbackNapi_);
947 cb->SaveCallbackReference(cbName, args[PARAM2]);
948
949 AUDIO_INFO_LOG("AudioRoutingManager::On SetDeviceChangeCallback is successful");
950 }
951
RegisterCallback(napi_env env,napi_value jsThis,napi_value * args,const std::string & cbName,int32_t flag)952 void AudioRoutingManagerNapi::RegisterCallback(napi_env env, napi_value jsThis,
953 napi_value* args, const std::string& cbName, int32_t flag)
954 {
955 AudioRoutingManagerNapi* routingMgrNapi = nullptr;
956 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void**>(&routingMgrNapi));
957 if ((status != napi_ok) || (routingMgrNapi == nullptr) || (routingMgrNapi->audioMngr_ == nullptr)
958 || (routingMgrNapi->audioRoutingMngr_ == nullptr)) {
959 AUDIO_ERR_LOG("AudioRoutingMgrNapi::Failed to retrieve stream mgr napi instance.");
960
961 return;
962 }
963
964 if (!cbName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
965 RegisterDeviceChangeCallback(env, args, cbName, flag, routingMgrNapi);
966 } else {
967 AUDIO_ERR_LOG("AudioRoutingMgrNapi::No such supported");
968 AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
969 }
970 }
971
On(napi_env env,napi_callback_info info)972 napi_value AudioRoutingManagerNapi::On(napi_env env, napi_callback_info info)
973 {
974 AUDIO_INFO_LOG("audioRoutingManagerNapi: On inter");
975
976 const size_t requireArgc = PARAM2;
977 const size_t maxArgc = PARAM3;
978 size_t argc = PARAM3;
979
980 napi_value undefinedResult = nullptr;
981 napi_get_undefined(env, &undefinedResult);
982
983 napi_value args[requireArgc + 1] = { nullptr, nullptr, nullptr };
984 napi_value jsThis = nullptr;
985 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
986 bool isArgcCountRight = argc == requireArgc || argc == maxArgc;
987 THROW_ERROR_ASSERT(env, status == napi_ok && isArgcCountRight, NAPI_ERR_INPUT_INVALID);
988
989 napi_valuetype eventType = napi_undefined;
990 napi_typeof(env, args[0], &eventType);
991 THROW_ERROR_ASSERT(env, eventType == napi_string, NAPI_ERR_INPUT_INVALID);
992 std::string callbackName = AudioCommonNapi::GetStringArgument(env, args[0]);
993 AUDIO_INFO_LOG("AaudioRoutingManagerNapi: On callbackName: %{public}s", callbackName.c_str());
994
995 int32_t deviceFlag;
996
997 if (argc == requireArgc) {
998 napi_valuetype handler = napi_undefined;
999 napi_typeof(env, args[1], &handler);
1000 THROW_ERROR_ASSERT(env, handler == napi_function, NAPI_ERR_INPUT_INVALID);
1001 deviceFlag = 3; // 3 for ALL_DEVICES_FLAG
1002 }
1003 if (argc == maxArgc) {
1004 napi_valuetype valueType = napi_undefined;
1005 napi_typeof(env, args[PARAM1], &valueType);
1006 if (valueType == napi_number) {
1007 napi_get_value_int32(env, args[PARAM1], &deviceFlag);
1008 AUDIO_INFO_LOG("AudioRoutingMgrNapi:On deviceFlag: %{public}d", deviceFlag);
1009 if (!AudioCommonNapi::IsLegalInputArgumentDeviceFlag(deviceFlag)) {
1010 THROW_ERROR_ASSERT(env, false, NAPI_ERR_INVALID_PARAM);
1011 }
1012 } else {
1013 THROW_ERROR_ASSERT(env, false, NAPI_ERR_INPUT_INVALID);
1014 }
1015
1016 napi_valuetype handler = napi_undefined;
1017 napi_typeof(env, args[PARAM2], &handler);
1018 THROW_ERROR_ASSERT(env, handler == napi_function, NAPI_ERR_INPUT_INVALID);
1019 }
1020
1021 RegisterCallback(env, jsThis, args, callbackName, deviceFlag);
1022
1023 return undefinedResult;
1024 }
1025
Off(napi_env env,napi_callback_info info)1026 napi_value AudioRoutingManagerNapi::Off(napi_env env, napi_callback_info info)
1027 {
1028 napi_value undefinedResult = nullptr;
1029 napi_get_undefined(env, &undefinedResult);
1030
1031 const size_t minArgCount = 1;
1032 size_t argCount = 3;
1033 napi_value args[minArgCount + 2] = {nullptr, nullptr, nullptr};
1034 napi_value jsThis = nullptr;
1035 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
1036 if (status != napi_ok || argCount < minArgCount) {
1037 AUDIO_ERR_LOG("Off fail to napi_get_cb_info/Requires min 1 parameters");
1038 AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
1039 return undefinedResult;
1040 }
1041
1042 napi_valuetype eventType = napi_undefined;
1043 if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
1044 AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
1045 return undefinedResult;
1046 }
1047 std::string callbackName = AudioCommonNapi::GetStringArgument(env, args[0]);
1048 AUDIO_INFO_LOG("AudioManagerNapi::Off callbackName: %{public}s", callbackName.c_str());
1049
1050 AudioRoutingManagerNapi* routingMgrNapi = nullptr;
1051 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&routingMgrNapi));
1052 NAPI_ASSERT(env, status == napi_ok && routingMgrNapi != nullptr, "Failed to retrieve audio mgr napi instance.");
1053 NAPI_ASSERT(env, routingMgrNapi->audioMngr_ != nullptr, "audio system mgr instance is null.");
1054
1055 if (!callbackName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
1056 int32_t ret = routingMgrNapi->audioMngr_->UnsetDeviceChangeCallback();
1057 if (ret) {
1058 AUDIO_ERR_LOG("AudioManagerNapi::Off UnsetDeviceChangeCallback Failed");
1059 return undefinedResult;
1060 }
1061 if (routingMgrNapi->deviceChangeCallbackNapi_ != nullptr) {
1062 routingMgrNapi->deviceChangeCallbackNapi_.reset();
1063 routingMgrNapi->deviceChangeCallbackNapi_ = nullptr;
1064 }
1065 AUDIO_INFO_LOG("AudioManagerNapi::Off UnsetDeviceChangeCallback Success");
1066 } else {
1067 AUDIO_ERR_LOG("AudioRoutingMgrNapi:: off no such supported");
1068 AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
1069 }
1070 return undefinedResult;
1071 }
1072
SetCommunicationDevice(napi_env env,napi_callback_info info)1073 napi_value AudioRoutingManagerNapi::SetCommunicationDevice(napi_env env, napi_callback_info info)
1074 {
1075 napi_status status;
1076 const int32_t refCount = 1;
1077 napi_value result = nullptr;
1078
1079 GET_PARAMS(env, info, ARGS_THREE);
1080
1081 unique_ptr<AudioRoutingManagerAsyncContext> asyncContext = make_unique<AudioRoutingManagerAsyncContext>();
1082
1083 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1084 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1085 if (argc < ARGS_TWO) {
1086 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1087 }
1088 for (size_t i = PARAM0; i < argc; i++) {
1089 napi_valuetype valueType = napi_undefined;
1090 napi_typeof(env, argv[i], &valueType);
1091
1092 if (i == PARAM0 && valueType == napi_number) {
1093 napi_get_value_int32(env, argv[i], &asyncContext->deviceType);
1094 if (!AudioCommonNapi::IsLegalInputArgumentCommunicationDeviceType(asyncContext->deviceType)) {
1095 asyncContext->status = asyncContext->status ==
1096 NAPI_ERR_INVALID_PARAM? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1097 }
1098 } else if (i == PARAM1 && valueType == napi_boolean) {
1099 napi_get_value_bool(env, argv[i], &asyncContext->isActive);
1100 } else if (i == PARAM2) {
1101 if (valueType == napi_function) {
1102 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1103 }
1104 break;
1105 } else {
1106 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1107 }
1108 }
1109
1110 if (asyncContext->callbackRef == nullptr) {
1111 napi_create_promise(env, &asyncContext->deferred, &result);
1112 } else {
1113 napi_get_undefined(env, &result);
1114 }
1115
1116 napi_value resource = nullptr;
1117 napi_create_string_utf8(env, "SetCommunicationDeviceActive", NAPI_AUTO_LENGTH, &resource);
1118
1119 status = napi_create_async_work(
1120 env, nullptr, resource,
1121 [](napi_env env, void *data) {
1122 auto context = static_cast<AudioRoutingManagerAsyncContext*>(data);
1123 if (context->status == 0) {
1124 context->status = context->objectInfo->audioMngr_->SetDeviceActive(
1125 static_cast<ActiveDeviceType>(context->deviceType), context->isActive);
1126 }
1127 },
1128 SetFunctionAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1129 if (status != napi_ok) {
1130 result = nullptr;
1131 } else {
1132 status = napi_queue_async_work(env, asyncContext->work);
1133 if (status == napi_ok) {
1134 asyncContext.release();
1135 } else {
1136 result = nullptr;
1137 }
1138 }
1139 }
1140
1141 return result;
1142 }
1143
IsCommunicationDeviceActive(napi_env env,napi_callback_info info)1144 napi_value AudioRoutingManagerNapi::IsCommunicationDeviceActive(napi_env env, napi_callback_info info)
1145 {
1146 napi_status status;
1147 const int32_t refCount = 1;
1148 napi_value result = nullptr;
1149
1150 GET_PARAMS(env, info, ARGS_TWO);
1151
1152 unique_ptr<AudioRoutingManagerAsyncContext> asyncContext = make_unique<AudioRoutingManagerAsyncContext>();
1153
1154 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1155 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1156 if (argc < ARGS_ONE) {
1157 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1158 }
1159 for (size_t i = PARAM0; i < argc; i++) {
1160 napi_valuetype valueType = napi_undefined;
1161 napi_typeof(env, argv[i], &valueType);
1162
1163 if (i == PARAM0 && valueType == napi_number) {
1164 napi_get_value_int32(env, argv[i], &asyncContext->deviceType);
1165 if (!AudioCommonNapi::IsLegalInputArgumentActiveDeviceType(asyncContext->deviceType)) {
1166 asyncContext->status = asyncContext->status ==
1167 NAPI_ERR_INVALID_PARAM? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
1168 }
1169 } else if (i == PARAM1) {
1170 if (valueType == napi_function) {
1171 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1172 }
1173 break;
1174 } else {
1175 asyncContext->status = NAPI_ERR_INVALID_PARAM;
1176 }
1177 }
1178
1179 if (asyncContext->callbackRef == nullptr) {
1180 napi_create_promise(env, &asyncContext->deferred, &result);
1181 } else {
1182 napi_get_undefined(env, &result);
1183 }
1184
1185 napi_value resource = nullptr;
1186 napi_create_string_utf8(env, "IsCommunicationDeviceActive", NAPI_AUTO_LENGTH, &resource);
1187
1188 status = napi_create_async_work(
1189 env, nullptr, resource,
1190 [](napi_env env, void *data) {
1191 auto context = static_cast<AudioRoutingManagerAsyncContext*>(data);
1192 if (context->status == SUCCESS) {
1193 context->isActive = context->objectInfo->audioMngr_->
1194 IsDeviceActive(static_cast<ActiveDeviceType>(context->deviceType));
1195 context->isTrue = context->isActive;
1196 context->status = 0;
1197 }
1198 },
1199 IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1200 if (status != napi_ok) {
1201 result = nullptr;
1202 } else {
1203 status = napi_queue_async_work(env, asyncContext->work);
1204 if (status == napi_ok) {
1205 asyncContext.release();
1206 } else {
1207 result = nullptr;
1208 }
1209 }
1210 }
1211
1212 return result;
1213 }
1214
1215 } // namespace AudioStandard
1216 } // namespace OHOS
1217