1 /*
2 * Copyright (c) 2023-2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "NapiAudioRoutingManager"
17 #endif
18
19 #include "napi_audio_routing_manager.h"
20 #include "napi_audio_error.h"
21 #include "napi_param_utils.h"
22 #include "napi_audio_enum.h"
23 #include "audio_errors.h"
24 #include "audio_manager_log.h"
25 #include "napi_audio_manager_callbacks.h"
26 #include "napi_audio_rounting_available_devicechange_callback.h"
27 #include "napi_audio_routing_manager_callbacks.h"
28 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
29 #include "parameters.h"
30 #endif
31
32 namespace OHOS {
33 namespace AudioStandard {
34 using namespace std;
35 using namespace HiviewDFX;
36 static __thread napi_ref g_routingManagerConstructor = nullptr;
37
NapiAudioRoutingManager()38 NapiAudioRoutingManager::NapiAudioRoutingManager()
39 : audioMngr_(nullptr), env_(nullptr) {}
40
41 NapiAudioRoutingManager::~NapiAudioRoutingManager() = default;
42
Destructor(napi_env env,void * nativeObject,void * finalizeHint)43 void NapiAudioRoutingManager::Destructor(napi_env env, void *nativeObject, void *finalizeHint)
44 {
45 if (nativeObject == nullptr) {
46 AUDIO_WARNING_LOG("Native object is null");
47 return;
48 }
49 auto obj = static_cast<NapiAudioRoutingManager *>(nativeObject);
50 ObjectRefMap<NapiAudioRoutingManager>::DecreaseRef(obj);
51 AUDIO_INFO_LOG("Decrease obj count");
52 }
53
Construct(napi_env env,napi_callback_info info)54 napi_value NapiAudioRoutingManager::Construct(napi_env env, napi_callback_info info)
55 {
56 napi_status status;
57 napi_value result = nullptr;
58 napi_get_undefined(env, &result);
59
60 size_t argc = ARGS_TWO;
61 napi_value argv[ARGS_TWO] = {0};
62 napi_value thisVar = nullptr;
63 void *data = nullptr;
64 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
65 unique_ptr<NapiAudioRoutingManager> napiAudioRoutingManager = make_unique<NapiAudioRoutingManager>();
66 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "No memory");
67
68 napiAudioRoutingManager->audioMngr_ = AudioSystemManager::GetInstance();
69 napiAudioRoutingManager->audioRoutingMngr_ = AudioRoutingManager::GetInstance();
70 napiAudioRoutingManager->env_ = env;
71 ObjectRefMap<NapiAudioRoutingManager>::Insert(napiAudioRoutingManager.get());
72
73 status = napi_wrap(env, thisVar, static_cast<void*>(napiAudioRoutingManager.get()),
74 NapiAudioRoutingManager::Destructor, nullptr, nullptr);
75 if (status != napi_ok) {
76 ObjectRefMap<NapiAudioRoutingManager>::Erase(napiAudioRoutingManager.get());
77 return result;
78 }
79 napiAudioRoutingManager.release();
80 return thisVar;
81 }
82
Init(napi_env env,napi_value exports)83 napi_value NapiAudioRoutingManager::Init(napi_env env, napi_value exports)
84 {
85 napi_status status;
86 napi_value constructor;
87 napi_value result = nullptr;
88 const int32_t refCount = ARGS_ONE;
89 napi_get_undefined(env, &result);
90
91 napi_property_descriptor audio_routing_manager_properties[] = {
92 DECLARE_NAPI_FUNCTION("getDevices", GetDevices),
93 DECLARE_NAPI_FUNCTION("getDevicesSync", GetDevicesSync),
94 DECLARE_NAPI_FUNCTION("selectOutputDevice", SelectOutputDevice),
95 DECLARE_NAPI_FUNCTION("selectOutputDeviceByFilter", SelectOutputDeviceByFilter),
96 DECLARE_NAPI_FUNCTION("selectInputDevice", SelectInputDevice),
97 DECLARE_NAPI_FUNCTION("selectInputDeviceByFilter", SelectInputDeviceByFilter),
98 DECLARE_NAPI_FUNCTION("excludeOutputDevices", ExcludeOutputDevices),
99 DECLARE_NAPI_FUNCTION("unexcludeOutputDevices", UnexcludeOutputDevices),
100 DECLARE_NAPI_FUNCTION("setCommunicationDevice", SetCommunicationDevice),
101 DECLARE_NAPI_FUNCTION("isCommunicationDeviceActive", IsCommunicationDeviceActive),
102 DECLARE_NAPI_FUNCTION("isCommunicationDeviceActiveSync", IsCommunicationDeviceActiveSync),
103 DECLARE_NAPI_FUNCTION("getActiveOutputDeviceDescriptors", GetActiveOutputDeviceDescriptors),
104 DECLARE_NAPI_FUNCTION("getPreferredOutputDeviceForRendererInfo", GetPreferredOutputDeviceForRendererInfo),
105 DECLARE_NAPI_FUNCTION("getPreferOutputDeviceForRendererInfo", GetPreferOutputDeviceForRendererInfo),
106 DECLARE_NAPI_FUNCTION("getPreferredOutputDeviceForRendererInfoSync",
107 GetPreferredOutputDeviceForRendererInfoSync),
108 DECLARE_NAPI_FUNCTION("getPreferredOutputDeviceByFilter", GetPreferredOutputDeviceByFilter),
109 DECLARE_NAPI_FUNCTION("getPreferredInputDeviceForCapturerInfo", GetPreferredInputDeviceForCapturerInfo),
110 DECLARE_NAPI_FUNCTION("getPreferredInputDeviceForCapturerInfoSync", GetPreferredInputDeviceForCapturerInfoSync),
111 DECLARE_NAPI_FUNCTION("getPreferredInputDeviceByFilter", GetPreferredInputDeviceByFilter),
112 DECLARE_NAPI_FUNCTION("getAvailableMicrophones", GetAvailableMicrophones),
113 DECLARE_NAPI_FUNCTION("getAvailableDevices", GetAvailableDevices),
114 DECLARE_NAPI_FUNCTION("getExcludedDevices", GetExcludedDevices),
115 DECLARE_NAPI_FUNCTION("on", On),
116 DECLARE_NAPI_FUNCTION("off", Off),
117 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
118 DECLARE_NAPI_FUNCTION("isMicBlockDetectionSupported", IsMicBlockDetectionSupported),
119 #endif
120 };
121
122 status = napi_define_class(env, NAPI_AUDIO_ROUTING_MANAGER_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct,
123 nullptr, sizeof(audio_routing_manager_properties) / sizeof(audio_routing_manager_properties[PARAM0]),
124 audio_routing_manager_properties, &constructor);
125 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_define_class fail");
126
127 status = napi_create_reference(env, constructor, refCount, &g_routingManagerConstructor);
128 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_reference fail");
129 status = napi_set_named_property(env, exports, NAPI_AUDIO_ROUTING_MANAGER_CLASS_NAME.c_str(), constructor);
130 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_set_named_property fail");
131 return exports;
132 }
133
CheckContextStatus(std::shared_ptr<AudioRoutingManagerAsyncContext> context)134 bool NapiAudioRoutingManager::CheckContextStatus(std::shared_ptr<AudioRoutingManagerAsyncContext> context)
135 {
136 CHECK_AND_RETURN_RET_LOG(context != nullptr, false, "context object is nullptr.");
137 if (context->native == nullptr) {
138 context->SignError(NAPI_ERR_SYSTEM);
139 AUDIO_ERR_LOG("context object state is error.");
140 return false;
141 }
142 return true;
143 }
144
CheckAudioRoutingManagerStatus(NapiAudioRoutingManager * napi,std::shared_ptr<AudioRoutingManagerAsyncContext> context)145 bool NapiAudioRoutingManager::CheckAudioRoutingManagerStatus(NapiAudioRoutingManager *napi,
146 std::shared_ptr<AudioRoutingManagerAsyncContext> context)
147 {
148 CHECK_AND_RETURN_RET_LOG(napi != nullptr, false, "napi object is nullptr.");
149 if ((napi->audioMngr_ == nullptr) || (napi->audioRoutingMngr_ == nullptr)) {
150 context->SignError(NAPI_ERR_SYSTEM);
151 AUDIO_ERR_LOG("audioMngr_ is nullptr");
152 return false;
153 }
154
155 return true;
156 }
157
GetParamWithSync(const napi_env & env,napi_callback_info info,size_t & argc,napi_value * args)158 NapiAudioRoutingManager* NapiAudioRoutingManager::GetParamWithSync(const napi_env &env, napi_callback_info info,
159 size_t &argc, napi_value *args)
160 {
161 napi_status status;
162 NapiAudioRoutingManager *napiAudioRoutingManager = nullptr;
163 napi_value jsThis = nullptr;
164 status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
165 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr,
166 "GetParamWithSync fail to napi_get_cb_info");
167
168 status = napi_unwrap(env, jsThis, (void **)&napiAudioRoutingManager);
169 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "napi_unwrap failed");
170 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr && napiAudioRoutingManager->audioMngr_ !=
171 nullptr, napiAudioRoutingManager, "GetParamWithSync fail to napi_unwrap");
172 return napiAudioRoutingManager;
173 }
174
CreateRoutingManagerWrapper(napi_env env)175 napi_value NapiAudioRoutingManager::CreateRoutingManagerWrapper(napi_env env)
176 {
177 napi_status status;
178 napi_value result = nullptr;
179 napi_value constructor;
180
181 status = napi_get_reference_value(env, g_routingManagerConstructor, &constructor);
182 if (status != napi_ok) {
183 AUDIO_ERR_LOG("Failed in CreateRoutingManagerWrapper, %{public}d", status);
184 goto fail;
185 }
186 status = napi_new_instance(env, constructor, PARAM0, nullptr, &result);
187 if (status != napi_ok) {
188 AUDIO_ERR_LOG("napi_new_instance failed, status:%{public}d", status);
189 goto fail;
190 }
191 return result;
192
193 fail:
194 napi_get_undefined(env, &result);
195 return result;
196 }
197
GetDevices(napi_env env,napi_callback_info info)198 napi_value NapiAudioRoutingManager::GetDevices(napi_env env, napi_callback_info info)
199 {
200 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
201 if (context == nullptr) {
202 AUDIO_ERR_LOG("GetDevices failed : no memory");
203 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
204 return NapiParamUtils::GetUndefinedValue(env);
205 }
206
207 auto inputParser = [env, context](size_t argc, napi_value *argv) {
208 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
209 NAPI_ERR_INVALID_PARAM);
210 context->status = NapiParamUtils::GetValueInt32(env, context->deviceFlag, argv[PARAM0]);
211 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get deviceFlag failed",
212 NAPI_ERR_INVALID_PARAM);
213 if (!NapiAudioEnum::IsLegalInputArgumentDeviceFlag(context->deviceFlag)) {
214 context->SignError(context->errCode ==
215 NAPI_ERR_INVALID_PARAM?
216 NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED);
217 }
218 };
219 context->GetCbInfo(env, info, inputParser);
220
221 auto executor = [context]() {
222 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
223 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
224 ObjectRefMap objectGuard(obj);
225 auto *napiAudioRoutingManager = objectGuard.GetPtr();
226 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
227 "context object state is error.");
228 context->deviceDescriptors = napiAudioRoutingManager->audioMngr_->GetDevices(
229 static_cast<DeviceFlag>(context->deviceFlag));
230 };
231 auto complete = [env, context](napi_value &output) {
232 NapiParamUtils::SetDeviceDescriptors(env, context->deviceDescriptors, output);
233 };
234 return NapiAsyncWork::Enqueue(env, context, "GetDevices", executor, complete);
235 }
236
GetDevicesSync(napi_env env,napi_callback_info info)237 napi_value NapiAudioRoutingManager::GetDevicesSync(napi_env env, napi_callback_info info)
238 {
239 napi_value result = nullptr;
240 size_t argc = ARGS_ONE;
241 napi_value argv[ARGS_ONE] = {};
242 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
243 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
244 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argCount invalid");
245
246 napi_valuetype valueType = napi_undefined;
247 napi_typeof(env, argv[PARAM0], &valueType);
248 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
249 NAPI_ERR_INPUT_INVALID,
250 "incorrect parameter types: The type of deviceFlag must be number"), "valueType invalid");
251
252 int32_t deviceFlag;
253 napi_status status = NapiParamUtils::GetValueInt32(env, deviceFlag, argv[PARAM0]);
254 CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentDeviceFlag(deviceFlag) && (status == napi_ok),
255 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
256 "parameter verification failed: The param of deviceFlag must be enum DeviceFlag"), "deviceFlag invalid");
257
258 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
259 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioMngr_ != nullptr, result, "audioMngr_ nullptr");
260 vector<std::shared_ptr<AudioDeviceDescriptor>> deviceDescriptors = napiAudioRoutingManager->audioMngr_->GetDevices(
261 static_cast<DeviceFlag>(deviceFlag));
262
263 NapiParamUtils::SetDeviceDescriptors(env, deviceDescriptors, result);
264
265 return result;
266 }
267
SelectOutputDevice(napi_env env,napi_callback_info info)268 napi_value NapiAudioRoutingManager::SelectOutputDevice(napi_env env, napi_callback_info info)
269 {
270 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
271 if (context == nullptr) {
272 AUDIO_ERR_LOG("SelectOutputDevice failed : no memory");
273 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
274 return NapiParamUtils::GetUndefinedValue(env);
275 }
276
277 auto inputParser = [env, context](size_t argc, napi_value *argv) {
278 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
279 NAPI_ERR_INVALID_PARAM);
280 NapiParamUtils::GetAudioDeviceDescriptorVector(env, context->deviceDescriptors,
281 context->bArgTransFlag, argv[PARAM0]);
282 NAPI_CHECK_ARGS_RETURN_VOID(context, context->bArgTransFlag, "select output device failed",
283 NAPI_ERR_UNSUPPORTED);
284 };
285 context->GetCbInfo(env, info, inputParser);
286
287 auto executor = [context]() {
288 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
289 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
290 ObjectRefMap objectGuard(obj);
291 auto *napiAudioRoutingManager = objectGuard.GetPtr();
292 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
293 "context object state is error.");
294 context->intValue = napiAudioRoutingManager->audioMngr_->SelectOutputDevice(context->deviceDescriptors);
295 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SelectOutputDevice failed",
296 NAPI_ERR_SYSTEM);
297 };
298
299 auto complete = [env](napi_value &output) {
300 output = NapiParamUtils::GetUndefinedValue(env);
301 };
302 return NapiAsyncWork::Enqueue(env, context, "SelectOutputDevice", executor, complete);
303 }
304
SelectOutputDeviceByFilter(napi_env env,napi_callback_info info)305 napi_value NapiAudioRoutingManager::SelectOutputDeviceByFilter(napi_env env, napi_callback_info info)
306 {
307 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
308 if (context == nullptr) {
309 AUDIO_ERR_LOG("SelectOutputDeviceByFilter failed : no memory");
310 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
311 return NapiParamUtils::GetUndefinedValue(env);
312 }
313
314 auto inputParser = [env, context](size_t argc, napi_value *argv) {
315 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_TWO, "invalid arguments",
316 NAPI_ERR_INVALID_PARAM);
317 NapiParamUtils::GetAudioRendererFilter(env, context->audioRendererFilter,
318 context->bArgTransFlag, argv[PARAM0]);
319 NapiParamUtils::GetAudioDeviceDescriptorVector(env, context->deviceDescriptors,
320 context->bArgTransFlag, argv[PARAM1]);
321 };
322 context->GetCbInfo(env, info, inputParser);
323
324 auto executor = [context]() {
325 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
326 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
327 ObjectRefMap objectGuard(obj);
328 auto *napiAudioRoutingManager = objectGuard.GetPtr();
329 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
330 "context object state is error.");
331 if (!context->bArgTransFlag) {
332 context->SignError(NAPI_ERR_UNSUPPORTED);
333 }
334 context->intValue = napiAudioRoutingManager->audioMngr_->SelectOutputDevice(context->audioRendererFilter,
335 context->deviceDescriptors);
336 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SelectOutputDeviceByFilter failed",
337 NAPI_ERR_SYSTEM);
338 };
339
340 auto complete = [env](napi_value &output) {
341 output = NapiParamUtils::GetUndefinedValue(env);
342 };
343 return NapiAsyncWork::Enqueue(env, context, "SelectOutputDeviceByFilter", executor, complete);
344 }
345
SelectInputDevice(napi_env env,napi_callback_info info)346 napi_value NapiAudioRoutingManager::SelectInputDevice(napi_env env, napi_callback_info info)
347 {
348 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
349 if (context == nullptr) {
350 AUDIO_ERR_LOG("SelectInputDevice failed : no memory");
351 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
352 return NapiParamUtils::GetUndefinedValue(env);
353 }
354
355 auto inputParser = [env, context](size_t argc, napi_value *argv) {
356 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
357 NAPI_ERR_INVALID_PARAM);
358 NapiParamUtils::GetAudioDeviceDescriptorVector(env, context->deviceDescriptors,
359 context->bArgTransFlag, argv[PARAM0]);
360 };
361 context->GetCbInfo(env, info, inputParser);
362
363 auto executor = [context]() {
364 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
365 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
366 ObjectRefMap objectGuard(obj);
367 auto *napiAudioRoutingManager = objectGuard.GetPtr();
368 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
369 "context object state is error.");
370 if (!context->bArgTransFlag) {
371 context->SignError(NAPI_ERR_INVALID_PARAM);
372 }
373 context->intValue = napiAudioRoutingManager->audioMngr_->SelectInputDevice(context->deviceDescriptors);
374 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SelectInputDevice failed",
375 NAPI_ERR_SYSTEM);
376 };
377
378 auto complete = [env](napi_value &output) {
379 output = NapiParamUtils::GetUndefinedValue(env);
380 };
381 return NapiAsyncWork::Enqueue(env, context, "SelectInputDevice", executor, complete);
382 }
383
SelectInputDeviceByFilter(napi_env env,napi_callback_info info)384 napi_value NapiAudioRoutingManager::SelectInputDeviceByFilter(napi_env env, napi_callback_info info)
385 {
386 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
387 if (context == nullptr) {
388 AUDIO_ERR_LOG("SelectInputDeviceByFilter failed : no memory");
389 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
390 return NapiParamUtils::GetUndefinedValue(env);
391 }
392
393 auto inputParser = [env, context](size_t argc, napi_value *argv) {
394 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_TWO, "invalid arguments",
395 NAPI_ERR_INVALID_PARAM);
396 context->status = NapiParamUtils::GetAudioCapturerFilter(env, context->audioCapturerFilter, argv[PARAM0]);
397 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "select input device by filter failed",
398 NAPI_ERR_INVALID_PARAM);
399 NapiParamUtils::GetAudioDeviceDescriptorVector(env, context->deviceDescriptors,
400 context->bArgTransFlag, argv[PARAM1]);
401 };
402 context->GetCbInfo(env, info, inputParser);
403
404 auto executor = [context]() {
405 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
406 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
407 ObjectRefMap objectGuard(obj);
408 auto *napiAudioRoutingManager = objectGuard.GetPtr();
409 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
410 "context object state is error.");
411 if (!context->bArgTransFlag) {
412 context->SignError(NAPI_ERR_UNSUPPORTED);
413 }
414 context->intValue = napiAudioRoutingManager->audioMngr_->SelectInputDevice(context->audioCapturerFilter,
415 context->deviceDescriptors);
416 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SelectInputDevice failed",
417 NAPI_ERR_SYSTEM);
418 };
419
420 auto complete = [env](napi_value &output) {
421 output = NapiParamUtils::GetUndefinedValue(env);
422 };
423 return NapiAsyncWork::Enqueue(env, context, "SelectInputDeviceByFilter", executor, complete);
424 }
425
ExcludeOutputDevices(napi_env env,napi_callback_info info)426 napi_value NapiAudioRoutingManager::ExcludeOutputDevices(napi_env env, napi_callback_info info)
427 {
428 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
429 if (context == nullptr) {
430 AUDIO_ERR_LOG("ExcludeOutputDevices failed : no memory");
431 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
432 return NapiParamUtils::GetUndefinedValue(env);
433 }
434
435 auto inputParser = [env, context](size_t argc, napi_value *argv) {
436 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_TWO, "invalid arguments", NAPI_ERR_INVALID_PARAM);
437 context->status = NapiParamUtils::GetAudioDeviceUsage(env, context->audioDevUsage, argv[PARAM0]);
438 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "exclude output devices failed",
439 NAPI_ERR_UNSUPPORTED);
440 NapiParamUtils::GetAudioDeviceDescriptorVector(env, context->deviceDescriptors,
441 context->bArgTransFlag, argv[PARAM1]);
442 };
443 context->GetCbInfo(env, info, inputParser);
444
445 auto executor = [context]() {
446 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
447 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
448 ObjectRefMap objectGuard(obj);
449 auto *napiAudioRoutingManager = objectGuard.GetPtr();
450 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
451 "context object state is error.");
452 context->intValue = napiAudioRoutingManager->audioMngr_->ExcludeOutputDevices(context->audioDevUsage,
453 context->deviceDescriptors);
454 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "ExcludeOutputDevices failed",
455 NAPI_ERR_SYSTEM);
456 };
457
458 auto complete = [env](napi_value &output) {
459 output = NapiParamUtils::GetUndefinedValue(env);
460 };
461 return NapiAsyncWork::Enqueue(env, context, "ExcludeOutputDevices", executor, complete);
462 }
463
UnexcludeOutputDevices(napi_env env,napi_callback_info info)464 napi_value NapiAudioRoutingManager::UnexcludeOutputDevices(napi_env env, napi_callback_info info)
465 {
466 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
467 if (context == nullptr) {
468 AUDIO_ERR_LOG("UnexcludeOutputDevices failed : no memory");
469 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
470 return NapiParamUtils::GetUndefinedValue(env);
471 }
472
473 auto inputParser = [env, context](size_t argc, napi_value *argv) {
474 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
475 context->status = NapiParamUtils::GetAudioDeviceUsage(env, context->audioDevUsage, argv[PARAM0]);
476 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "unexclude output devices failed",
477 NAPI_ERR_UNSUPPORTED);
478 context->argSize = argc;
479 if (argc == ARGS_TWO) {
480 NapiParamUtils::GetAudioDeviceDescriptorVector(env, context->deviceDescriptors,
481 context->bArgTransFlag, argv[PARAM1]);
482 }
483 };
484 context->GetCbInfo(env, info, inputParser);
485
486 auto executor = [context]() {
487 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
488 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
489 ObjectRefMap objectGuard(obj);
490 auto *napiAudioRoutingManager = objectGuard.GetPtr();
491 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
492 "context object state is error.");
493 if (context->argSize == ARGS_ONE) {
494 context->intValue = napiAudioRoutingManager->audioMngr_->UnexcludeOutputDevices(context->audioDevUsage);
495 } else {
496 context->intValue = napiAudioRoutingManager->audioMngr_->UnexcludeOutputDevices(context->audioDevUsage,
497 context->deviceDescriptors);
498 }
499 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "UnexcludeOutputDevices failed",
500 NAPI_ERR_SYSTEM);
501 };
502
503 auto complete = [env](napi_value &output) {
504 output = NapiParamUtils::GetUndefinedValue(env);
505 };
506 return NapiAsyncWork::Enqueue(env, context, "UnexcludeOutputDevices", executor, complete);
507 }
508
SetCommunicationDevice(napi_env env,napi_callback_info info)509 napi_value NapiAudioRoutingManager::SetCommunicationDevice(napi_env env, napi_callback_info info)
510 {
511 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
512 if (context == nullptr) {
513 AUDIO_ERR_LOG("SetCommunicationDevice failed : no memory");
514 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
515 return NapiParamUtils::GetUndefinedValue(env);
516 }
517
518 auto inputParser = [env, context](size_t argc, napi_value *argv) {
519 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_TWO, "invalid arguments",
520 NAPI_ERR_INVALID_PARAM);
521 context->status = NapiParamUtils::GetValueInt32(env, context->deviceType, argv[PARAM0]);
522 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "set communication device failed",
523 NAPI_ERR_INVALID_PARAM);
524 if (!NapiAudioEnum::IsLegalInputArgumentCommunicationDeviceType(context->deviceType)) {
525 context->SignError(context->errCode == NAPI_ERR_INVALID_PARAM?
526 NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED);
527 }
528 context->status = NapiParamUtils::GetValueBoolean(env, context->isActive, argv[PARAM1]);
529 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "set communication device failed",
530 NAPI_ERR_INVALID_PARAM);
531 };
532 context->GetCbInfo(env, info, inputParser);
533
534 auto executor = [context]() {
535 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
536 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
537 ObjectRefMap objectGuard(obj);
538 auto *napiAudioRoutingManager = objectGuard.GetPtr();
539 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
540 "context object state is error.");
541 context->intValue = napiAudioRoutingManager->audioMngr_->SetDeviceActive(
542 static_cast<DeviceType>(context->deviceType), context->isActive);
543 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SelectInputDevice failed",
544 NAPI_ERR_SYSTEM);
545 };
546
547 auto complete = [env](napi_value &output) {
548 output = NapiParamUtils::GetUndefinedValue(env);
549 };
550 return NapiAsyncWork::Enqueue(env, context, "SetCommunicationDevice", executor, complete);
551 }
552
IsCommunicationDeviceActive(napi_env env,napi_callback_info info)553 napi_value NapiAudioRoutingManager::IsCommunicationDeviceActive(napi_env env, napi_callback_info info)
554 {
555 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
556 if (context == nullptr) {
557 AUDIO_ERR_LOG("IsCommunicationDeviceActive failed : no memory");
558 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
559 return NapiParamUtils::GetUndefinedValue(env);
560 }
561
562 auto inputParser = [env, context](size_t argc, napi_value *argv) {
563 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
564 NAPI_ERR_INVALID_PARAM);
565 context->status = NapiParamUtils::GetValueInt32(env, context->deviceType, argv[PARAM0]);
566 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "IsCommunicationDeviceActive failed",
567 NAPI_ERR_INVALID_PARAM);
568 if (!NapiAudioEnum::IsLegalInputArgumentActiveDeviceType(context->deviceType)) {
569 context->SignError(context->errCode == NAPI_ERR_INVALID_PARAM?
570 NAPI_ERR_INVALID_PARAM: NAPI_ERR_UNSUPPORTED);
571 }
572 };
573 context->GetCbInfo(env, info, inputParser);
574
575 auto executor = [context]() {
576 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
577 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
578 ObjectRefMap objectGuard(obj);
579 auto *napiAudioRoutingManager = objectGuard.GetPtr();
580 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
581 "context object state is error.");
582 context->isActive = napiAudioRoutingManager->audioMngr_->IsDeviceActive(
583 static_cast<DeviceType>(context->deviceType));
584 context->isTrue = context->isActive;
585 };
586
587 auto complete = [env, context](napi_value &output) {
588 NapiParamUtils::SetValueBoolean(env, context->isTrue, output);
589 };
590 return NapiAsyncWork::Enqueue(env, context, "IsCommunicationDeviceActive", executor, complete);
591 }
592
IsCommunicationDeviceActiveSync(napi_env env,napi_callback_info info)593 napi_value NapiAudioRoutingManager::IsCommunicationDeviceActiveSync(napi_env env, napi_callback_info info)
594 {
595 napi_value result = nullptr;
596 size_t argc = ARGS_ONE;
597 napi_value argv[ARGS_ONE] = {};
598 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
599 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
600 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argCount invalid");
601
602 napi_valuetype valueType = napi_undefined;
603 napi_typeof(env, argv[PARAM0], &valueType);
604 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
605 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceType must be number"),
606 "valueType invalid");
607
608 int32_t deviceType;
609 napi_status status = NapiParamUtils::GetValueInt32(env, deviceType, argv[PARAM0]);
610 CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentActiveDeviceType(deviceType) && status == napi_ok,
611 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
612 "parameter verification failed: The param of deviceType must be enum CommunicationDeviceType"),
613 "valueType invalid");
614
615 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
616 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioMngr_ != nullptr, result, "audioMngr_ nullptr");
617 bool isActive = napiAudioRoutingManager->audioMngr_->IsDeviceActive(static_cast<DeviceType>(deviceType));
618
619 NapiParamUtils::SetValueBoolean(env, isActive, result);
620 return result;
621 }
622
GetActiveOutputDeviceDescriptors(napi_env env,napi_callback_info info)623 napi_value NapiAudioRoutingManager::GetActiveOutputDeviceDescriptors(napi_env env, napi_callback_info info)
624 {
625 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
626 if (context == nullptr) {
627 AUDIO_ERR_LOG("GetActiveOutputDeviceDescriptors failed : no memory");
628 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
629 return NapiParamUtils::GetUndefinedValue(env);
630 }
631
632 context->GetCbInfo(env, info);
633
634 auto executor = [context]() {
635 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
636 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
637 ObjectRefMap objectGuard(obj);
638 auto *napiAudioRoutingManager = objectGuard.GetPtr();
639 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
640 "context object state is error.");
641 context->outDeviceDescriptors = napiAudioRoutingManager->audioMngr_->GetActiveOutputDeviceDescriptors();
642 };
643
644 auto complete = [env, context](napi_value &output) {
645 NapiParamUtils::SetDeviceDescriptors(env, context->outDeviceDescriptors, output);
646 };
647 return NapiAsyncWork::Enqueue(env, context, "GetActiveOutputDeviceDescriptors", executor, complete);
648 }
649
GetPreferredOutputDeviceForRendererInfo(napi_env env,napi_callback_info info)650 napi_value NapiAudioRoutingManager::GetPreferredOutputDeviceForRendererInfo(napi_env env, napi_callback_info info)
651 {
652 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
653 if (context == nullptr) {
654 AUDIO_ERR_LOG("GetPreferredOutputDeviceForRendererInfo failed : no memory");
655 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
656 return NapiParamUtils::GetUndefinedValue(env);
657 }
658
659 auto inputParser = [env, context](size_t argc, napi_value *argv) {
660 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
661 NAPI_ERR_INPUT_INVALID);
662 context->status = NapiParamUtils::GetRendererInfo(env, &(context->rendererInfo), argv[PARAM0]);
663 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
664 "incorrect parameter types: The type of rendererInfo must be interface AudioRendererInfo",
665 NAPI_ERR_INPUT_INVALID);
666 };
667 context->GetCbInfo(env, info, inputParser);
668 if (context->status != napi_ok) {
669 NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
670 return NapiParamUtils::GetUndefinedValue(env);
671 }
672
673 auto executor = [context]() {
674 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
675 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
676 ObjectRefMap objectGuard(obj);
677 auto *napiAudioRoutingManager = objectGuard.GetPtr();
678 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
679 "context object state is error.");
680 if (context->rendererInfo.streamUsage == StreamUsage::STREAM_USAGE_INVALID) {
681 context->SignError(NAPI_ERR_INVALID_PARAM,
682 "parameter verification failed: The param of usage invalid");
683 } else {
684 context->intValue = napiAudioRoutingManager->audioRoutingMngr_->GetPreferredOutputDeviceForRendererInfo(
685 context->rendererInfo, context->outDeviceDescriptors);
686 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS,
687 "GetPreferredOutputDeviceForRendererInfo failed", NAPI_ERR_SYSTEM);
688 }
689 };
690
691 auto complete = [env, context](napi_value &output) {
692 NapiParamUtils::SetDeviceDescriptors(env, context->outDeviceDescriptors, output);
693 };
694 return NapiAsyncWork::Enqueue(env, context, "GetPreferredOutputDeviceForRendererInfo", executor, complete);
695 }
696
GetPreferOutputDeviceForRendererInfo(napi_env env,napi_callback_info info)697 napi_value NapiAudioRoutingManager::GetPreferOutputDeviceForRendererInfo(napi_env env, napi_callback_info info)
698 {
699 // for api compatibility, leave some time for applications to adapt to new one
700 return GetPreferredOutputDeviceForRendererInfo(env, info);
701 }
702
GetPreferredOutputDeviceForRendererInfoSync(napi_env env,napi_callback_info info)703 napi_value NapiAudioRoutingManager::GetPreferredOutputDeviceForRendererInfoSync(napi_env env, napi_callback_info info)
704 {
705 AUDIO_INFO_LOG("GetPreferredOutputDeviceForRendererInfoSync");
706 napi_value result = nullptr;
707 size_t argc = ARGS_ONE;
708 napi_value argv[ARGS_ONE] = {};
709 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
710 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
711 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argCount invalid");
712
713 napi_valuetype valueType = napi_undefined;
714 napi_typeof(env, argv[PARAM0], &valueType);
715 CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
716 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of rendererInfo must be object"),
717 "valueType invalid");
718
719 AudioRendererInfo rendererInfo;
720 if (NapiParamUtils::GetRendererInfo(env, &rendererInfo, argv[PARAM0]) != napi_ok) {
721 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
722 "incorrect parameter types: The type of rendererInfo must be interface AudioRendererInfo");
723 return result;
724 } else if (rendererInfo.streamUsage == StreamUsage::STREAM_USAGE_INVALID) {
725 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
726 "parameter verification failed: The param of usage invalid");
727 return result;
728 }
729
730 vector<std::shared_ptr<AudioDeviceDescriptor>> outDeviceDescriptors;
731 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
732 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioRoutingMngr_ != nullptr, result,
733 "audioRoutingMngr_ nullptr");
734 napiAudioRoutingManager->audioRoutingMngr_->GetPreferredOutputDeviceForRendererInfo(
735 rendererInfo, outDeviceDescriptors);
736
737 NapiParamUtils::SetDeviceDescriptors(env, outDeviceDescriptors, result);
738
739 return result;
740 }
741
742
GetPreferredOutputDeviceByFilter(napi_env env,napi_callback_info info)743 napi_value NapiAudioRoutingManager::GetPreferredOutputDeviceByFilter(napi_env env, napi_callback_info info)
744 {
745 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
746 if (context == nullptr) {
747 AUDIO_ERR_LOG("GetPreferredOutputDeviceByFilter failed : no memory");
748 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
749 return NapiParamUtils::GetUndefinedValue(env);
750 }
751
752 auto inputParser = [env, context](size_t argc, napi_value *argv) {
753 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
754 NAPI_ERR_INVALID_PARAM);
755 context->status = NapiParamUtils::GetAudioRendererFilter(env, context->audioRendererFilter,
756 context->bArgTransFlag, argv[PARAM0]);
757 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get AudioRendererFilter failed",
758 NAPI_ERR_INVALID_PARAM);
759 };
760 context->GetCbInfo(env, info, inputParser);
761
762 auto executor = [context]() {
763 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
764 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
765 ObjectRefMap objectGuard(obj);
766 auto *napiAudioRoutingManager = objectGuard.GetPtr();
767 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
768 "context object state is error.");
769 context->deviceDescriptors = napiAudioRoutingManager->audioMngr_->GetOutputDevice(context->audioRendererFilter);
770 };
771 auto complete = [env, context](napi_value &output) {
772 NapiParamUtils::SetDeviceDescriptors(env, context->deviceDescriptors, output);
773 };
774 return NapiAsyncWork::Enqueue(env, context, "GetPreferredOutputDeviceByFilter", executor, complete);
775 }
776
GetPreferredInputDeviceForCapturerInfo(napi_env env,napi_callback_info info)777 napi_value NapiAudioRoutingManager::GetPreferredInputDeviceForCapturerInfo(napi_env env, napi_callback_info info)
778 {
779 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
780 if (context == nullptr) {
781 AUDIO_ERR_LOG("GetPreferredInputDeviceForCapturerInfo failed : no memory");
782 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
783 return NapiParamUtils::GetUndefinedValue(env);
784 }
785
786 auto inputParser = [env, context](size_t argc, napi_value *argv) {
787 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
788 NAPI_ERR_INPUT_INVALID);
789 context->status = NapiParamUtils::GetAudioCapturerInfo(env, &context->captureInfo, argv[PARAM0]);
790 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
791 "incorrect parameter types: The type of capturerInfo must be interface AudioCapturerInfo",
792 NAPI_ERR_INPUT_INVALID);
793 };
794 context->GetCbInfo(env, info, inputParser);
795
796 if (context->status != napi_ok) {
797 NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
798 return NapiParamUtils::GetUndefinedValue(env);
799 }
800
801 auto executor = [context]() {
802 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
803 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
804 ObjectRefMap objectGuard(obj);
805 auto *napiAudioRoutingManager = objectGuard.GetPtr();
806 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
807 "context object state is error.");
808 if (context->captureInfo.sourceType == SourceType::SOURCE_TYPE_INVALID) {
809 context->SignError(NAPI_ERR_INVALID_PARAM,
810 "parameter verification failed: The param of sourceType invalid");
811 } else {
812 context->intValue = napiAudioRoutingManager->audioRoutingMngr_->GetPreferredInputDeviceForCapturerInfo(
813 context->captureInfo, context->inputDeviceDescriptors);
814 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS,
815 "GetPreferredInputDeviceForCapturerInfo failed", NAPI_ERR_SYSTEM);
816 }
817 };
818
819 auto complete = [env, context](napi_value &output) {
820 NapiParamUtils::SetDeviceDescriptors(env, context->inputDeviceDescriptors, output);
821 };
822 return NapiAsyncWork::Enqueue(env, context, "GetPreferredInputDeviceForCapturerInfo", executor, complete);
823 }
824
GetPreferredInputDeviceForCapturerInfoSync(napi_env env,napi_callback_info info)825 napi_value NapiAudioRoutingManager::GetPreferredInputDeviceForCapturerInfoSync(napi_env env, napi_callback_info info)
826 {
827 napi_value result = nullptr;
828 size_t argc = ARGS_ONE;
829 napi_value argv[ARGS_ONE] = {};
830 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
831 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
832 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argCount invalid");
833
834 napi_valuetype valueType = napi_undefined;
835 napi_typeof(env, argv[PARAM0], &valueType);
836 CHECK_AND_RETURN_RET_LOG(valueType == napi_object,
837 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
838 "incorrect parameter types: The type of capturerInfo must be object"), "valueType invalid");
839
840 AudioCapturerInfo capturerInfo;
841 napi_status status = NapiParamUtils::GetAudioCapturerInfo(env, &capturerInfo, argv[PARAM0]);
842 CHECK_AND_RETURN_RET_LOG((capturerInfo.sourceType != SourceType::SOURCE_TYPE_INVALID) && (status == napi_ok),
843 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
844 "parameter verification failed: The param of capturerInfo must be interface AudioCapturerInfo"),
845 "sourceType invalid");
846
847 vector<std::shared_ptr<AudioDeviceDescriptor>> outDeviceDescriptors;
848 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
849 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioRoutingMngr_ != nullptr, result,
850 "audioRoutingMngr_ nullptr");
851 napiAudioRoutingManager->audioRoutingMngr_->GetPreferredInputDeviceForCapturerInfo(
852 capturerInfo, outDeviceDescriptors);
853
854 NapiParamUtils::SetDeviceDescriptors(env, outDeviceDescriptors, result);
855
856 return result;
857 }
858
GetPreferredInputDeviceByFilter(napi_env env,napi_callback_info info)859 napi_value NapiAudioRoutingManager::GetPreferredInputDeviceByFilter(napi_env env, napi_callback_info info)
860 {
861 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
862 if (context == nullptr) {
863 AUDIO_ERR_LOG("GetPreferredInputDeviceByFilter failed : no memory");
864 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
865 return NapiParamUtils::GetUndefinedValue(env);
866 }
867
868 auto inputParser = [env, context](size_t argc, napi_value *argv) {
869 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
870 NAPI_ERR_INVALID_PARAM);
871 context->status = NapiParamUtils::GetAudioCapturerFilter(env, context->audioCapturerFilter, argv[PARAM0]);
872 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get GetAudioCapturerFilter failed",
873 NAPI_ERR_INVALID_PARAM);
874 };
875 context->GetCbInfo(env, info, inputParser);
876
877 auto executor = [context]() {
878 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
879 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
880 ObjectRefMap objectGuard(obj);
881 auto *napiAudioRoutingManager = objectGuard.GetPtr();
882 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
883 "context object state is error.");
884 context->deviceDescriptors = napiAudioRoutingManager->audioMngr_->GetInputDevice(context->audioCapturerFilter);
885 };
886 auto complete = [env, context](napi_value &output) {
887 NapiParamUtils::SetDeviceDescriptors(env, context->deviceDescriptors, output);
888 };
889 return NapiAsyncWork::Enqueue(env, context, "GetPreferredInputDeviceByFilter", executor, complete);
890 }
891
GetAvailableMicrophones(napi_env env,napi_callback_info info)892 napi_value NapiAudioRoutingManager::GetAvailableMicrophones(napi_env env, napi_callback_info info)
893 {
894 AUDIO_INFO_LOG("GetAvailableMicrophones");
895 napi_value result = nullptr;
896 size_t argc = PARAM0;
897 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, nullptr);
898 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
899 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argCount invalid");
900 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
901 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioRoutingMngr_ != nullptr, result,
902 "audioRoutingMngr_ is nullptr");
903
904 vector<sptr<MicrophoneDescriptor>> micDescs =
905 napiAudioRoutingManager->audioRoutingMngr_->GetAvailableMicrophones();
906
907 NapiParamUtils::SetMicrophoneDescriptors(env, micDescs, result);
908
909 return result;
910 }
911
GetAvailableDevices(napi_env env,napi_callback_info info)912 napi_value NapiAudioRoutingManager::GetAvailableDevices(napi_env env, napi_callback_info info)
913 {
914 napi_value result = nullptr;
915 size_t argc = ARGS_ONE;
916 napi_value argv[ARGS_ONE] = {};
917 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
918 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
919 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argcCount invalid");
920
921 napi_valuetype valueType = napi_undefined;
922 napi_status status = napi_typeof(env, argv[PARAM0], &valueType);
923 CHECK_AND_RETURN_RET_LOG(status == napi_ok && valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
924 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceUsage must be number"),
925 "valueType invalid");
926
927 int32_t intValue = 0;
928 status = napi_get_value_int32(env, argv[PARAM0], &intValue);
929 CHECK_AND_RETURN_RET_LOG(status == napi_ok && NapiAudioEnum::IsLegalDeviceUsage(intValue),
930 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
931 "parameter verification failed: The param of deviceUsage must be enum DeviceUsage"), "invalid deviceusage");
932
933 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
934 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioRoutingMngr_ != nullptr, result,
935 "audioRoutingMngr_ is nullptr");
936 AudioDeviceUsage usage = static_cast<AudioDeviceUsage>(intValue);
937
938 vector<std::shared_ptr<AudioDeviceDescriptor>> availableDescs =
939 napiAudioRoutingManager->audioRoutingMngr_->GetAvailableDevices(usage);
940
941 vector<std::shared_ptr<AudioDeviceDescriptor>> availableSptrDescs;
942 for (const auto &availableDesc : availableDescs) {
943 std::shared_ptr<AudioDeviceDescriptor> dec = std::make_shared<AudioDeviceDescriptor>(*availableDesc);
944 CHECK_AND_BREAK_LOG(dec != nullptr, "dec mallac failed,no memery.");
945 availableSptrDescs.push_back(dec);
946 }
947 NapiParamUtils::SetDeviceDescriptors(env, availableSptrDescs, result);
948 return result;
949 }
950
GetExcludedDevices(napi_env env,napi_callback_info info)951 napi_value NapiAudioRoutingManager::GetExcludedDevices(napi_env env, napi_callback_info info)
952 {
953 napi_value result = nullptr;
954 size_t argc = ARGS_ONE;
955 napi_value argv[ARGS_ONE] = {};
956 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
957 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
958 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioMngr_ != nullptr, result,
959 "audioMngr_ is nullptr");
960 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
961 "mandatory parameters are left unspecified"), "argCount invalid");
962
963 AudioDeviceUsage audioDevUsage;
964 napi_status status = NapiParamUtils::GetAudioDeviceUsage(env, audioDevUsage, argv[PARAM0]);
965 CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
966 "parameter verification failed: The param of deviceUsage must be enum DeviceUsage"),
967 "exclude output devices failed");
968 vector<shared_ptr<AudioDeviceDescriptor>> excludedDevices =
969 napiAudioRoutingManager->audioMngr_->GetExcludedDevices(audioDevUsage);
970 NapiParamUtils::SetDeviceDescriptors(env, excludedDevices, result);
971 return result;
972 }
973
RegisterCallback(napi_env env,napi_value jsThis,size_t argc,napi_value * args,const std::string & cbName)974 napi_value NapiAudioRoutingManager::RegisterCallback(napi_env env, napi_value jsThis, size_t argc,
975 napi_value *args, const std::string &cbName)
976 {
977 napi_value undefinedResult = nullptr;
978 NapiAudioRoutingManager *napiRoutingMgr = nullptr;
979 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void**>(&napiRoutingMgr));
980 if ((status != napi_ok) || (napiRoutingMgr == nullptr) || (napiRoutingMgr->audioMngr_ == nullptr) ||
981 (napiRoutingMgr->audioRoutingMngr_ == nullptr)) {
982 AUDIO_ERR_LOG("NapiAudioRoutingManager::Failed to retrieve stream mgr napi instance.");
983 return undefinedResult;
984 }
985
986 if (!cbName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
987 RegisterDeviceChangeCallback(env, argc, args, cbName, napiRoutingMgr);
988 } else if (!cbName.compare(PREFERRED_OUTPUT_DEVICE_CALLBACK_NAME) ||
989 !cbName.compare(PREFER_OUTPUT_DEVICE_CALLBACK_NAME)) {
990 RegisterPreferredOutputDeviceChangeCallback(env, argc, args, cbName, napiRoutingMgr);
991 } else if (!cbName.compare(PREFERRED_INPUT_DEVICE_CALLBACK_NAME)) {
992 RegisterPreferredInputDeviceChangeCallback(env, argc, args, cbName, napiRoutingMgr);
993 } else if (!cbName.compare(AVAILABLE_DEVICE_CHANGE_CALLBACK_NAME)) {
994 RegisterAvaiableDeviceChangeCallback(env, argc, args, cbName, napiRoutingMgr);
995 } else if (!cbName.compare(MICROPHONE_BLOCKED_CALLBACK_NAME)) {
996 RegisterMicrophoneBlockedCallback(env, argc, args, cbName, napiRoutingMgr);
997 } else {
998 AUDIO_ERR_LOG("NapiAudioRoutingManager::No such supported");
999 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1000 "parameter verification failed: The param of type is not supported");
1001 }
1002 return undefinedResult;
1003 }
1004
RegisterDeviceChangeCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1005 void NapiAudioRoutingManager::RegisterDeviceChangeCallback(napi_env env, size_t argc, napi_value *args,
1006 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1007 {
1008 int32_t flag = ARGS_THREE;
1009 napi_valuetype valueType = napi_undefined;
1010 napi_typeof(env, args[PARAM1], &valueType);
1011 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowError(env,
1012 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceFlag must be number"),
1013 "invalid valueType");
1014 if (valueType == napi_number) {
1015 NapiParamUtils::GetValueInt32(env, flag, args[PARAM1]);
1016 AUDIO_INFO_LOG("RegisterDeviceChangeCallback:On deviceFlag: %{public}d", flag);
1017 if (!NapiAudioEnum::IsLegalInputArgumentDeviceFlag(flag)) {
1018 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1019 "parameter verification failed: The param of deviceFlag must be enum DeviceFlag");
1020 }
1021 }
1022
1023 napi_valuetype handler = napi_undefined;
1024 napi_typeof(env, args[PARAM2], &handler);
1025
1026 if (handler != napi_function) {
1027 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1028 "incorrect parameter types: The type of callback must be function");
1029 }
1030 DeviceFlag deviceFlag = DeviceFlag(flag);
1031 if (!napiRoutingMgr->deviceChangeCallbackNapi_) {
1032 napiRoutingMgr->deviceChangeCallbackNapi_ = std::make_shared<NapiAudioManagerCallback>(env);
1033 }
1034 CHECK_AND_RETURN_LOG(napiRoutingMgr->deviceChangeCallbackNapi_,
1035 "RegisterDeviceChangeCallback: Memory Allocation Failed !");
1036
1037 int32_t ret = napiRoutingMgr->audioMngr_->SetDeviceChangeCallback(deviceFlag,
1038 napiRoutingMgr->deviceChangeCallbackNapi_);
1039 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1040 "RegisterDeviceChangeCallback: Registering Device Change Callback Failed %{public}d", ret);
1041
1042 std::shared_ptr<NapiAudioManagerCallback> cb =
1043 std::static_pointer_cast<NapiAudioManagerCallback>(napiRoutingMgr->deviceChangeCallbackNapi_);
1044 cb->SaveRoutingManagerDeviceChangeCbRef(deviceFlag, args[PARAM2]);
1045 if (!cb->GetDevChgTsfnFlag()) {
1046 cb->CreateDevChgTsfn(env);
1047 }
1048 }
1049
GetNapiPrefOutputDeviceChangeCb(napi_value args,NapiAudioRoutingManager * napiRoutingMgr)1050 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> NapiAudioRoutingManager::GetNapiPrefOutputDeviceChangeCb(
1051 napi_value args, NapiAudioRoutingManager *napiRoutingMgr)
1052 {
1053 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredOutputDeviceMutex_);
1054 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb = nullptr;
1055 for (auto &iter : napiRoutingMgr->preferredOutputDeviceCallbacks_) {
1056 if (iter->ContainSameJsCallback(args)) {
1057 cb = iter;
1058 }
1059 }
1060 return cb;
1061 }
1062
AddPreferredOutputDeviceChangeCallback(NapiAudioRoutingManager * napiRoutingMgr,std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb)1063 void NapiAudioRoutingManager::AddPreferredOutputDeviceChangeCallback(NapiAudioRoutingManager *napiRoutingMgr,
1064 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb)
1065 {
1066 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredOutputDeviceMutex_);
1067 napiRoutingMgr->preferredOutputDeviceCallbacks_.push_back(cb);
1068 }
1069
RegisterPreferredOutputDeviceChangeCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1070 void NapiAudioRoutingManager::RegisterPreferredOutputDeviceChangeCallback(napi_env env, size_t argc, napi_value *args,
1071 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1072 {
1073 CHECK_AND_RETURN_RET_LOG(argc == ARGS_THREE, NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1074 "incorrect number of parameters: expected at least 3 parameters"), "argc invalid");
1075
1076 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::CheckArgType(env, args[PARAM1], napi_object),
1077 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1078 "incorrect parameter types: The type of rendererInfo must be object"), "rendererInfo invalid");
1079
1080 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::CheckArgType(env, args[PARAM2], napi_function),
1081 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1082 "incorrect parameter types: The type of callback must be function"), "callback invalid");
1083
1084 CHECK_AND_RETURN_LOG(GetNapiPrefOutputDeviceChangeCb(args[PARAM2], napiRoutingMgr) == nullptr,
1085 "Do not allow duplicate registration of the same callback");
1086
1087 AudioRendererInfo rendererInfo;
1088 NapiParamUtils::GetRendererInfo(env, &rendererInfo, args[PARAM1]);
1089 CHECK_AND_RETURN_RET_LOG(rendererInfo.streamUsage != StreamUsage::STREAM_USAGE_INVALID,
1090 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1091 "parameter verification failed: The param of streamUsage invalid"), "invalid streamUsage");
1092 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb =
1093 std::make_shared<NapiAudioPreferredOutputDeviceChangeCallback>(env);
1094 CHECK_AND_RETURN_LOG(cb != nullptr, "Memory allocation failed!!");
1095
1096 cb->SaveCallbackReference(args[PARAM2]);
1097 cb->CreatePreferredOutTsfn(env);
1098
1099 int32_t ret = napiRoutingMgr->audioRoutingMngr_->SetPreferredOutputDeviceChangeCallback(
1100 rendererInfo, cb);
1101 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1102 "Registering Preferred Output Device Change Callback Failed %{public}d", ret);
1103
1104 AddPreferredOutputDeviceChangeCallback(napiRoutingMgr, cb);
1105 }
1106
GetNapiPrefInputDeviceChangeCb(napi_value args,NapiAudioRoutingManager * napiRoutingMgr)1107 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> NapiAudioRoutingManager::GetNapiPrefInputDeviceChangeCb(
1108 napi_value args, NapiAudioRoutingManager *napiRoutingMgr)
1109 {
1110 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredInputDeviceMutex_);
1111 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb = nullptr;
1112 for (auto &iter : napiRoutingMgr->preferredInputDeviceCallbacks_) {
1113 if (iter->ContainSameJsCallback(args)) {
1114 cb = iter;
1115 }
1116 }
1117 return cb;
1118 }
1119
AddPreferredInputDeviceChangeCallback(NapiAudioRoutingManager * napiRoutingMgr,std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb)1120 void NapiAudioRoutingManager::AddPreferredInputDeviceChangeCallback(NapiAudioRoutingManager *napiRoutingMgr,
1121 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb)
1122 {
1123 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredInputDeviceMutex_);
1124 napiRoutingMgr->preferredInputDeviceCallbacks_.push_back(cb);
1125 }
1126
RegisterPreferredInputDeviceChangeCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1127 void NapiAudioRoutingManager::RegisterPreferredInputDeviceChangeCallback(napi_env env, size_t argc, napi_value *args,
1128 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1129 {
1130 CHECK_AND_RETURN_RET_LOG(argc >= ARGS_THREE, NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1131 "mandatory parameters are left unspecified"), "argCount invalid");
1132
1133 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::CheckArgType(env, args[PARAM1], napi_object),
1134 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1135 "incorrect parameter types: The type of capturerInfo must be object"), "capturerInfo invalid");
1136
1137 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::CheckArgType(env, args[PARAM2], napi_function),
1138 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1139 "incorrect parameter types: The type of callback must be function"), "callback invalid");
1140
1141 CHECK_AND_RETURN_LOG(GetNapiPrefInputDeviceChangeCb(args[PARAM2], napiRoutingMgr) == nullptr,
1142 "Do not allow duplicate registration of the same callback");
1143
1144 AudioCapturerInfo captureInfo;
1145 NapiParamUtils::GetAudioCapturerInfo(env, &captureInfo, args[PARAM1]);
1146
1147 CHECK_AND_RETURN_RET_LOG(captureInfo.sourceType != SourceType::SOURCE_TYPE_INVALID,
1148 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1149 "parameter verification failed: The param of sourceType invalid"), "invalid sourceType");
1150
1151 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb =
1152 std::make_shared<NapiAudioPreferredInputDeviceChangeCallback>(env);
1153 CHECK_AND_RETURN_LOG(cb != nullptr, "Memory allocation failed!!");
1154
1155 cb->SaveCallbackReference(args[PARAM2]);
1156 cb->CreatePreferredInTsfn(env);
1157
1158 int32_t ret = napiRoutingMgr->audioRoutingMngr_->SetPreferredInputDeviceChangeCallback(
1159 captureInfo, cb);
1160 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1161 "Registering Preferred Input Device Change Callback Failed %{public}d", ret);
1162
1163 AddPreferredInputDeviceChangeCallback(napiRoutingMgr, cb);
1164 }
1165
RegisterAvaiableDeviceChangeCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1166 void NapiAudioRoutingManager::RegisterAvaiableDeviceChangeCallback(napi_env env, size_t argc, napi_value *args,
1167 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1168 {
1169 int32_t flag = 0;
1170 napi_valuetype valueType = napi_undefined;
1171 napi_typeof(env, args[PARAM1], &valueType);
1172 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowError(env,
1173 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceUsage must be number"),
1174 "invalid Type");
1175
1176 NapiParamUtils::GetValueInt32(env, flag, args[PARAM1]);
1177 AUDIO_INFO_LOG("RegisterDeviceChangeCallback:On deviceFlag: %{public}d", flag);
1178 if (!NapiAudioEnum::IsLegalDeviceUsage(flag)) {
1179 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1180 "parameter verification failed: The param of deviceUsage must be enum DeviceUsage");
1181 }
1182
1183 napi_valuetype handler = napi_undefined;
1184 napi_typeof(env, args[PARAM2], &handler);
1185 if (handler != napi_function) {
1186 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1187 "incorrect parameter types: The type of callback must be function");
1188 }
1189 AudioDeviceUsage usage = static_cast<AudioDeviceUsage>(flag);
1190 if (!napiRoutingMgr->availableDeviceChangeCallbackNapi_) {
1191 napiRoutingMgr->availableDeviceChangeCallbackNapi_ =
1192 std::make_shared<NapiAudioRountingAvailableDeviceChangeCallback>(env);
1193 }
1194 CHECK_AND_RETURN_LOG(napiRoutingMgr->availableDeviceChangeCallbackNapi_ != nullptr,
1195 "RegisterDeviceChangeCallback: Memory Allocation Failed !");
1196
1197 int32_t ret = napiRoutingMgr->audioMngr_->SetAvailableDeviceChangeCallback(usage,
1198 napiRoutingMgr->availableDeviceChangeCallbackNapi_);
1199 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1200 "RegisterDeviceChangeCallback: Registering Device Change Callback Failed %{public}d", ret);
1201
1202 std::shared_ptr<NapiAudioRountingAvailableDeviceChangeCallback> cb =
1203 std::static_pointer_cast<NapiAudioRountingAvailableDeviceChangeCallback>(
1204 napiRoutingMgr->availableDeviceChangeCallbackNapi_);
1205 cb->SaveRoutingAvailbleDeviceChangeCbRef(usage, args[PARAM2]);
1206 if (!cb->GetRouDevChgTsfnFlag()) {
1207 cb->CreateRouDevChgTsfn(env);
1208 }
1209 }
1210
RegisterMicrophoneBlockedCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1211 void NapiAudioRoutingManager::RegisterMicrophoneBlockedCallback(napi_env env, size_t argc, napi_value *args,
1212 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1213 {
1214 napi_valuetype valueType = napi_undefined;
1215 napi_typeof(env, args[PARAM1], &valueType);
1216 if (valueType != napi_function) {
1217 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1218 "parameter verification failed: The param of deviceFlag must be enum DeviceFlag");
1219 }
1220 if (!napiRoutingMgr->microphoneBlockedCallbackNapi_) {
1221 napiRoutingMgr->microphoneBlockedCallbackNapi_ = std::make_shared<NapiAudioManagerCallback>(env);
1222 }
1223 int32_t ret = napiRoutingMgr->audioMngr_->SetMicrophoneBlockedCallback(
1224 napiRoutingMgr->microphoneBlockedCallbackNapi_);
1225 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1226 "Registering micro phone blocked Callback Failed %{public}d", ret);
1227 std::shared_ptr<NapiAudioManagerCallback> cb =
1228 std::static_pointer_cast<NapiAudioManagerCallback>(napiRoutingMgr->microphoneBlockedCallbackNapi_);
1229 cb->SaveMicrophoneBlockedCallbackReference(args[PARAM1]);
1230 if (!cb->GetMicBlockedTsfnFlag()) {
1231 cb->CreateMicBlockedTsfn(env);
1232 }
1233 }
1234
On(napi_env env,napi_callback_info info)1235 napi_value NapiAudioRoutingManager::On(napi_env env, napi_callback_info info)
1236 {
1237 const size_t requireArgc = ARGS_TWO;
1238 const size_t maxArgc = ARGS_THREE;
1239 size_t argc = ARGS_THREE;
1240
1241 napi_value undefinedResult = nullptr;
1242 napi_get_undefined(env, &undefinedResult);
1243
1244 napi_value args[requireArgc + PARAM1] = { nullptr, nullptr, nullptr };
1245 napi_value jsThis = nullptr;
1246 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
1247 bool isArgcCountRight = argc == requireArgc || argc == maxArgc;
1248 CHECK_AND_RETURN_RET_LOG(status == napi_ok && isArgcCountRight, NapiAudioError::ThrowErrorAndReturn(env,
1249 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"),
1250 "status or isArgcCountRight error");
1251
1252 napi_valuetype eventType = napi_undefined;
1253 napi_typeof(env, args[PARAM0], &eventType);
1254 CHECK_AND_RETURN_RET_LOG(eventType == napi_string, NapiAudioError::ThrowErrorAndReturn(env,
1255 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of eventType must be string"),
1256 "eventType is invalid");
1257 std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
1258 AUDIO_INFO_LOG("On callbackName: %{public}s", callbackName.c_str());
1259
1260 if (argc == requireArgc) {
1261 napi_valuetype handler = napi_undefined;
1262 napi_typeof(env, args[PARAM1], &handler);
1263 CHECK_AND_RETURN_RET_LOG(handler == napi_function, NapiAudioError::ThrowErrorAndReturn(env,
1264 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of callback must be function"),
1265 "handler is invalid");
1266 }
1267
1268 return RegisterCallback(env, jsThis, argc, args, callbackName);
1269 }
1270
UnregisterCallback(napi_env env,napi_value jsThis,const std::string & callbackName,napi_value callback)1271 napi_value NapiAudioRoutingManager::UnregisterCallback(napi_env env, napi_value jsThis,
1272 const std::string &callbackName, napi_value callback)
1273 {
1274 napi_value undefinedResult = nullptr;
1275 napi_get_undefined(env, &undefinedResult);
1276 NapiAudioRoutingManager *napiRoutingMgr = nullptr;
1277 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiRoutingMgr));
1278 CHECK_AND_RETURN_RET_LOG(status == napi_ok && napiRoutingMgr != nullptr, undefinedResult,
1279 "Failed to retrieve audio mgr napi instance.");
1280 CHECK_AND_RETURN_RET_LOG(napiRoutingMgr->audioMngr_ != nullptr, undefinedResult,
1281 "audio system mgr instance is null.");
1282 if (!callbackName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
1283 UnregisterDeviceChangeCallback(env, callback, napiRoutingMgr);
1284 } else if (!callbackName.compare(PREFERRED_OUTPUT_DEVICE_CALLBACK_NAME) ||
1285 !callbackName.compare(PREFER_OUTPUT_DEVICE_CALLBACK_NAME)) {
1286 UnregisterPreferredOutputDeviceChangeCallback(env, callback, napiRoutingMgr);
1287 } else if (!callbackName.compare(PREFERRED_INPUT_DEVICE_CALLBACK_NAME)) {
1288 UnregisterPreferredInputDeviceChangeCallback(env, callback, napiRoutingMgr);
1289 } else if (!callbackName.compare(AVAILABLE_DEVICE_CHANGE_CALLBACK_NAME)) {
1290 UnregisterAvailableDeviceChangeCallback(env, callback, napiRoutingMgr);
1291 } else if (!callbackName.compare(MICROPHONE_BLOCKED_CALLBACK_NAME)) {
1292 UnregisterMicrophoneBlockedCallback(env, callback, napiRoutingMgr);
1293 } else {
1294 AUDIO_ERR_LOG("off no such supported");
1295 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1296 "parameter verification failed: The param of type is not supported");
1297 }
1298
1299 return undefinedResult;
1300 }
1301
UnregisterDeviceChangeCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1302 void NapiAudioRoutingManager::UnregisterDeviceChangeCallback(napi_env env, napi_value callback,
1303 NapiAudioRoutingManager *napiRoutingMgr)
1304 {
1305 if (napiRoutingMgr->deviceChangeCallbackNapi_ != nullptr) {
1306 std::shared_ptr<NapiAudioManagerCallback> cb =
1307 std::static_pointer_cast<NapiAudioManagerCallback>(
1308 napiRoutingMgr->deviceChangeCallbackNapi_);
1309 if (callback != nullptr) {
1310 cb->RemoveRoutingManagerDeviceChangeCbRef(env, callback);
1311 }
1312 if (callback == nullptr || cb->GetRoutingManagerDeviceChangeCbListSize() == 0) {
1313 int32_t ret = napiRoutingMgr->audioMngr_->UnsetDeviceChangeCallback(DeviceFlag::ALL_L_D_DEVICES_FLAG,
1314 napiRoutingMgr->deviceChangeCallbackNapi_);
1315 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetDeviceChangeCallback Failed");
1316 napiRoutingMgr->deviceChangeCallbackNapi_.reset();
1317 napiRoutingMgr->deviceChangeCallbackNapi_ = nullptr;
1318
1319 cb->RemoveAllRoutingManagerDeviceChangeCb();
1320 }
1321 } else {
1322 AUDIO_ERR_LOG("UnregisterDeviceChangeCallback: deviceChangeCallbackNapi_ is null");
1323 }
1324 }
1325
RemovePreferredOutputDeviceChangeCallback(NapiAudioRoutingManager * napiRoutingMgr,std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb)1326 void NapiAudioRoutingManager::RemovePreferredOutputDeviceChangeCallback(NapiAudioRoutingManager *napiRoutingMgr,
1327 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb)
1328 {
1329 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredOutputDeviceMutex_);
1330 napiRoutingMgr->preferredOutputDeviceCallbacks_.remove(cb);
1331 }
1332
RemoveAllPrefOutputDeviceChangeCallback(napi_env env,NapiAudioRoutingManager * napiRoutingMgr)1333 void NapiAudioRoutingManager::RemoveAllPrefOutputDeviceChangeCallback(napi_env env,
1334 NapiAudioRoutingManager *napiRoutingMgr)
1335 {
1336 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredOutputDeviceMutex_);
1337 for (auto &iter : napiRoutingMgr->preferredOutputDeviceCallbacks_) {
1338 int32_t ret = napiRoutingMgr->audioRoutingMngr_->UnsetPreferredOutputDeviceChangeCallback(iter);
1339 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1340 "Unset one of preferred output device change callback failed!");
1341 }
1342 napiRoutingMgr->preferredOutputDeviceCallbacks_.clear();
1343 }
1344
UnregisterPreferredOutputDeviceChangeCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1345 void NapiAudioRoutingManager::UnregisterPreferredOutputDeviceChangeCallback(napi_env env, napi_value callback,
1346 NapiAudioRoutingManager *napiRoutingMgr)
1347 {
1348 if (callback != nullptr) {
1349 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb =
1350 GetNapiPrefOutputDeviceChangeCb(callback, napiRoutingMgr);
1351 CHECK_AND_RETURN_LOG(cb != nullptr, "NapiPreferredOutputDeviceCallback is nullptr");
1352 int32_t ret = napiRoutingMgr->audioRoutingMngr_->UnsetPreferredOutputDeviceChangeCallback(cb);
1353 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetPreferredOutputDeviceChangeCallback Failed");
1354
1355 RemovePreferredOutputDeviceChangeCallback(napiRoutingMgr, cb);
1356 return;
1357 }
1358
1359 RemoveAllPrefOutputDeviceChangeCallback(env, napiRoutingMgr);
1360 }
1361
RemovePreferredInputDeviceChangeCallback(NapiAudioRoutingManager * napiRoutingMgr,std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb)1362 void NapiAudioRoutingManager::RemovePreferredInputDeviceChangeCallback(NapiAudioRoutingManager *napiRoutingMgr,
1363 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb)
1364 {
1365 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredInputDeviceMutex_);
1366 napiRoutingMgr->preferredInputDeviceCallbacks_.remove(cb);
1367 }
1368
RemoveAllPrefInputDeviceChangeCallback(napi_env env,NapiAudioRoutingManager * napiRoutingMgr)1369 void NapiAudioRoutingManager::RemoveAllPrefInputDeviceChangeCallback(napi_env env,
1370 NapiAudioRoutingManager *napiRoutingMgr)
1371 {
1372 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredInputDeviceMutex_);
1373 for (auto &iter : napiRoutingMgr->preferredInputDeviceCallbacks_) {
1374 int32_t ret = napiRoutingMgr->audioRoutingMngr_->UnsetPreferredInputDeviceChangeCallback(iter);
1375 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1376 "Unset one of preferred input device change callback failed!");
1377 }
1378 napiRoutingMgr->preferredInputDeviceCallbacks_.clear();
1379 }
1380
UnregisterPreferredInputDeviceChangeCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1381 void NapiAudioRoutingManager::UnregisterPreferredInputDeviceChangeCallback(napi_env env, napi_value callback,
1382 NapiAudioRoutingManager *napiRoutingMgr)
1383 {
1384 if (callback != nullptr) {
1385 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb =
1386 GetNapiPrefInputDeviceChangeCb(callback, napiRoutingMgr);
1387 CHECK_AND_RETURN_LOG(cb != nullptr, "NapiPreferredInputDeviceCallback is nullptr");
1388 int32_t ret = napiRoutingMgr->audioRoutingMngr_->UnsetPreferredInputDeviceChangeCallback(cb);
1389 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetPreferredInputDeviceChangeCallback Failed");
1390
1391 RemovePreferredInputDeviceChangeCallback(napiRoutingMgr, cb);
1392 return;
1393 }
1394
1395 RemoveAllPrefInputDeviceChangeCallback(env, napiRoutingMgr);
1396 }
1397
UnregisterAvailableDeviceChangeCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1398 void NapiAudioRoutingManager::UnregisterAvailableDeviceChangeCallback(napi_env env, napi_value callback,
1399 NapiAudioRoutingManager *napiRoutingMgr)
1400 {
1401 if (napiRoutingMgr->availableDeviceChangeCallbackNapi_ != nullptr) {
1402 std::shared_ptr<NapiAudioRountingAvailableDeviceChangeCallback> cb =
1403 std::static_pointer_cast<NapiAudioRountingAvailableDeviceChangeCallback>(
1404 napiRoutingMgr->availableDeviceChangeCallbackNapi_);
1405 if (callback == nullptr || cb->GetRoutingAvailbleDeviceChangeCbListSize() == 0) {
1406 int32_t ret = napiRoutingMgr->audioMngr_->UnsetAvailableDeviceChangeCallback(D_ALL_DEVICES);
1407 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetAvailableDeviceChangeCallback Failed");
1408
1409 napiRoutingMgr->availableDeviceChangeCallbackNapi_.reset();
1410 napiRoutingMgr->availableDeviceChangeCallbackNapi_ = nullptr;
1411 cb->RemoveAllRoutinAvailbleDeviceChangeCb();
1412 return;
1413 }
1414 cb->RemoveRoutingAvailbleDeviceChangeCbRef(env, callback);
1415 } else {
1416 AUDIO_ERR_LOG("UnregisterAvailableDeviceChangeCallback: availableDeviceChangeCallbackNapi_ is null");
1417 }
1418 }
1419
UnregisterMicrophoneBlockedCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1420 void NapiAudioRoutingManager::UnregisterMicrophoneBlockedCallback(napi_env env, napi_value callback,
1421 NapiAudioRoutingManager *napiRoutingMgr)
1422 {
1423 if (napiRoutingMgr->microphoneBlockedCallbackNapi_ != nullptr) {
1424 std::shared_ptr<NapiAudioManagerCallback> cb =
1425 std::static_pointer_cast<NapiAudioManagerCallback>(
1426 napiRoutingMgr->microphoneBlockedCallbackNapi_);
1427 if (callback == nullptr || cb->GetMicrophoneBlockedCbListSize() == 0) {
1428 int32_t ret = napiRoutingMgr->audioMngr_->UnsetMicrophoneBlockedCallback(
1429 napiRoutingMgr->microphoneBlockedCallbackNapi_);
1430 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetMicrophoneBlockedCallback Failed");
1431 napiRoutingMgr->microphoneBlockedCallbackNapi_.reset();
1432 napiRoutingMgr->microphoneBlockedCallbackNapi_ = nullptr;
1433 cb->RemoveAllMicrophoneBlockedCallback();
1434 return;
1435 }
1436 cb->RemoveMicrophoneBlockedCallbackReference(env, callback);
1437 } else {
1438 AUDIO_ERR_LOG("microphoneBlockedCallbackNapi_ is null");
1439 }
1440 }
1441
Off(napi_env env,napi_callback_info info)1442 napi_value NapiAudioRoutingManager::Off(napi_env env, napi_callback_info info)
1443 {
1444 napi_value undefinedResult = nullptr;
1445 napi_get_undefined(env, &undefinedResult);
1446
1447 const size_t minArgCount = ARGS_ONE;
1448 size_t argCount = ARGS_TWO;
1449 napi_value args[minArgCount + PARAM1] = {nullptr, nullptr};
1450 napi_value jsThis = nullptr;
1451 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
1452 if (status != napi_ok || argCount < minArgCount) {
1453 AUDIO_ERR_LOG("Off fail to napi_get_cb_info/Requires min 1 parameters");
1454 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1455 "mandatory parameters are left unspecified");
1456 return undefinedResult;
1457 }
1458
1459 napi_valuetype eventType = napi_undefined;
1460 if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
1461 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1462 "incorrect parameter types: The type of eventType must be string");
1463 return undefinedResult;
1464 }
1465
1466 napi_valuetype secondArgsType = napi_undefined;
1467 if (argCount > minArgCount &&
1468 (napi_typeof(env, args[PARAM1], &secondArgsType) != napi_ok || secondArgsType != napi_function)) {
1469 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1470 "incorrect parameter types: The type of callback must be function");
1471 return undefinedResult;
1472 }
1473 std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
1474
1475 if (argCount == minArgCount) {
1476 args[PARAM1] = nullptr;
1477 }
1478 AUDIO_INFO_LOG("Off callbackName: %{public}s", callbackName.c_str());
1479
1480 return UnregisterCallback(env, jsThis, callbackName, args[PARAM1]);
1481 }
1482
GetMicrophoneBlockedCbListSize()1483 int32_t NapiAudioManagerCallback::GetMicrophoneBlockedCbListSize()
1484 {
1485 std::lock_guard<std::mutex> lock(mutex_);
1486 return microphoneBlockedCbList_.size();
1487 }
1488
1489 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
IsMicBlockDetectionSupported(napi_env env,napi_callback_info info)1490 napi_value NapiAudioRoutingManager::IsMicBlockDetectionSupported(napi_env env, napi_callback_info info)
1491 {
1492 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
1493 context->GetCbInfo(env, info);
1494 auto executor = [context]() {
1495 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1496 context->supported = OHOS::system::GetBoolParameter("const.multimedia.audio.mic_block_detection", false);
1497 if (context->supported == true) {
1498 AUDIO_INFO_LOG("mic block detection supported");
1499 } else {
1500 AUDIO_ERR_LOG("mic block detection is not supported");
1501 }
1502 };
1503 auto complete = [env, context](napi_value &output) {
1504 NapiParamUtils::SetValueBoolean(env, context->supported, output);
1505 };
1506 return NapiAsyncWork::Enqueue(env, context, "IsMicBlockDetectionSupported", executor, complete);
1507 }
1508 #endif
1509 } // namespace AudioStandard
1510 } // namespace OHOS
1511