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,
395 "Invalid arguments. The number of parameters should be greater than 2.", 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,
398 "Parameter verification failed. AudioCapturerFilter abnormal.", 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 count.", 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 count.", 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 count.", NAPI_ERR_INVALID_PARAM);
520 context->status = NapiParamUtils::GetValueInt32(env, context->deviceType, argv[PARAM0]);
521 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "Invalid arguments type.",
522 NAPI_ERR_INVALID_PARAM);
523 if (!NapiAudioEnum::IsLegalInputArgumentCommunicationDeviceType(context->deviceType)) {
524 context->SignError(context->errCode == NAPI_ERR_INVALID_PARAM?
525 NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED);
526 }
527 context->status = NapiParamUtils::GetValueBoolean(env, context->isActive, argv[PARAM1]);
528 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "Invalid arguments type.",
529 NAPI_ERR_INVALID_PARAM);
530 };
531 context->GetCbInfo(env, info, inputParser);
532
533 auto executor = [context]() {
534 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
535 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
536 ObjectRefMap objectGuard(obj);
537 auto *napiAudioRoutingManager = objectGuard.GetPtr();
538 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
539 "context object state is error.");
540 context->intValue = napiAudioRoutingManager->audioMngr_->SetDeviceActive(
541 static_cast<DeviceType>(context->deviceType), context->isActive);
542 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SelectInputDevice failed",
543 NAPI_ERR_SYSTEM);
544 };
545
546 auto complete = [env](napi_value &output) {
547 output = NapiParamUtils::GetUndefinedValue(env);
548 };
549 return NapiAsyncWork::Enqueue(env, context, "SetCommunicationDevice", executor, complete);
550 }
551
IsCommunicationDeviceActive(napi_env env,napi_callback_info info)552 napi_value NapiAudioRoutingManager::IsCommunicationDeviceActive(napi_env env, napi_callback_info info)
553 {
554 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
555 if (context == nullptr) {
556 AUDIO_ERR_LOG("IsCommunicationDeviceActive failed : no memory");
557 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
558 return NapiParamUtils::GetUndefinedValue(env);
559 }
560
561 auto inputParser = [env, context](size_t argc, napi_value *argv) {
562 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
563 NAPI_ERR_INVALID_PARAM);
564 context->status = NapiParamUtils::GetValueInt32(env, context->deviceType, argv[PARAM0]);
565 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "IsCommunicationDeviceActive failed",
566 NAPI_ERR_INVALID_PARAM);
567 if (!NapiAudioEnum::IsLegalInputArgumentActiveDeviceType(context->deviceType)) {
568 context->SignError(context->errCode == NAPI_ERR_INVALID_PARAM?
569 NAPI_ERR_INVALID_PARAM: NAPI_ERR_UNSUPPORTED);
570 }
571 };
572 context->GetCbInfo(env, info, inputParser);
573
574 auto executor = [context]() {
575 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
576 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
577 ObjectRefMap objectGuard(obj);
578 auto *napiAudioRoutingManager = objectGuard.GetPtr();
579 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
580 "context object state is error.");
581 context->isActive = napiAudioRoutingManager->audioMngr_->IsDeviceActive(
582 static_cast<DeviceType>(context->deviceType));
583 context->isTrue = context->isActive;
584 };
585
586 auto complete = [env, context](napi_value &output) {
587 NapiParamUtils::SetValueBoolean(env, context->isTrue, output);
588 };
589 return NapiAsyncWork::Enqueue(env, context, "IsCommunicationDeviceActive", executor, complete);
590 }
591
IsCommunicationDeviceActiveSync(napi_env env,napi_callback_info info)592 napi_value NapiAudioRoutingManager::IsCommunicationDeviceActiveSync(napi_env env, napi_callback_info info)
593 {
594 napi_value result = nullptr;
595 size_t argc = ARGS_ONE;
596 napi_value argv[ARGS_ONE] = {};
597 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
598 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
599 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argCount invalid");
600
601 napi_valuetype valueType = napi_undefined;
602 napi_typeof(env, argv[PARAM0], &valueType);
603 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
604 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceType must be number"),
605 "valueType invalid");
606
607 int32_t deviceType;
608 napi_status status = NapiParamUtils::GetValueInt32(env, deviceType, argv[PARAM0]);
609 CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentActiveDeviceType(deviceType) && status == napi_ok,
610 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
611 "parameter verification failed: The param of deviceType must be enum CommunicationDeviceType"),
612 "valueType invalid");
613
614 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
615 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioMngr_ != nullptr, result, "audioMngr_ nullptr");
616 bool isActive = napiAudioRoutingManager->audioMngr_->IsDeviceActive(static_cast<DeviceType>(deviceType));
617
618 NapiParamUtils::SetValueBoolean(env, isActive, result);
619 return result;
620 }
621
GetActiveOutputDeviceDescriptors(napi_env env,napi_callback_info info)622 napi_value NapiAudioRoutingManager::GetActiveOutputDeviceDescriptors(napi_env env, napi_callback_info info)
623 {
624 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
625 if (context == nullptr) {
626 AUDIO_ERR_LOG("GetActiveOutputDeviceDescriptors failed : no memory");
627 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
628 return NapiParamUtils::GetUndefinedValue(env);
629 }
630
631 context->GetCbInfo(env, info);
632
633 auto executor = [context]() {
634 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
635 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
636 ObjectRefMap objectGuard(obj);
637 auto *napiAudioRoutingManager = objectGuard.GetPtr();
638 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
639 "context object state is error.");
640 context->outDeviceDescriptors = napiAudioRoutingManager->audioMngr_->GetActiveOutputDeviceDescriptors();
641 };
642
643 auto complete = [env, context](napi_value &output) {
644 NapiParamUtils::SetDeviceDescriptors(env, context->outDeviceDescriptors, output);
645 };
646 return NapiAsyncWork::Enqueue(env, context, "GetActiveOutputDeviceDescriptors", executor, complete);
647 }
648
GetPreferredOutputDeviceForRendererInfo(napi_env env,napi_callback_info info)649 napi_value NapiAudioRoutingManager::GetPreferredOutputDeviceForRendererInfo(napi_env env, napi_callback_info info)
650 {
651 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
652 if (context == nullptr) {
653 AUDIO_ERR_LOG("GetPreferredOutputDeviceForRendererInfo failed : no memory");
654 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
655 return NapiParamUtils::GetUndefinedValue(env);
656 }
657
658 auto inputParser = [env, context](size_t argc, napi_value *argv) {
659 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
660 NAPI_ERR_INPUT_INVALID);
661 context->status = NapiParamUtils::GetRendererInfo(env, &(context->rendererInfo), argv[PARAM0]);
662 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
663 "incorrect parameter types: The type of rendererInfo must be interface AudioRendererInfo",
664 NAPI_ERR_INPUT_INVALID);
665 };
666 context->GetCbInfo(env, info, inputParser);
667 if (context->status != napi_ok) {
668 NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
669 return NapiParamUtils::GetUndefinedValue(env);
670 }
671
672 auto executor = [context]() {
673 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
674 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
675 ObjectRefMap objectGuard(obj);
676 auto *napiAudioRoutingManager = objectGuard.GetPtr();
677 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
678 "context object state is error.");
679 if (context->rendererInfo.streamUsage == StreamUsage::STREAM_USAGE_INVALID) {
680 context->SignError(NAPI_ERR_INVALID_PARAM,
681 "Parameter verification failed. Your usage in AudioRendererInfo is invalid.");
682 } else {
683 context->intValue = napiAudioRoutingManager->audioRoutingMngr_->GetPreferredOutputDeviceForRendererInfo(
684 context->rendererInfo, context->outDeviceDescriptors);
685 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS,
686 "GetPreferredOutputDeviceForRendererInfo failed", NAPI_ERR_SYSTEM);
687 }
688 };
689
690 auto complete = [env, context](napi_value &output) {
691 NapiParamUtils::SetDeviceDescriptors(env, context->outDeviceDescriptors, output);
692 };
693 return NapiAsyncWork::Enqueue(env, context, "GetPreferredOutputDeviceForRendererInfo", executor, complete);
694 }
695
GetPreferOutputDeviceForRendererInfo(napi_env env,napi_callback_info info)696 napi_value NapiAudioRoutingManager::GetPreferOutputDeviceForRendererInfo(napi_env env, napi_callback_info info)
697 {
698 // for api compatibility, leave some time for applications to adapt to new one
699 return GetPreferredOutputDeviceForRendererInfo(env, info);
700 }
701
GetPreferredOutputDeviceForRendererInfoSync(napi_env env,napi_callback_info info)702 napi_value NapiAudioRoutingManager::GetPreferredOutputDeviceForRendererInfoSync(napi_env env, napi_callback_info info)
703 {
704 AUDIO_INFO_LOG("GetPreferredOutputDeviceForRendererInfoSync");
705 napi_value result = nullptr;
706 size_t argc = ARGS_ONE;
707 napi_value argv[ARGS_ONE] = {};
708 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
709 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
710 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argCount invalid");
711
712 napi_valuetype valueType = napi_undefined;
713 napi_typeof(env, argv[PARAM0], &valueType);
714 CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
715 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of rendererInfo must be object"),
716 "valueType invalid");
717
718 AudioRendererInfo rendererInfo;
719 if (NapiParamUtils::GetRendererInfo(env, &rendererInfo, argv[PARAM0]) != napi_ok) {
720 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
721 "incorrect parameter types: The type of rendererInfo must be interface AudioRendererInfo");
722 return result;
723 } else if (rendererInfo.streamUsage == StreamUsage::STREAM_USAGE_INVALID) {
724 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
725 "Parameter verification failed. Your usage in AudioRendererInfo is invalid.");
726 return result;
727 }
728
729 vector<std::shared_ptr<AudioDeviceDescriptor>> outDeviceDescriptors;
730 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
731 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioRoutingMngr_ != nullptr, result,
732 "audioRoutingMngr_ nullptr");
733 napiAudioRoutingManager->audioRoutingMngr_->GetPreferredOutputDeviceForRendererInfo(
734 rendererInfo, outDeviceDescriptors);
735
736 NapiParamUtils::SetDeviceDescriptors(env, outDeviceDescriptors, result);
737
738 return result;
739 }
740
741
GetPreferredOutputDeviceByFilter(napi_env env,napi_callback_info info)742 napi_value NapiAudioRoutingManager::GetPreferredOutputDeviceByFilter(napi_env env, napi_callback_info info)
743 {
744 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
745 if (context == nullptr) {
746 AUDIO_ERR_LOG("GetPreferredOutputDeviceByFilter failed : no memory");
747 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
748 return NapiParamUtils::GetUndefinedValue(env);
749 }
750
751 auto inputParser = [env, context](size_t argc, napi_value *argv) {
752 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "Invalid arguments count.", NAPI_ERR_INVALID_PARAM);
753 context->status = NapiParamUtils::GetAudioRendererFilter(env, context->audioRendererFilter,
754 context->bArgTransFlag, argv[PARAM0]);
755 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
756 "Parameter verification failed. Your usage in AudioRendererFilter is invalid.", NAPI_ERR_INVALID_PARAM);
757 };
758 context->GetCbInfo(env, info, inputParser);
759
760 auto executor = [context]() {
761 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
762 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
763 ObjectRefMap objectGuard(obj);
764 auto *napiAudioRoutingManager = objectGuard.GetPtr();
765 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
766 "context object state is error.");
767 context->deviceDescriptors = napiAudioRoutingManager->audioMngr_->GetOutputDevice(context->audioRendererFilter);
768 };
769 auto complete = [env, context](napi_value &output) {
770 NapiParamUtils::SetDeviceDescriptors(env, context->deviceDescriptors, output);
771 };
772 return NapiAsyncWork::Enqueue(env, context, "GetPreferredOutputDeviceByFilter", executor, complete);
773 }
774
GetPreferredInputDeviceForCapturerInfo(napi_env env,napi_callback_info info)775 napi_value NapiAudioRoutingManager::GetPreferredInputDeviceForCapturerInfo(napi_env env, napi_callback_info info)
776 {
777 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
778 if (context == nullptr) {
779 AUDIO_ERR_LOG("GetPreferredInputDeviceForCapturerInfo failed : no memory");
780 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
781 return NapiParamUtils::GetUndefinedValue(env);
782 }
783
784 auto inputParser = [env, context](size_t argc, napi_value *argv) {
785 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
786 NAPI_ERR_INPUT_INVALID);
787 context->status = NapiParamUtils::GetAudioCapturerInfo(env, &context->captureInfo, argv[PARAM0]);
788 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
789 "incorrect parameter types: The type of capturerInfo must be interface AudioCapturerInfo",
790 NAPI_ERR_INPUT_INVALID);
791 };
792 context->GetCbInfo(env, info, inputParser);
793
794 if (context->status != napi_ok) {
795 NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
796 return NapiParamUtils::GetUndefinedValue(env);
797 }
798
799 auto executor = [context]() {
800 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
801 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
802 ObjectRefMap objectGuard(obj);
803 auto *napiAudioRoutingManager = objectGuard.GetPtr();
804 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
805 "context object state is error.");
806 if (context->captureInfo.sourceType == SourceType::SOURCE_TYPE_INVALID) {
807 context->SignError(NAPI_ERR_INVALID_PARAM,
808 "Parameter verification failed. You source in AudioCapturerInfo is invalid.");
809 } else {
810 context->intValue = napiAudioRoutingManager->audioRoutingMngr_->GetPreferredInputDeviceForCapturerInfo(
811 context->captureInfo, context->inputDeviceDescriptors);
812 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS,
813 "GetPreferredInputDeviceForCapturerInfo failed", NAPI_ERR_SYSTEM);
814 }
815 };
816
817 auto complete = [env, context](napi_value &output) {
818 NapiParamUtils::SetDeviceDescriptors(env, context->inputDeviceDescriptors, output);
819 };
820 return NapiAsyncWork::Enqueue(env, context, "GetPreferredInputDeviceForCapturerInfo", executor, complete);
821 }
822
GetPreferredInputDeviceForCapturerInfoSync(napi_env env,napi_callback_info info)823 napi_value NapiAudioRoutingManager::GetPreferredInputDeviceForCapturerInfoSync(napi_env env, napi_callback_info info)
824 {
825 napi_value result = nullptr;
826 size_t argc = ARGS_ONE;
827 napi_value argv[ARGS_ONE] = {};
828 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
829 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
830 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argCount invalid");
831
832 napi_valuetype valueType = napi_undefined;
833 napi_typeof(env, argv[PARAM0], &valueType);
834 CHECK_AND_RETURN_RET_LOG(valueType == napi_object,
835 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
836 "incorrect parameter types: The type of capturerInfo must be object"), "valueType invalid");
837
838 AudioCapturerInfo capturerInfo;
839 napi_status status = NapiParamUtils::GetAudioCapturerInfo(env, &capturerInfo, argv[PARAM0]);
840 CHECK_AND_RETURN_RET_LOG((capturerInfo.sourceType != SourceType::SOURCE_TYPE_INVALID) && (status == napi_ok),
841 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
842 "Parameter verification failed. AudioCapturerInfo abnormal."), "sourceType invalid");
843
844 vector<std::shared_ptr<AudioDeviceDescriptor>> outDeviceDescriptors;
845 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
846 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioRoutingMngr_ != nullptr, result,
847 "audioRoutingMngr_ nullptr");
848 napiAudioRoutingManager->audioRoutingMngr_->GetPreferredInputDeviceForCapturerInfo(
849 capturerInfo, outDeviceDescriptors);
850
851 NapiParamUtils::SetDeviceDescriptors(env, outDeviceDescriptors, result);
852
853 return result;
854 }
855
GetPreferredInputDeviceByFilter(napi_env env,napi_callback_info info)856 napi_value NapiAudioRoutingManager::GetPreferredInputDeviceByFilter(napi_env env, napi_callback_info info)
857 {
858 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
859 if (context == nullptr) {
860 AUDIO_ERR_LOG("GetPreferredInputDeviceByFilter failed : no memory");
861 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
862 return NapiParamUtils::GetUndefinedValue(env);
863 }
864
865 auto inputParser = [env, context](size_t argc, napi_value *argv) {
866 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "Invalid arguments count.", NAPI_ERR_INVALID_PARAM);
867 context->status = NapiParamUtils::GetAudioCapturerFilter(env, context->audioCapturerFilter, argv[PARAM0]);
868 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
869 "Parameter verification failed. AudioCapturerFilter abnormal.", NAPI_ERR_INVALID_PARAM);
870 };
871 context->GetCbInfo(env, info, inputParser);
872
873 auto executor = [context]() {
874 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
875 auto obj = reinterpret_cast<NapiAudioRoutingManager*>(context->native);
876 ObjectRefMap objectGuard(obj);
877 auto *napiAudioRoutingManager = objectGuard.GetPtr();
878 CHECK_AND_RETURN_LOG(CheckAudioRoutingManagerStatus(napiAudioRoutingManager, context),
879 "context object state is error.");
880 context->deviceDescriptors = napiAudioRoutingManager->audioMngr_->GetInputDevice(context->audioCapturerFilter);
881 };
882 auto complete = [env, context](napi_value &output) {
883 NapiParamUtils::SetDeviceDescriptors(env, context->deviceDescriptors, output);
884 };
885 return NapiAsyncWork::Enqueue(env, context, "GetPreferredInputDeviceByFilter", executor, complete);
886 }
887
GetAvailableMicrophones(napi_env env,napi_callback_info info)888 napi_value NapiAudioRoutingManager::GetAvailableMicrophones(napi_env env, napi_callback_info info)
889 {
890 AUDIO_INFO_LOG("GetAvailableMicrophones");
891 napi_value result = nullptr;
892 size_t argc = PARAM0;
893 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, nullptr);
894 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
895 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argCount invalid");
896 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
897 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioRoutingMngr_ != nullptr, result,
898 "audioRoutingMngr_ is nullptr");
899
900 vector<sptr<MicrophoneDescriptor>> micDescs =
901 napiAudioRoutingManager->audioRoutingMngr_->GetAvailableMicrophones();
902
903 NapiParamUtils::SetMicrophoneDescriptors(env, micDescs, result);
904
905 return result;
906 }
907
GetAvailableDevices(napi_env env,napi_callback_info info)908 napi_value NapiAudioRoutingManager::GetAvailableDevices(napi_env env, napi_callback_info info)
909 {
910 napi_value result = nullptr;
911 size_t argc = ARGS_ONE;
912 napi_value argv[ARGS_ONE] = {};
913 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
914 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
915 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argcCount invalid");
916
917 napi_valuetype valueType = napi_undefined;
918 napi_status status = napi_typeof(env, argv[PARAM0], &valueType);
919 CHECK_AND_RETURN_RET_LOG(status == napi_ok && valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
920 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceUsage must be number"),
921 "valueType invalid");
922
923 int32_t intValue = 0;
924 status = napi_get_value_int32(env, argv[PARAM0], &intValue);
925 CHECK_AND_RETURN_RET_LOG(status == napi_ok && NapiAudioEnum::IsLegalDeviceUsage(intValue),
926 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
927 "parameter verification failed: The param of deviceUsage must be enum DeviceUsage"), "invalid deviceusage");
928
929 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
930 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioRoutingMngr_ != nullptr, result,
931 "audioRoutingMngr_ is nullptr");
932 AudioDeviceUsage usage = static_cast<AudioDeviceUsage>(intValue);
933
934 vector<std::shared_ptr<AudioDeviceDescriptor>> availableDescs =
935 napiAudioRoutingManager->audioRoutingMngr_->GetAvailableDevices(usage);
936
937 vector<std::shared_ptr<AudioDeviceDescriptor>> availableSptrDescs;
938 for (const auto &availableDesc : availableDescs) {
939 std::shared_ptr<AudioDeviceDescriptor> dec = std::make_shared<AudioDeviceDescriptor>(*availableDesc);
940 CHECK_AND_BREAK_LOG(dec != nullptr, "dec mallac failed,no memery.");
941 availableSptrDescs.push_back(dec);
942 }
943 NapiParamUtils::SetDeviceDescriptors(env, availableSptrDescs, result);
944 return result;
945 }
946
GetExcludedDevices(napi_env env,napi_callback_info info)947 napi_value NapiAudioRoutingManager::GetExcludedDevices(napi_env env, napi_callback_info info)
948 {
949 napi_value result = nullptr;
950 size_t argc = ARGS_ONE;
951 napi_value argv[ARGS_ONE] = {};
952 auto *napiAudioRoutingManager = GetParamWithSync(env, info, argc, argv);
953 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager != nullptr, result, "napiAudioRoutingManager is nullptr");
954 CHECK_AND_RETURN_RET_LOG(napiAudioRoutingManager->audioMngr_ != nullptr, result,
955 "audioMngr_ is nullptr");
956 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
957 "mandatory parameters are left unspecified"), "argCount invalid");
958
959 AudioDeviceUsage audioDevUsage;
960 napi_status status = NapiParamUtils::GetAudioDeviceUsage(env, audioDevUsage, argv[PARAM0]);
961 CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
962 "parameter verification failed: The param of deviceUsage must be enum DeviceUsage"),
963 "exclude output devices failed");
964 vector<shared_ptr<AudioDeviceDescriptor>> excludedDevices =
965 napiAudioRoutingManager->audioMngr_->GetExcludedDevices(audioDevUsage);
966 NapiParamUtils::SetDeviceDescriptors(env, excludedDevices, result);
967 return result;
968 }
969
RegisterCallback(napi_env env,napi_value jsThis,size_t argc,napi_value * args,const std::string & cbName)970 napi_value NapiAudioRoutingManager::RegisterCallback(napi_env env, napi_value jsThis, size_t argc,
971 napi_value *args, const std::string &cbName)
972 {
973 napi_value undefinedResult = nullptr;
974 NapiAudioRoutingManager *napiRoutingMgr = nullptr;
975 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void**>(&napiRoutingMgr));
976 if ((status != napi_ok) || (napiRoutingMgr == nullptr) || (napiRoutingMgr->audioMngr_ == nullptr) ||
977 (napiRoutingMgr->audioRoutingMngr_ == nullptr)) {
978 AUDIO_ERR_LOG("NapiAudioRoutingManager::Failed to retrieve stream mgr napi instance.");
979 return undefinedResult;
980 }
981
982 if (!cbName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
983 RegisterDeviceChangeCallback(env, argc, args, cbName, napiRoutingMgr);
984 } else if (!cbName.compare(PREFERRED_OUTPUT_DEVICE_CALLBACK_NAME) ||
985 !cbName.compare(PREFER_OUTPUT_DEVICE_CALLBACK_NAME)) {
986 RegisterPreferredOutputDeviceChangeCallback(env, argc, args, cbName, napiRoutingMgr);
987 } else if (!cbName.compare(PREFERRED_INPUT_DEVICE_CALLBACK_NAME)) {
988 RegisterPreferredInputDeviceChangeCallback(env, argc, args, cbName, napiRoutingMgr);
989 } else if (!cbName.compare(AVAILABLE_DEVICE_CHANGE_CALLBACK_NAME)) {
990 RegisterAvaiableDeviceChangeCallback(env, argc, args, cbName, napiRoutingMgr);
991 } else if (!cbName.compare(MICROPHONE_BLOCKED_CALLBACK_NAME)) {
992 RegisterMicrophoneBlockedCallback(env, argc, args, cbName, napiRoutingMgr);
993 } else {
994 AUDIO_ERR_LOG("NapiAudioRoutingManager::No such supported");
995 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
996 "parameter verification failed: The param of type is not supported");
997 }
998 return undefinedResult;
999 }
1000
RegisterDeviceChangeCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1001 void NapiAudioRoutingManager::RegisterDeviceChangeCallback(napi_env env, size_t argc, napi_value *args,
1002 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1003 {
1004 int32_t flag = ARGS_THREE;
1005 napi_valuetype valueType = napi_undefined;
1006 napi_typeof(env, args[PARAM1], &valueType);
1007 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowError(env,
1008 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceFlag must be number"),
1009 "invalid valueType");
1010 if (valueType == napi_number) {
1011 NapiParamUtils::GetValueInt32(env, flag, args[PARAM1]);
1012 AUDIO_INFO_LOG("RegisterDeviceChangeCallback:On deviceFlag: %{public}d", flag);
1013 if (!NapiAudioEnum::IsLegalInputArgumentDeviceFlag(flag)) {
1014 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1015 "parameter verification failed: The param of deviceFlag must be enum DeviceFlag");
1016 }
1017 }
1018
1019 napi_valuetype handler = napi_undefined;
1020 napi_typeof(env, args[PARAM2], &handler);
1021
1022 if (handler != napi_function) {
1023 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1024 "incorrect parameter types: The type of callback must be function");
1025 }
1026 DeviceFlag deviceFlag = DeviceFlag(flag);
1027 if (!napiRoutingMgr->deviceChangeCallbackNapi_) {
1028 napiRoutingMgr->deviceChangeCallbackNapi_ = std::make_shared<NapiAudioManagerCallback>(env);
1029 }
1030 CHECK_AND_RETURN_LOG(napiRoutingMgr->deviceChangeCallbackNapi_,
1031 "RegisterDeviceChangeCallback: Memory Allocation Failed !");
1032
1033 int32_t ret = napiRoutingMgr->audioMngr_->SetDeviceChangeCallback(deviceFlag,
1034 napiRoutingMgr->deviceChangeCallbackNapi_);
1035 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1036 "RegisterDeviceChangeCallback: Registering Device Change Callback Failed %{public}d", ret);
1037
1038 std::shared_ptr<NapiAudioManagerCallback> cb =
1039 std::static_pointer_cast<NapiAudioManagerCallback>(napiRoutingMgr->deviceChangeCallbackNapi_);
1040 cb->SaveRoutingManagerDeviceChangeCbRef(deviceFlag, args[PARAM2]);
1041 if (!cb->GetDevChgTsfnFlag()) {
1042 cb->CreateDevChgTsfn(env);
1043 }
1044 }
1045
GetNapiPrefOutputDeviceChangeCb(napi_value args,NapiAudioRoutingManager * napiRoutingMgr)1046 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> NapiAudioRoutingManager::GetNapiPrefOutputDeviceChangeCb(
1047 napi_value args, NapiAudioRoutingManager *napiRoutingMgr)
1048 {
1049 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredOutputDeviceMutex_);
1050 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb = nullptr;
1051 for (auto &iter : napiRoutingMgr->preferredOutputDeviceCallbacks_) {
1052 if (iter->ContainSameJsCallback(args)) {
1053 cb = iter;
1054 }
1055 }
1056 return cb;
1057 }
1058
AddPreferredOutputDeviceChangeCallback(NapiAudioRoutingManager * napiRoutingMgr,std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb)1059 void NapiAudioRoutingManager::AddPreferredOutputDeviceChangeCallback(NapiAudioRoutingManager *napiRoutingMgr,
1060 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb)
1061 {
1062 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredOutputDeviceMutex_);
1063 napiRoutingMgr->preferredOutputDeviceCallbacks_.push_back(cb);
1064 }
1065
RegisterPreferredOutputDeviceChangeCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1066 void NapiAudioRoutingManager::RegisterPreferredOutputDeviceChangeCallback(napi_env env, size_t argc, napi_value *args,
1067 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1068 {
1069 CHECK_AND_RETURN_RET_LOG(argc == ARGS_THREE, NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1070 "incorrect number of parameters: expected at least 3 parameters"), "argc invalid");
1071
1072 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::CheckArgType(env, args[PARAM1], napi_object),
1073 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1074 "incorrect parameter types: The type of rendererInfo must be object"), "rendererInfo invalid");
1075
1076 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::CheckArgType(env, args[PARAM2], napi_function),
1077 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1078 "incorrect parameter types: The type of callback must be function"), "callback invalid");
1079
1080 CHECK_AND_RETURN_LOG(GetNapiPrefOutputDeviceChangeCb(args[PARAM2], napiRoutingMgr) == nullptr,
1081 "Do not allow duplicate registration of the same callback");
1082
1083 AudioRendererInfo rendererInfo;
1084 NapiParamUtils::GetRendererInfo(env, &rendererInfo, args[PARAM1]);
1085 CHECK_AND_RETURN_RET_LOG(rendererInfo.streamUsage != StreamUsage::STREAM_USAGE_INVALID,
1086 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1087 "Parameter verification failed. Your usage in AudioRendererInfo is invalid."), "invalid streamUsage");
1088 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb =
1089 std::make_shared<NapiAudioPreferredOutputDeviceChangeCallback>(env);
1090 CHECK_AND_RETURN_LOG(cb != nullptr, "Memory allocation failed!!");
1091
1092 cb->SaveCallbackReference(args[PARAM2]);
1093 cb->CreatePreferredOutTsfn(env);
1094
1095 int32_t ret = napiRoutingMgr->audioRoutingMngr_->SetPreferredOutputDeviceChangeCallback(
1096 rendererInfo, cb);
1097 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1098 "Registering Preferred Output Device Change Callback Failed %{public}d", ret);
1099
1100 AddPreferredOutputDeviceChangeCallback(napiRoutingMgr, cb);
1101 }
1102
GetNapiPrefInputDeviceChangeCb(napi_value args,NapiAudioRoutingManager * napiRoutingMgr)1103 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> NapiAudioRoutingManager::GetNapiPrefInputDeviceChangeCb(
1104 napi_value args, NapiAudioRoutingManager *napiRoutingMgr)
1105 {
1106 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredInputDeviceMutex_);
1107 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb = nullptr;
1108 for (auto &iter : napiRoutingMgr->preferredInputDeviceCallbacks_) {
1109 if (iter->ContainSameJsCallback(args)) {
1110 cb = iter;
1111 }
1112 }
1113 return cb;
1114 }
1115
AddPreferredInputDeviceChangeCallback(NapiAudioRoutingManager * napiRoutingMgr,std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb)1116 void NapiAudioRoutingManager::AddPreferredInputDeviceChangeCallback(NapiAudioRoutingManager *napiRoutingMgr,
1117 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb)
1118 {
1119 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredInputDeviceMutex_);
1120 napiRoutingMgr->preferredInputDeviceCallbacks_.push_back(cb);
1121 }
1122
RegisterPreferredInputDeviceChangeCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1123 void NapiAudioRoutingManager::RegisterPreferredInputDeviceChangeCallback(napi_env env, size_t argc, napi_value *args,
1124 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1125 {
1126 CHECK_AND_RETURN_RET_LOG(argc >= ARGS_THREE, NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1127 "mandatory parameters are left unspecified"), "argCount invalid");
1128
1129 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::CheckArgType(env, args[PARAM1], napi_object),
1130 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1131 "incorrect parameter types: The type of capturerInfo must be object"), "capturerInfo invalid");
1132
1133 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::CheckArgType(env, args[PARAM2], napi_function),
1134 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1135 "incorrect parameter types: The type of callback must be function"), "callback invalid");
1136
1137 CHECK_AND_RETURN_LOG(GetNapiPrefInputDeviceChangeCb(args[PARAM2], napiRoutingMgr) == nullptr,
1138 "Do not allow duplicate registration of the same callback");
1139
1140 AudioCapturerInfo captureInfo;
1141 NapiParamUtils::GetAudioCapturerInfo(env, &captureInfo, args[PARAM1]);
1142
1143 CHECK_AND_RETURN_RET_LOG(captureInfo.sourceType != SourceType::SOURCE_TYPE_INVALID,
1144 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1145 "Parameter verification failed. Your source in AudioCapturerInfo is invalid."), "invalid sourceType");
1146
1147 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb =
1148 std::make_shared<NapiAudioPreferredInputDeviceChangeCallback>(env);
1149 CHECK_AND_RETURN_LOG(cb != nullptr, "Memory allocation failed!!");
1150
1151 cb->SaveCallbackReference(args[PARAM2]);
1152 cb->CreatePreferredInTsfn(env);
1153
1154 int32_t ret = napiRoutingMgr->audioRoutingMngr_->SetPreferredInputDeviceChangeCallback(
1155 captureInfo, cb);
1156 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1157 "Registering Preferred Input Device Change Callback Failed %{public}d", ret);
1158
1159 AddPreferredInputDeviceChangeCallback(napiRoutingMgr, cb);
1160 }
1161
RegisterAvaiableDeviceChangeCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1162 void NapiAudioRoutingManager::RegisterAvaiableDeviceChangeCallback(napi_env env, size_t argc, napi_value *args,
1163 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1164 {
1165 int32_t flag = 0;
1166 napi_valuetype valueType = napi_undefined;
1167 napi_typeof(env, args[PARAM1], &valueType);
1168 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowError(env,
1169 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceUsage must be number"),
1170 "invalid Type");
1171
1172 NapiParamUtils::GetValueInt32(env, flag, args[PARAM1]);
1173 AUDIO_INFO_LOG("RegisterDeviceChangeCallback:On deviceFlag: %{public}d", flag);
1174 if (!NapiAudioEnum::IsLegalDeviceUsage(flag)) {
1175 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1176 "parameter verification failed: The param of deviceUsage must be enum DeviceUsage");
1177 }
1178
1179 napi_valuetype handler = napi_undefined;
1180 napi_typeof(env, args[PARAM2], &handler);
1181 if (handler != napi_function) {
1182 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1183 "incorrect parameter types: The type of callback must be function");
1184 }
1185 AudioDeviceUsage usage = static_cast<AudioDeviceUsage>(flag);
1186 if (!napiRoutingMgr->availableDeviceChangeCallbackNapi_) {
1187 napiRoutingMgr->availableDeviceChangeCallbackNapi_ =
1188 std::make_shared<NapiAudioRountingAvailableDeviceChangeCallback>(env);
1189 }
1190 CHECK_AND_RETURN_LOG(napiRoutingMgr->availableDeviceChangeCallbackNapi_ != nullptr,
1191 "RegisterDeviceChangeCallback: Memory Allocation Failed !");
1192
1193 int32_t ret = napiRoutingMgr->audioMngr_->SetAvailableDeviceChangeCallback(usage,
1194 napiRoutingMgr->availableDeviceChangeCallbackNapi_);
1195 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1196 "RegisterDeviceChangeCallback: Registering Device Change Callback Failed %{public}d", ret);
1197
1198 std::shared_ptr<NapiAudioRountingAvailableDeviceChangeCallback> cb =
1199 std::static_pointer_cast<NapiAudioRountingAvailableDeviceChangeCallback>(
1200 napiRoutingMgr->availableDeviceChangeCallbackNapi_);
1201 cb->SaveRoutingAvailbleDeviceChangeCbRef(usage, args[PARAM2]);
1202 if (!cb->GetRouDevChgTsfnFlag()) {
1203 cb->CreateRouDevChgTsfn(env);
1204 }
1205 }
1206
RegisterMicrophoneBlockedCallback(napi_env env,size_t argc,napi_value * args,const std::string & cbName,NapiAudioRoutingManager * napiRoutingMgr)1207 void NapiAudioRoutingManager::RegisterMicrophoneBlockedCallback(napi_env env, size_t argc, napi_value *args,
1208 const std::string &cbName, NapiAudioRoutingManager *napiRoutingMgr)
1209 {
1210 napi_valuetype valueType = napi_undefined;
1211 napi_typeof(env, args[PARAM1], &valueType);
1212 if (valueType != napi_function) {
1213 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1214 "parameter verification failed: The param of deviceFlag must be enum DeviceFlag");
1215 }
1216 if (!napiRoutingMgr->microphoneBlockedCallbackNapi_) {
1217 napiRoutingMgr->microphoneBlockedCallbackNapi_ = std::make_shared<NapiAudioManagerCallback>(env);
1218 }
1219 int32_t ret = napiRoutingMgr->audioMngr_->SetMicrophoneBlockedCallback(
1220 napiRoutingMgr->microphoneBlockedCallbackNapi_);
1221 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1222 "Registering micro phone blocked Callback Failed %{public}d", ret);
1223 std::shared_ptr<NapiAudioManagerCallback> cb =
1224 std::static_pointer_cast<NapiAudioManagerCallback>(napiRoutingMgr->microphoneBlockedCallbackNapi_);
1225 cb->SaveMicrophoneBlockedCallbackReference(args[PARAM1]);
1226 if (!cb->GetMicBlockedTsfnFlag()) {
1227 cb->CreateMicBlockedTsfn(env);
1228 }
1229 }
1230
On(napi_env env,napi_callback_info info)1231 napi_value NapiAudioRoutingManager::On(napi_env env, napi_callback_info info)
1232 {
1233 const size_t requireArgc = ARGS_TWO;
1234 const size_t maxArgc = ARGS_THREE;
1235 size_t argc = ARGS_THREE;
1236
1237 napi_value undefinedResult = nullptr;
1238 napi_get_undefined(env, &undefinedResult);
1239
1240 napi_value args[requireArgc + PARAM1] = { nullptr, nullptr, nullptr };
1241 napi_value jsThis = nullptr;
1242 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
1243 bool isArgcCountRight = argc == requireArgc || argc == maxArgc;
1244 CHECK_AND_RETURN_RET_LOG(status == napi_ok && isArgcCountRight, NapiAudioError::ThrowErrorAndReturn(env,
1245 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"),
1246 "status or isArgcCountRight error");
1247
1248 napi_valuetype eventType = napi_undefined;
1249 napi_typeof(env, args[PARAM0], &eventType);
1250 CHECK_AND_RETURN_RET_LOG(eventType == napi_string, NapiAudioError::ThrowErrorAndReturn(env,
1251 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of eventType must be string"),
1252 "eventType is invalid");
1253 std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
1254 AUDIO_INFO_LOG("On callbackName: %{public}s", callbackName.c_str());
1255
1256 if (argc == requireArgc) {
1257 napi_valuetype handler = napi_undefined;
1258 napi_typeof(env, args[PARAM1], &handler);
1259 CHECK_AND_RETURN_RET_LOG(handler == napi_function, NapiAudioError::ThrowErrorAndReturn(env,
1260 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of callback must be function"),
1261 "handler is invalid");
1262 }
1263
1264 return RegisterCallback(env, jsThis, argc, args, callbackName);
1265 }
1266
UnregisterCallback(napi_env env,napi_value jsThis,const std::string & callbackName,napi_value callback)1267 napi_value NapiAudioRoutingManager::UnregisterCallback(napi_env env, napi_value jsThis,
1268 const std::string &callbackName, napi_value callback)
1269 {
1270 napi_value undefinedResult = nullptr;
1271 napi_get_undefined(env, &undefinedResult);
1272 NapiAudioRoutingManager *napiRoutingMgr = nullptr;
1273 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiRoutingMgr));
1274 CHECK_AND_RETURN_RET_LOG(status == napi_ok && napiRoutingMgr != nullptr, undefinedResult,
1275 "Failed to retrieve audio mgr napi instance.");
1276 CHECK_AND_RETURN_RET_LOG(napiRoutingMgr->audioMngr_ != nullptr, undefinedResult,
1277 "audio system mgr instance is null.");
1278 if (!callbackName.compare(DEVICE_CHANGE_CALLBACK_NAME)) {
1279 UnregisterDeviceChangeCallback(env, callback, napiRoutingMgr);
1280 } else if (!callbackName.compare(PREFERRED_OUTPUT_DEVICE_CALLBACK_NAME) ||
1281 !callbackName.compare(PREFER_OUTPUT_DEVICE_CALLBACK_NAME)) {
1282 UnregisterPreferredOutputDeviceChangeCallback(env, callback, napiRoutingMgr);
1283 } else if (!callbackName.compare(PREFERRED_INPUT_DEVICE_CALLBACK_NAME)) {
1284 UnregisterPreferredInputDeviceChangeCallback(env, callback, napiRoutingMgr);
1285 } else if (!callbackName.compare(AVAILABLE_DEVICE_CHANGE_CALLBACK_NAME)) {
1286 UnregisterAvailableDeviceChangeCallback(env, callback, napiRoutingMgr);
1287 } else if (!callbackName.compare(MICROPHONE_BLOCKED_CALLBACK_NAME)) {
1288 UnregisterMicrophoneBlockedCallback(env, callback, napiRoutingMgr);
1289 } else {
1290 AUDIO_ERR_LOG("off no such supported");
1291 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1292 "parameter verification failed: The param of type is not supported");
1293 }
1294
1295 return undefinedResult;
1296 }
1297
UnregisterDeviceChangeCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1298 void NapiAudioRoutingManager::UnregisterDeviceChangeCallback(napi_env env, napi_value callback,
1299 NapiAudioRoutingManager *napiRoutingMgr)
1300 {
1301 if (napiRoutingMgr->deviceChangeCallbackNapi_ != nullptr) {
1302 std::shared_ptr<NapiAudioManagerCallback> cb =
1303 std::static_pointer_cast<NapiAudioManagerCallback>(
1304 napiRoutingMgr->deviceChangeCallbackNapi_);
1305 if (callback != nullptr) {
1306 cb->RemoveRoutingManagerDeviceChangeCbRef(env, callback);
1307 }
1308 if (callback == nullptr || cb->GetRoutingManagerDeviceChangeCbListSize() == 0) {
1309 int32_t ret = napiRoutingMgr->audioMngr_->UnsetDeviceChangeCallback(DeviceFlag::ALL_L_D_DEVICES_FLAG,
1310 napiRoutingMgr->deviceChangeCallbackNapi_);
1311 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetDeviceChangeCallback Failed");
1312 napiRoutingMgr->deviceChangeCallbackNapi_.reset();
1313 napiRoutingMgr->deviceChangeCallbackNapi_ = nullptr;
1314
1315 cb->RemoveAllRoutingManagerDeviceChangeCb();
1316 }
1317 } else {
1318 AUDIO_ERR_LOG("UnregisterDeviceChangeCallback: deviceChangeCallbackNapi_ is null");
1319 }
1320 }
1321
RemovePreferredOutputDeviceChangeCallback(NapiAudioRoutingManager * napiRoutingMgr,std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb)1322 void NapiAudioRoutingManager::RemovePreferredOutputDeviceChangeCallback(NapiAudioRoutingManager *napiRoutingMgr,
1323 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb)
1324 {
1325 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredOutputDeviceMutex_);
1326 napiRoutingMgr->preferredOutputDeviceCallbacks_.remove(cb);
1327 }
1328
RemoveAllPrefOutputDeviceChangeCallback(napi_env env,NapiAudioRoutingManager * napiRoutingMgr)1329 void NapiAudioRoutingManager::RemoveAllPrefOutputDeviceChangeCallback(napi_env env,
1330 NapiAudioRoutingManager *napiRoutingMgr)
1331 {
1332 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredOutputDeviceMutex_);
1333 for (auto &iter : napiRoutingMgr->preferredOutputDeviceCallbacks_) {
1334 int32_t ret = napiRoutingMgr->audioRoutingMngr_->UnsetPreferredOutputDeviceChangeCallback(iter);
1335 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1336 "Unset one of preferred output device change callback failed!");
1337 }
1338 napiRoutingMgr->preferredOutputDeviceCallbacks_.clear();
1339 }
1340
UnregisterPreferredOutputDeviceChangeCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1341 void NapiAudioRoutingManager::UnregisterPreferredOutputDeviceChangeCallback(napi_env env, napi_value callback,
1342 NapiAudioRoutingManager *napiRoutingMgr)
1343 {
1344 if (callback != nullptr) {
1345 std::shared_ptr<NapiAudioPreferredOutputDeviceChangeCallback> cb =
1346 GetNapiPrefOutputDeviceChangeCb(callback, napiRoutingMgr);
1347 CHECK_AND_RETURN_LOG(cb != nullptr, "NapiPreferredOutputDeviceCallback is nullptr");
1348 int32_t ret = napiRoutingMgr->audioRoutingMngr_->UnsetPreferredOutputDeviceChangeCallback(cb);
1349 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetPreferredOutputDeviceChangeCallback Failed");
1350
1351 RemovePreferredOutputDeviceChangeCallback(napiRoutingMgr, cb);
1352 return;
1353 }
1354
1355 RemoveAllPrefOutputDeviceChangeCallback(env, napiRoutingMgr);
1356 }
1357
RemovePreferredInputDeviceChangeCallback(NapiAudioRoutingManager * napiRoutingMgr,std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb)1358 void NapiAudioRoutingManager::RemovePreferredInputDeviceChangeCallback(NapiAudioRoutingManager *napiRoutingMgr,
1359 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb)
1360 {
1361 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredInputDeviceMutex_);
1362 napiRoutingMgr->preferredInputDeviceCallbacks_.remove(cb);
1363 }
1364
RemoveAllPrefInputDeviceChangeCallback(napi_env env,NapiAudioRoutingManager * napiRoutingMgr)1365 void NapiAudioRoutingManager::RemoveAllPrefInputDeviceChangeCallback(napi_env env,
1366 NapiAudioRoutingManager *napiRoutingMgr)
1367 {
1368 std::lock_guard<std::mutex> lock(napiRoutingMgr->preferredInputDeviceMutex_);
1369 for (auto &iter : napiRoutingMgr->preferredInputDeviceCallbacks_) {
1370 int32_t ret = napiRoutingMgr->audioRoutingMngr_->UnsetPreferredInputDeviceChangeCallback(iter);
1371 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowError(env, ret),
1372 "Unset one of preferred input device change callback failed!");
1373 }
1374 napiRoutingMgr->preferredInputDeviceCallbacks_.clear();
1375 }
1376
UnregisterPreferredInputDeviceChangeCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1377 void NapiAudioRoutingManager::UnregisterPreferredInputDeviceChangeCallback(napi_env env, napi_value callback,
1378 NapiAudioRoutingManager *napiRoutingMgr)
1379 {
1380 if (callback != nullptr) {
1381 std::shared_ptr<NapiAudioPreferredInputDeviceChangeCallback> cb =
1382 GetNapiPrefInputDeviceChangeCb(callback, napiRoutingMgr);
1383 CHECK_AND_RETURN_LOG(cb != nullptr, "NapiPreferredInputDeviceCallback is nullptr");
1384 int32_t ret = napiRoutingMgr->audioRoutingMngr_->UnsetPreferredInputDeviceChangeCallback(cb);
1385 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetPreferredInputDeviceChangeCallback Failed");
1386
1387 RemovePreferredInputDeviceChangeCallback(napiRoutingMgr, cb);
1388 return;
1389 }
1390
1391 RemoveAllPrefInputDeviceChangeCallback(env, napiRoutingMgr);
1392 }
1393
UnregisterAvailableDeviceChangeCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1394 void NapiAudioRoutingManager::UnregisterAvailableDeviceChangeCallback(napi_env env, napi_value callback,
1395 NapiAudioRoutingManager *napiRoutingMgr)
1396 {
1397 if (napiRoutingMgr->availableDeviceChangeCallbackNapi_ != nullptr) {
1398 std::shared_ptr<NapiAudioRountingAvailableDeviceChangeCallback> cb =
1399 std::static_pointer_cast<NapiAudioRountingAvailableDeviceChangeCallback>(
1400 napiRoutingMgr->availableDeviceChangeCallbackNapi_);
1401 if (callback == nullptr || cb->GetRoutingAvailbleDeviceChangeCbListSize() == 0) {
1402 int32_t ret = napiRoutingMgr->audioMngr_->UnsetAvailableDeviceChangeCallback(D_ALL_DEVICES);
1403 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetAvailableDeviceChangeCallback Failed");
1404
1405 napiRoutingMgr->availableDeviceChangeCallbackNapi_.reset();
1406 napiRoutingMgr->availableDeviceChangeCallbackNapi_ = nullptr;
1407 cb->RemoveAllRoutinAvailbleDeviceChangeCb();
1408 return;
1409 }
1410 cb->RemoveRoutingAvailbleDeviceChangeCbRef(env, callback);
1411 } else {
1412 AUDIO_ERR_LOG("UnregisterAvailableDeviceChangeCallback: availableDeviceChangeCallbackNapi_ is null");
1413 }
1414 }
1415
UnregisterMicrophoneBlockedCallback(napi_env env,napi_value callback,NapiAudioRoutingManager * napiRoutingMgr)1416 void NapiAudioRoutingManager::UnregisterMicrophoneBlockedCallback(napi_env env, napi_value callback,
1417 NapiAudioRoutingManager *napiRoutingMgr)
1418 {
1419 if (napiRoutingMgr->microphoneBlockedCallbackNapi_ != nullptr) {
1420 std::shared_ptr<NapiAudioManagerCallback> cb =
1421 std::static_pointer_cast<NapiAudioManagerCallback>(
1422 napiRoutingMgr->microphoneBlockedCallbackNapi_);
1423 if (callback == nullptr || cb->GetMicrophoneBlockedCbListSize() == 0) {
1424 int32_t ret = napiRoutingMgr->audioMngr_->UnsetMicrophoneBlockedCallback(
1425 napiRoutingMgr->microphoneBlockedCallbackNapi_);
1426 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnsetMicrophoneBlockedCallback Failed");
1427 napiRoutingMgr->microphoneBlockedCallbackNapi_.reset();
1428 napiRoutingMgr->microphoneBlockedCallbackNapi_ = nullptr;
1429 cb->RemoveAllMicrophoneBlockedCallback();
1430 return;
1431 }
1432 cb->RemoveMicrophoneBlockedCallbackReference(env, callback);
1433 } else {
1434 AUDIO_ERR_LOG("microphoneBlockedCallbackNapi_ is null");
1435 }
1436 }
1437
Off(napi_env env,napi_callback_info info)1438 napi_value NapiAudioRoutingManager::Off(napi_env env, napi_callback_info info)
1439 {
1440 napi_value undefinedResult = nullptr;
1441 napi_get_undefined(env, &undefinedResult);
1442
1443 const size_t minArgCount = ARGS_ONE;
1444 size_t argCount = ARGS_TWO;
1445 napi_value args[minArgCount + PARAM1] = {nullptr, nullptr};
1446 napi_value jsThis = nullptr;
1447 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
1448 if (status != napi_ok || argCount < minArgCount) {
1449 AUDIO_ERR_LOG("Off fail to napi_get_cb_info/Requires min 1 parameters");
1450 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1451 "mandatory parameters are left unspecified");
1452 return undefinedResult;
1453 }
1454
1455 napi_valuetype eventType = napi_undefined;
1456 if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
1457 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1458 "incorrect parameter types: The type of eventType must be string");
1459 return undefinedResult;
1460 }
1461
1462 napi_valuetype secondArgsType = napi_undefined;
1463 if (argCount > minArgCount &&
1464 (napi_typeof(env, args[PARAM1], &secondArgsType) != napi_ok || secondArgsType != napi_function)) {
1465 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
1466 "incorrect parameter types: The type of callback must be function");
1467 return undefinedResult;
1468 }
1469 std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
1470
1471 if (argCount == minArgCount) {
1472 args[PARAM1] = nullptr;
1473 }
1474 AUDIO_INFO_LOG("Off callbackName: %{public}s", callbackName.c_str());
1475
1476 return UnregisterCallback(env, jsThis, callbackName, args[PARAM1]);
1477 }
1478
GetMicrophoneBlockedCbListSize()1479 int32_t NapiAudioManagerCallback::GetMicrophoneBlockedCbListSize()
1480 {
1481 std::lock_guard<std::mutex> lock(mutex_);
1482 return microphoneBlockedCbList_.size();
1483 }
1484
1485 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
IsMicBlockDetectionSupported(napi_env env,napi_callback_info info)1486 napi_value NapiAudioRoutingManager::IsMicBlockDetectionSupported(napi_env env, napi_callback_info info)
1487 {
1488 auto context = std::make_shared<AudioRoutingManagerAsyncContext>();
1489 context->GetCbInfo(env, info);
1490 auto executor = [context]() {
1491 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1492 context->supported = OHOS::system::GetBoolParameter("const.multimedia.audio.mic_block_detection", false);
1493 if (context->supported == true) {
1494 AUDIO_INFO_LOG("mic block detection supported");
1495 } else {
1496 AUDIO_ERR_LOG("mic block detection is not supported");
1497 }
1498 };
1499 auto complete = [env, context](napi_value &output) {
1500 NapiParamUtils::SetValueBoolean(env, context->supported, output);
1501 };
1502 return NapiAsyncWork::Enqueue(env, context, "IsMicBlockDetectionSupported", executor, complete);
1503 }
1504 #endif
1505 } // namespace AudioStandard
1506 } // namespace OHOS
1507