1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "audio_stream_mgr_napi.h"
17
18 #include "audio_common_napi.h"
19 #include "audio_errors.h"
20 #include "audio_log.h"
21 #include "hilog/log.h"
22 #include "napi_base_context.h"
23 #include "audio_capturer_state_callback_napi.h"
24 #include "audio_renderer_state_callback_napi.h"
25
26 using namespace std;
27 using OHOS::HiviewDFX::HiLog;
28 using OHOS::HiviewDFX::HiLogLabel;
29
30 namespace OHOS {
31 namespace AudioStandard {
32 static __thread napi_ref g_streamMgrConstructor = nullptr;
33
34 namespace {
35 const std::string RENDERERCHANGE_CALLBACK_NAME = "audioRendererChange";
36 const std::string CAPTURERCHANGE_CALLBACK_NAME = "audioCapturerChange";
37
38 const int ARGS_ONE = 1;
39 const int ARGS_TWO = 2;
40
41 const int PARAM0 = 0;
42 const int PARAM1 = 1;
43 const int PARAM2 = 2;
44 const int PARAM3 = 3;
45
46 constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AudioStreamManagerNapi"};
47
48 #define GET_PARAMS(env, info, num) \
49 size_t argc = num; \
50 napi_value argv[num] = {0}; \
51 napi_value thisVar = nullptr; \
52 void *data; \
53 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)
54 }
55
AudioStreamMgrNapi()56 AudioStreamMgrNapi::AudioStreamMgrNapi()
57 : env_(nullptr), audioStreamMngr_(nullptr) {}
58
59 AudioStreamMgrNapi::~AudioStreamMgrNapi() = default;
60
Destructor(napi_env env,void * nativeObject,void * finalize_hint)61 void AudioStreamMgrNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
62 {
63 if (nativeObject != nullptr) {
64 auto obj = static_cast<AudioStreamMgrNapi *>(nativeObject);
65 delete obj;
66 obj = nullptr;
67 }
68 }
69
70
GetNativeAudioVolumeType(int32_t volumeType)71 static AudioVolumeType GetNativeAudioVolumeType(int32_t volumeType)
72 {
73 AudioVolumeType result = STREAM_MUSIC;
74
75 switch (volumeType) {
76 case AudioManagerNapi::VOICE_CALL:
77 result = STREAM_VOICE_CALL;
78 break;
79 case AudioManagerNapi::RINGTONE:
80 result = STREAM_RING;
81 break;
82 case AudioManagerNapi::MEDIA:
83 result = STREAM_MUSIC;
84 break;
85 case AudioManagerNapi::ALARM:
86 result = STREAM_ALARM;
87 break;
88 case AudioManagerNapi::ACCESSIBILITY:
89 result = STREAM_ACCESSIBILITY;
90 break;
91 case AudioManagerNapi::VOICE_ASSISTANT:
92 result = STREAM_VOICE_ASSISTANT;
93 break;
94 case AudioManagerNapi::ULTRASONIC:
95 result = STREAM_ULTRASONIC;
96 break;
97 case AudioManagerNapi::ALL:
98 result = STREAM_ALL;
99 break;
100 default:
101 result = STREAM_MUSIC;
102 HiLog::Error(LABEL, "Unknown volume type, Set it to default MEDIA!");
103 break;
104 }
105
106 return result;
107 }
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int intValue,napi_value & result)108 static void SetValueInt32(const napi_env& env, const std::string& fieldStr, const int intValue, napi_value &result)
109 {
110 napi_value value = nullptr;
111 napi_create_int32(env, intValue, &value);
112 napi_set_named_property(env, result, fieldStr.c_str(), value);
113 }
114
SetValueString(const napi_env & env,const std::string & fieldStr,const std::string stringValue,napi_value & result)115 static void SetValueString(const napi_env &env, const std::string &fieldStr, const std::string stringValue,
116 napi_value &result)
117 {
118 napi_value value = nullptr;
119 napi_create_string_utf8(env, stringValue.c_str(), NAPI_AUTO_LENGTH, &value);
120 napi_set_named_property(env, result, fieldStr.c_str(), value);
121 }
122
SetDeviceDescriptors(const napi_env & env,napi_value & jsChangeInfoObj,const DeviceInfo & deviceInfo)123 static void SetDeviceDescriptors(const napi_env& env, napi_value &jsChangeInfoObj, const DeviceInfo &deviceInfo)
124 {
125 napi_value jsDeviceDescriptorsObj = nullptr;
126 napi_value valueParam = nullptr;
127 napi_create_array_with_length(env, 1, &jsDeviceDescriptorsObj);
128
129 (void)napi_create_object(env, &valueParam);
130 SetValueInt32(env, "deviceRole", static_cast<int32_t>(deviceInfo.deviceRole), valueParam);
131 SetValueInt32(env, "deviceType", static_cast<int32_t>(deviceInfo.deviceType), valueParam);
132 SetValueInt32(env, "id", static_cast<int32_t>(deviceInfo.deviceId), valueParam);
133 SetValueString(env, "name", deviceInfo.deviceName, valueParam);
134 SetValueString(env, "address", deviceInfo.macAddress, valueParam);
135 SetValueString(env, "networkId", deviceInfo.networkId, valueParam);
136 SetValueString(env, "displayName", deviceInfo.displayName, valueParam);
137 SetValueInt32(env, "interruptGroupId", static_cast<int32_t>(deviceInfo.interruptGroupId), valueParam);
138 SetValueInt32(env, "volumeGroupId", static_cast<int32_t>(deviceInfo.volumeGroupId), valueParam);
139
140 napi_value value = nullptr;
141 napi_value sampleRates;
142 napi_create_array_with_length(env, 1, &sampleRates);
143 napi_create_int32(env, deviceInfo.audioStreamInfo.samplingRate, &value);
144 napi_set_element(env, sampleRates, 0, value);
145 napi_set_named_property(env, valueParam, "sampleRates", sampleRates);
146
147 napi_value channelCounts;
148 napi_create_array_with_length(env, 1, &channelCounts);
149 napi_create_int32(env, deviceInfo.audioStreamInfo.channels, &value);
150 napi_set_element(env, channelCounts, 0, value);
151 napi_set_named_property(env, valueParam, "channelCounts", channelCounts);
152
153 napi_value channelMasks;
154 napi_create_array_with_length(env, 1, &channelMasks);
155 napi_create_int32(env, deviceInfo.channelMasks, &value);
156 napi_set_element(env, channelMasks, 0, value);
157 napi_set_named_property(env, valueParam, "channelMasks", channelMasks);
158
159 napi_set_element(env, jsDeviceDescriptorsObj, 0, valueParam);
160 napi_set_named_property(env, jsChangeInfoObj, "deviceDescriptors", jsDeviceDescriptorsObj);
161 }
162
GetCurrentRendererChangeInfosCallbackComplete(napi_env env,napi_status status,void * data)163 void AudioStreamMgrNapi::GetCurrentRendererChangeInfosCallbackComplete(napi_env env, napi_status status, void *data)
164 {
165 auto asyncContext = static_cast<AudioStreamMgrAsyncContext*>(data);
166 napi_value result[ARGS_TWO] = {0};
167 napi_value jsChangeInfoObj = nullptr;
168 napi_value jsRenInfoObj = nullptr;
169 napi_value retVal;
170
171 size_t size = asyncContext->audioRendererChangeInfos.size();
172 int32_t position = 0;
173
174 napi_create_array_with_length(env, size, &result[PARAM1]);
175 for (const unique_ptr<AudioRendererChangeInfo> &changeInfo: asyncContext->audioRendererChangeInfos) {
176 if (!changeInfo) {
177 AUDIO_ERR_LOG("AudioStreamMgrNapi:AudioRendererChangeInfo Null, something wrong!!");
178 continue;
179 }
180
181 napi_create_object(env, &jsChangeInfoObj);
182 SetValueInt32(env, "streamId", changeInfo->sessionId, jsChangeInfoObj);
183 SetValueInt32(env, "rendererState", static_cast<int32_t>(changeInfo->rendererState), jsChangeInfoObj);
184 SetValueInt32(env, "clientUid", changeInfo->clientUID, jsChangeInfoObj);
185
186 napi_create_object(env, &jsRenInfoObj);
187 SetValueInt32(env, "content", static_cast<int32_t>(changeInfo->rendererInfo.contentType), jsRenInfoObj);
188 SetValueInt32(env, "usage", static_cast<int32_t>(changeInfo->rendererInfo.streamUsage), jsRenInfoObj);
189 SetValueInt32(env, "rendererFlags", changeInfo->rendererInfo.rendererFlags, jsRenInfoObj);
190 napi_set_named_property(env, jsChangeInfoObj, "rendererInfo", jsRenInfoObj);
191 SetDeviceDescriptors(env, jsChangeInfoObj, changeInfo->outputDeviceInfo);
192
193 napi_set_element(env, result[PARAM1], position, jsChangeInfoObj);
194 position++;
195 }
196
197 napi_get_undefined(env, &result[PARAM0]);
198
199 if (asyncContext->deferred) {
200 napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]);
201 } else {
202 napi_value callback = nullptr;
203 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
204 napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
205 napi_delete_reference(env, asyncContext->callbackRef);
206 }
207 napi_delete_async_work(env, asyncContext->work);
208
209 delete asyncContext;
210 }
211
GetCurrentCapturerChangeInfosCallbackComplete(napi_env env,napi_status status,void * data)212 void AudioStreamMgrNapi::GetCurrentCapturerChangeInfosCallbackComplete(napi_env env, napi_status status, void *data)
213 {
214 auto asyncContext = static_cast<AudioStreamMgrAsyncContext*>(data);
215 napi_value result[ARGS_TWO] = {0};
216 napi_value jsChangeInfoObj = nullptr;
217 napi_value jsCapInfoObj = nullptr;
218 napi_value retVal;
219
220 size_t size = asyncContext->audioCapturerChangeInfos.size();
221 int32_t position = 0;
222
223 napi_create_array_with_length(env, size, &result[PARAM1]);
224 for (const unique_ptr<AudioCapturerChangeInfo> &changeInfo: asyncContext->audioCapturerChangeInfos) {
225 if (!changeInfo) {
226 AUDIO_ERR_LOG("AudioStreamMgrNapi:AudioCapturerChangeInfo Null, something wrong!!");
227 continue;
228 }
229
230 napi_create_object(env, &jsChangeInfoObj);
231 SetValueInt32(env, "streamId", changeInfo->sessionId, jsChangeInfoObj);
232 SetValueInt32(env, "capturerState", static_cast<int32_t>(changeInfo->capturerState), jsChangeInfoObj);
233 SetValueInt32(env, "clientUid", changeInfo->clientUID, jsChangeInfoObj);
234
235 napi_create_object(env, &jsCapInfoObj);
236 SetValueInt32(env, "source", static_cast<int32_t>(changeInfo->capturerInfo.sourceType), jsCapInfoObj);
237 SetValueInt32(env, "capturerFlags", changeInfo->capturerInfo.capturerFlags, jsCapInfoObj);
238 napi_set_named_property(env, jsChangeInfoObj, "capturerInfo", jsCapInfoObj);
239 SetDeviceDescriptors(env, jsChangeInfoObj, changeInfo->inputDeviceInfo);
240
241 napi_set_element(env, result[PARAM1], position, jsChangeInfoObj);
242 position++;
243 }
244
245 napi_get_undefined(env, &result[PARAM0]);
246
247 if (asyncContext->deferred) {
248 napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]);
249 } else {
250 napi_value callback = nullptr;
251 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
252 napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
253 napi_delete_reference(env, asyncContext->callbackRef);
254 }
255 napi_delete_async_work(env, asyncContext->work);
256
257 delete asyncContext;
258 }
259
Init(napi_env env,napi_value exports)260 napi_value AudioStreamMgrNapi::Init(napi_env env, napi_value exports)
261 {
262 AUDIO_INFO_LOG("Init");
263 napi_status status;
264 napi_value constructor;
265 napi_value result = nullptr;
266 const int32_t refCount = 1;
267 napi_get_undefined(env, &result);
268
269 napi_property_descriptor audio_stream_mgr_properties[] = {
270 DECLARE_NAPI_FUNCTION("on", On),
271 DECLARE_NAPI_FUNCTION("off", Off),
272 DECLARE_NAPI_FUNCTION("getCurrentAudioRendererInfoArray", GetCurrentAudioRendererInfos),
273 DECLARE_NAPI_FUNCTION("getCurrentAudioRendererInfoArraySync", GetCurrentAudioRendererInfosSync),
274 DECLARE_NAPI_FUNCTION("getCurrentAudioCapturerInfoArray", GetCurrentAudioCapturerInfos),
275 DECLARE_NAPI_FUNCTION("getCurrentAudioCapturerInfoArraySync", GetCurrentAudioCapturerInfosSync),
276 DECLARE_NAPI_FUNCTION("isAudioRendererLowLatencySupported", IsAudioRendererLowLatencySupported),
277 DECLARE_NAPI_FUNCTION("isActive", IsStreamActive),
278 DECLARE_NAPI_FUNCTION("isActiveSync", IsStreamActiveSync),
279 DECLARE_NAPI_FUNCTION("getAudioEffectInfoArray", GetEffectInfoArray),
280 DECLARE_NAPI_FUNCTION("getAudioEffectInfoArraySync", GetEffectInfoArraySync),
281 };
282
283 status = napi_define_class(env, AUDIO_STREAM_MGR_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct, nullptr,
284 sizeof(audio_stream_mgr_properties) / sizeof(audio_stream_mgr_properties[PARAM0]),
285 audio_stream_mgr_properties, &constructor);
286 if (status != napi_ok) {
287 return result;
288 }
289
290 status = napi_create_reference(env, constructor, refCount, &g_streamMgrConstructor);
291 if (status == napi_ok) {
292 status = napi_set_named_property(env, exports, AUDIO_STREAM_MGR_NAPI_CLASS_NAME.c_str(), constructor);
293 if (status == napi_ok) {
294 return exports;
295 }
296 }
297
298 HiLog::Error(LABEL, "Failure in AudioStreamMgrNapi::Init()");
299 return result;
300 }
301
CreateStreamManagerWrapper(napi_env env)302 napi_value AudioStreamMgrNapi::CreateStreamManagerWrapper(napi_env env)
303 {
304 napi_status status;
305 napi_value result = nullptr;
306 napi_value constructor;
307
308 status = napi_get_reference_value(env, g_streamMgrConstructor, &constructor);
309 if (status == napi_ok) {
310 status = napi_new_instance(env, constructor, 0, nullptr, &result);
311 if (status == napi_ok) {
312 return result;
313 }
314 }
315 HiLog::Error(LABEL, "Failed in AudioStreamManagerNapi::CreateStreamMngrWrapper!");
316 napi_get_undefined(env, &result);
317
318 return result;
319 }
320
Construct(napi_env env,napi_callback_info info)321 napi_value AudioStreamMgrNapi::Construct(napi_env env, napi_callback_info info)
322 {
323 AUDIO_INFO_LOG("Construct");
324 napi_status status;
325 napi_value result = nullptr;
326 napi_get_undefined(env, &result);
327
328 GET_PARAMS(env, info, ARGS_TWO);
329
330 unique_ptr<AudioStreamMgrNapi> streamMgrNapi = make_unique<AudioStreamMgrNapi>();
331 CHECK_AND_RETURN_RET_LOG(streamMgrNapi != nullptr, result, "No memory");
332
333 streamMgrNapi->env_ = env;
334 streamMgrNapi->audioStreamMngr_ = AudioStreamManager::GetInstance();
335 streamMgrNapi->cachedClientId_ = getpid();
336
337 status = napi_wrap(env, thisVar, static_cast<void*>(streamMgrNapi.get()),
338 AudioStreamMgrNapi::Destructor, nullptr, nullptr);
339 if (status == napi_ok) {
340 streamMgrNapi.release();
341 return thisVar;
342 }
343
344 HiLog::Error(LABEL, "Failed in AudioStreamManager::Construct()!");
345 return result;
346 }
347
RegisterRendererStateChangeCallback(napi_env env,napi_value * args,const std::string & cbName,AudioStreamMgrNapi * streamMgrNapi)348 void AudioStreamMgrNapi::RegisterRendererStateChangeCallback(napi_env env, napi_value* args,
349 const std::string& cbName, AudioStreamMgrNapi *streamMgrNapi)
350 {
351 if (!streamMgrNapi->rendererStateChangeCallbackNapi_) {
352 streamMgrNapi->rendererStateChangeCallbackNapi_ = std::make_shared<AudioRendererStateCallbackNapi>(env);
353 if (!streamMgrNapi->rendererStateChangeCallbackNapi_) {
354 AUDIO_ERR_LOG("AudioStreamMgrNapi: Memory Allocation Failed !!");
355 return;
356 }
357
358 int32_t ret =
359 streamMgrNapi->audioStreamMngr_->RegisterAudioRendererEventListener(streamMgrNapi->cachedClientId_,
360 streamMgrNapi->rendererStateChangeCallbackNapi_);
361 if (ret) {
362 AUDIO_ERR_LOG("AudioStreamMgrNapi: Registering of Renderer State Change Callback Failed");
363 return;
364 }
365 }
366
367 std::shared_ptr<AudioRendererStateCallbackNapi> cb =
368 std::static_pointer_cast<AudioRendererStateCallbackNapi>(streamMgrNapi->rendererStateChangeCallbackNapi_);
369 cb->SaveCallbackReference(args[PARAM1]);
370
371 AUDIO_INFO_LOG("OnRendererStateChangeCallback is successful");
372 }
373
RegisterCapturerStateChangeCallback(napi_env env,napi_value * args,const std::string & cbName,AudioStreamMgrNapi * streamMgrNapi)374 void AudioStreamMgrNapi::RegisterCapturerStateChangeCallback(napi_env env, napi_value* args,
375 const std::string& cbName, AudioStreamMgrNapi *streamMgrNapi)
376 {
377 if (!streamMgrNapi->capturerStateChangeCallbackNapi_) {
378 streamMgrNapi->capturerStateChangeCallbackNapi_ = std::make_shared<AudioCapturerStateCallbackNapi>(env);
379 if (!streamMgrNapi->capturerStateChangeCallbackNapi_) {
380 AUDIO_ERR_LOG("Memory Allocation Failed !!");
381 return;
382 }
383
384 int32_t ret =
385 streamMgrNapi->audioStreamMngr_->RegisterAudioCapturerEventListener(streamMgrNapi->cachedClientId_,
386 streamMgrNapi->capturerStateChangeCallbackNapi_);
387 if (ret) {
388 AUDIO_ERR_LOG("Registering of Capturer State Change Callback Failed");
389 return;
390 }
391 }
392
393 std::shared_ptr<AudioCapturerStateCallbackNapi> cb =
394 std::static_pointer_cast<AudioCapturerStateCallbackNapi>(streamMgrNapi->capturerStateChangeCallbackNapi_);
395 cb->SaveCallbackReference(args[PARAM1]);
396
397 AUDIO_INFO_LOG("OnCapturerStateChangeCallback is successful");
398 }
399
RegisterCallback(napi_env env,napi_value jsThis,napi_value * args,const std::string & cbName)400 void AudioStreamMgrNapi::RegisterCallback(napi_env env, napi_value jsThis,
401 napi_value* args, const std::string& cbName)
402 {
403 AudioStreamMgrNapi *streamMgrNapi = nullptr;
404 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&streamMgrNapi));
405 if ((status != napi_ok) || (streamMgrNapi == nullptr) || (streamMgrNapi->audioStreamMngr_ == nullptr)) {
406 AUDIO_ERR_LOG("AudioStreamMgrNapi::Failed to retrieve stream mgr napi instance.");
407 return;
408 }
409
410 if (!cbName.compare(RENDERERCHANGE_CALLBACK_NAME)) {
411 RegisterRendererStateChangeCallback(env, args, cbName, streamMgrNapi);
412 } else if (!cbName.compare(CAPTURERCHANGE_CALLBACK_NAME)) {
413 RegisterCapturerStateChangeCallback(env, args, cbName, streamMgrNapi);
414 } else {
415 AUDIO_ERR_LOG("AudioStreamMgrNapi::No such callback supported");
416 AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
417 }
418 }
419
On(napi_env env,napi_callback_info info)420 napi_value AudioStreamMgrNapi::On(napi_env env, napi_callback_info info)
421 {
422 const size_t requireArgc = PARAM2;
423 size_t argc = PARAM3;
424
425 napi_value undefinedResult = nullptr;
426 napi_get_undefined(env, &undefinedResult);
427
428 napi_value args[requireArgc + 1] = {nullptr, nullptr, nullptr};
429 napi_value jsThis = nullptr;
430 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
431 THROW_ERROR_ASSERT(env, status == napi_ok && argc == requireArgc, NAPI_ERR_INPUT_INVALID);
432
433 napi_valuetype eventType = napi_undefined;
434 napi_typeof(env, args[0], &eventType);
435 THROW_ERROR_ASSERT(env, eventType == napi_string, NAPI_ERR_INPUT_INVALID);
436
437 std::string callbackName = AudioCommonNapi::GetStringArgument(env, args[0]);
438 AUDIO_DEBUG_LOG("AudioStreamMgrNapi: On callbackName: %{public}s", callbackName.c_str());
439
440 napi_valuetype handler = napi_undefined;
441
442 napi_typeof(env, args[1], &handler);
443 THROW_ERROR_ASSERT(env, handler == napi_function, NAPI_ERR_INPUT_INVALID);
444
445 RegisterCallback(env, jsThis, args, callbackName);
446
447 return undefinedResult;
448 }
449
UnregisterCallback(napi_env env,napi_value jsThis,const std::string & cbName)450 void AudioStreamMgrNapi::UnregisterCallback(napi_env env, napi_value jsThis, const std::string& cbName)
451 {
452 AUDIO_INFO_LOG("UnregisterCallback");
453 AudioStreamMgrNapi *streamMgrNapi = nullptr;
454 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&streamMgrNapi));
455 if ((status != napi_ok) || (streamMgrNapi == nullptr) || (streamMgrNapi->audioStreamMngr_ == nullptr)) {
456 AUDIO_ERR_LOG("Failed to retrieve stream mgr napi instance.");
457 return;
458 }
459
460 if (!cbName.compare(RENDERERCHANGE_CALLBACK_NAME)) {
461 int32_t ret = streamMgrNapi->audioStreamMngr_->
462 UnregisterAudioRendererEventListener(streamMgrNapi->cachedClientId_);
463 if (ret) {
464 AUDIO_ERR_LOG("UnRegistering of Renderer State Change Callback Failed");
465 return;
466 }
467 if (streamMgrNapi->rendererStateChangeCallbackNapi_ != nullptr) {
468 std::shared_ptr<AudioRendererStateCallbackNapi> cb =
469 std::static_pointer_cast<AudioRendererStateCallbackNapi>(streamMgrNapi->
470 rendererStateChangeCallbackNapi_);
471 cb->RemoveCallbackReference();
472 streamMgrNapi->rendererStateChangeCallbackNapi_.reset();
473 }
474 AUDIO_INFO_LOG("UnRegistering of renderer State Change Callback successful");
475 } else if (!cbName.compare(CAPTURERCHANGE_CALLBACK_NAME)) {
476 int32_t ret = streamMgrNapi->audioStreamMngr_->
477 UnregisterAudioCapturerEventListener(streamMgrNapi->cachedClientId_);
478 if (ret) {
479 AUDIO_ERR_LOG("UnRegistering of capturer State Change Callback Failed");
480 return;
481 }
482 if (streamMgrNapi->capturerStateChangeCallbackNapi_ != nullptr) {
483 streamMgrNapi->capturerStateChangeCallbackNapi_.reset();
484 streamMgrNapi->capturerStateChangeCallbackNapi_ = nullptr;
485 }
486 AUDIO_INFO_LOG("UnRegistering of capturer State Change Callback successful");
487 } else {
488 AUDIO_ERR_LOG("No such callback supported");
489 AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
490 }
491 }
492
Off(napi_env env,napi_callback_info info)493 napi_value AudioStreamMgrNapi::Off(napi_env env, napi_callback_info info)
494 {
495 const size_t requireArgc = 1;
496 size_t argc = 1;
497
498 napi_value undefinedResult = nullptr;
499 napi_get_undefined(env, &undefinedResult);
500
501 napi_value args[requireArgc] = {nullptr};
502 napi_value jsThis = nullptr;
503 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
504 THROW_ERROR_ASSERT(env, status == napi_ok && argc >= requireArgc, NAPI_ERR_INPUT_INVALID);
505
506 napi_valuetype eventType = napi_undefined;
507 napi_typeof(env, args[0], &eventType);
508 THROW_ERROR_ASSERT(env, eventType == napi_string, NAPI_ERR_INPUT_INVALID);
509
510 std::string callbackName = AudioCommonNapi::GetStringArgument(env, args[0]);
511 AUDIO_DEBUG_LOG("AudioStreamMgrNapi: Off callbackName: %{public}s", callbackName.c_str());
512
513 UnregisterCallback(env, jsThis, callbackName);
514 return undefinedResult;
515 }
516
GetCurrentAudioRendererInfos(napi_env env,napi_callback_info info)517 napi_value AudioStreamMgrNapi::GetCurrentAudioRendererInfos(napi_env env, napi_callback_info info)
518 {
519 napi_status status;
520 const int32_t refCount = 1;
521 napi_value result = nullptr;
522
523 GET_PARAMS(env, info, ARGS_ONE);
524
525 unique_ptr<AudioStreamMgrAsyncContext> asyncContext = make_unique<AudioStreamMgrAsyncContext>();
526 if (!asyncContext) {
527 AUDIO_ERR_LOG("AudioStreamMgrNapi:Audio manager async context failed");
528 return result;
529 }
530
531 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
532 if ((status == napi_ok && asyncContext->objectInfo != nullptr)
533 && (asyncContext->objectInfo->audioStreamMngr_ != nullptr)) {
534 for (size_t i = PARAM0; i < argc; i++) {
535 napi_valuetype valueType = napi_undefined;
536 napi_typeof(env, argv[i], &valueType);
537
538 if (i == PARAM0) {
539 if (valueType == napi_function) {
540 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
541 }
542 break;
543 } else {
544 asyncContext->status = NAPI_ERR_INVALID_PARAM;
545 }
546 }
547
548 if (asyncContext->callbackRef == nullptr) {
549 napi_create_promise(env, &asyncContext->deferred, &result);
550 } else {
551 napi_get_undefined(env, &result);
552 }
553
554 napi_value resource = nullptr;
555 napi_create_string_utf8(env, "getCurrentAudioRendererInfoArray", NAPI_AUTO_LENGTH, &resource);
556
557 status = napi_create_async_work(
558 env, nullptr, resource,
559 [](napi_env env, void *data) {
560 auto context = static_cast<AudioStreamMgrAsyncContext *>(data);
561 if (context->status == SUCCESS) {
562 context->status = context->objectInfo->audioStreamMngr_->
563 GetCurrentRendererChangeInfos(context->audioRendererChangeInfos);
564 context->status = context->status == SUCCESS ? SUCCESS : NAPI_ERR_SYSTEM;
565 }
566 },
567 GetCurrentRendererChangeInfosCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
568 if (status != napi_ok) {
569 result = nullptr;
570 } else {
571 status = napi_queue_async_work(env, asyncContext->work);
572 if (status == napi_ok) {
573 asyncContext.release();
574 } else {
575 result = nullptr;
576 }
577 }
578 }
579
580 return result;
581 }
582
GetCurrentAudioRendererInfosSync(napi_env env,napi_callback_info info)583 napi_value AudioStreamMgrNapi::GetCurrentAudioRendererInfosSync(napi_env env, napi_callback_info info)
584 {
585 napi_status status;
586 napi_value thisVar = nullptr;
587 napi_value result = nullptr;
588 size_t argCount = 0;
589 void *native = nullptr;
590
591 status = napi_get_cb_info(env, info, &argCount, nullptr, &thisVar, nullptr);
592 if (status != napi_ok) {
593 AUDIO_ERR_LOG("Invalid parameters!");
594 return result;
595 }
596
597 status = napi_unwrap(env, thisVar, &native);
598 auto *audioStreamMgrNapi = reinterpret_cast<AudioStreamMgrNapi *>(native);
599 if (status != napi_ok || audioStreamMgrNapi == nullptr) {
600 AUDIO_ERR_LOG("GetCurrentAudioRendererInfosSync unwrap failure!");
601 return result;
602 }
603
604 vector<std::unique_ptr<AudioRendererChangeInfo>> audioRendererChangeInfos;
605 int32_t ret = audioStreamMgrNapi->audioStreamMngr_->GetCurrentRendererChangeInfos(audioRendererChangeInfos);
606 if (ret != AUDIO_OK) {
607 AUDIO_ERR_LOG("GetCurrentRendererChangeInfos failure!");
608 return result;
609 }
610
611 napi_value jsChangeInfoObj = nullptr;
612 napi_value jsRenInfoObj = nullptr;
613
614 int32_t position = 0;
615 napi_create_array_with_length(env, audioRendererChangeInfos.size(), &result);
616 for (const unique_ptr<AudioRendererChangeInfo> &changeInfo: audioRendererChangeInfos) {
617 if (!changeInfo) {
618 AUDIO_ERR_LOG("AudioStreamMgrNapi:AudioRendererChangeInfo Null, something wrong!!");
619 continue;
620 }
621
622 napi_create_object(env, &jsChangeInfoObj);
623 SetValueInt32(env, "streamId", changeInfo->sessionId, jsChangeInfoObj);
624 SetValueInt32(env, "rendererState", static_cast<int32_t>(changeInfo->rendererState), jsChangeInfoObj);
625 SetValueInt32(env, "clientUid", changeInfo->clientUID, jsChangeInfoObj);
626
627 napi_create_object(env, &jsRenInfoObj);
628 SetValueInt32(env, "content", static_cast<int32_t>(changeInfo->rendererInfo.contentType), jsRenInfoObj);
629 SetValueInt32(env, "usage", static_cast<int32_t>(changeInfo->rendererInfo.streamUsage), jsRenInfoObj);
630 SetValueInt32(env, "rendererFlags", changeInfo->rendererInfo.rendererFlags, jsRenInfoObj);
631 napi_set_named_property(env, jsChangeInfoObj, "rendererInfo", jsRenInfoObj);
632 SetDeviceDescriptors(env, jsChangeInfoObj, changeInfo->outputDeviceInfo);
633
634 napi_set_element(env, result, position, jsChangeInfoObj);
635 position++;
636 }
637
638 return result;
639 }
640
GetCurrentAudioCapturerInfos(napi_env env,napi_callback_info info)641 napi_value AudioStreamMgrNapi::GetCurrentAudioCapturerInfos(napi_env env, napi_callback_info info)
642 {
643 napi_status status;
644 const int32_t refCount = 1;
645 napi_value result = nullptr;
646
647 GET_PARAMS(env, info, ARGS_ONE);
648
649 unique_ptr<AudioStreamMgrAsyncContext> asyncContext = make_unique<AudioStreamMgrAsyncContext>();
650 if (!asyncContext) {
651 AUDIO_ERR_LOG("AudioStreamMgrNapi:async context memory alloc failed");
652 return result;
653 }
654
655 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
656 if ((status == napi_ok && asyncContext->objectInfo != nullptr)
657 && (asyncContext->objectInfo->audioStreamMngr_ != nullptr)) {
658 for (size_t i = PARAM0; i < argc; i++) {
659 napi_valuetype valueType = napi_undefined;
660 napi_typeof(env, argv[i], &valueType);
661
662 if (i == PARAM0) {
663 if (valueType == napi_function) {
664 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
665 }
666 break;
667 } else {
668 asyncContext->status = NAPI_ERR_INVALID_PARAM;
669 }
670 }
671
672 if (asyncContext->callbackRef == nullptr) {
673 napi_create_promise(env, &asyncContext->deferred, &result);
674 } else {
675 napi_get_undefined(env, &result);
676 }
677
678 napi_value resource = nullptr;
679 napi_create_string_utf8(env, "getCurrentAudioCapturerInfoArray", NAPI_AUTO_LENGTH, &resource);
680
681 status = napi_create_async_work(
682 env, nullptr, resource,
683 [](napi_env env, void *data) {
684 auto context = static_cast<AudioStreamMgrAsyncContext*>(data);
685 if (context->status == SUCCESS) {
686 context->objectInfo->audioStreamMngr_->
687 GetCurrentCapturerChangeInfos(context->audioCapturerChangeInfos);
688 context->status = SUCCESS;
689 }
690 },
691 GetCurrentCapturerChangeInfosCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
692 if (status != napi_ok) {
693 result = nullptr;
694 } else {
695 status = napi_queue_async_work(env, asyncContext->work);
696 if (status == napi_ok) {
697 asyncContext.release();
698 } else {
699 result = nullptr;
700 }
701 }
702 }
703
704 return result;
705 }
706
GetCurrentAudioCapturerInfosSync(napi_env env,napi_callback_info info)707 napi_value AudioStreamMgrNapi::GetCurrentAudioCapturerInfosSync(napi_env env, napi_callback_info info)
708 {
709 napi_status status;
710 napi_value thisVar = nullptr;
711 napi_value result = nullptr;
712 size_t argCount = 0;
713 void *native = nullptr;
714
715 status = napi_get_cb_info(env, info, &argCount, nullptr, &thisVar, nullptr);
716 if (status != napi_ok) {
717 AUDIO_ERR_LOG("Invalid parameters!");
718 return result;
719 }
720
721 status = napi_unwrap(env, thisVar, &native);
722 auto *audioStreamMgrNapi = reinterpret_cast<AudioStreamMgrNapi *>(native);
723 if (status != napi_ok || audioStreamMgrNapi == nullptr) {
724 AUDIO_ERR_LOG("GetCurrentAudioCapturerInfosSync unwrap failure!");
725 return result;
726 }
727
728 vector<std::unique_ptr<AudioCapturerChangeInfo>> audioCapturerChangeInfos;
729 int32_t ret = audioStreamMgrNapi->audioStreamMngr_->GetCurrentCapturerChangeInfos(audioCapturerChangeInfos);
730 if (ret != AUDIO_OK) {
731 AUDIO_ERR_LOG("GetCurrentCapturerChangeInfos failure!");
732 return result;
733 }
734
735 napi_value jsChangeInfoObj = nullptr;
736 napi_value jsCapInfoObj = nullptr;
737
738 int32_t position = 0;
739 napi_create_array_with_length(env, audioCapturerChangeInfos.size(), &result);
740 for (const unique_ptr<AudioCapturerChangeInfo> &changeInfo: audioCapturerChangeInfos) {
741 if (!changeInfo) {
742 AUDIO_ERR_LOG("AudioCapturerChangeInfo Null, something wrong!!");
743 continue;
744 }
745
746 napi_create_object(env, &jsChangeInfoObj);
747 SetValueInt32(env, "streamId", changeInfo->sessionId, jsChangeInfoObj);
748 SetValueInt32(env, "capturerState", static_cast<int32_t>(changeInfo->capturerState), jsChangeInfoObj);
749 SetValueInt32(env, "clientUid", changeInfo->clientUID, jsChangeInfoObj);
750
751 napi_create_object(env, &jsCapInfoObj);
752 SetValueInt32(env, "source", static_cast<int32_t>(changeInfo->capturerInfo.sourceType), jsCapInfoObj);
753 SetValueInt32(env, "capturerFlags", changeInfo->capturerInfo.capturerFlags, jsCapInfoObj);
754 napi_set_named_property(env, jsChangeInfoObj, "capturerInfo", jsCapInfoObj);
755 SetDeviceDescriptors(env, jsChangeInfoObj, changeInfo->inputDeviceInfo);
756
757 napi_set_element(env, result, position, jsChangeInfoObj);
758 position++;
759 }
760
761 return result;
762 }
763
IsAudioRendererLowLatencySupported(napi_env env,napi_callback_info info)764 napi_value AudioStreamMgrNapi::IsAudioRendererLowLatencySupported(napi_env env, napi_callback_info info)
765 {
766 napi_status status;
767 napi_value result = nullptr;
768 const int32_t refCount = 1;
769 napi_get_undefined(env, &result);
770 GET_PARAMS(env, info, ARGS_TWO);
771 unique_ptr<AudioStreamMgrAsyncContext> asyncContext = make_unique<AudioStreamMgrAsyncContext>();
772 CHECK_AND_RETURN_RET_LOG(asyncContext != nullptr, result, "No memory");
773 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
774 if (status != napi_ok) {
775 return result;
776 }
777
778 for (size_t i = PARAM0; i < argc; i++) {
779 napi_valuetype valueType = napi_undefined;
780 napi_typeof(env, argv[i], &valueType);
781 if (i == PARAM0 && valueType == napi_object) {
782 if (!ParseAudioStreamInfo(env, argv[i], asyncContext->audioStreamInfo)) {
783 HiLog::Error(LABEL, "Parsing of audiostream failed");
784 asyncContext->status = asyncContext->status ==
785 NAPI_ERR_INVALID_PARAM ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
786 }
787 } else if (i == PARAM1) {
788 if (valueType == napi_function) {
789 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
790 }
791 break;
792 } else {
793 asyncContext->status = NAPI_ERR_INVALID_PARAM;
794 }
795 }
796 if (asyncContext->callbackRef == nullptr) {
797 napi_create_promise(env, &asyncContext->deferred, &result);
798 } else {
799 napi_get_undefined(env, &result);
800 }
801
802 napi_value resource = nullptr;
803 napi_create_string_utf8(env, "IsAudioRendererLowLatencySupported", NAPI_AUTO_LENGTH, &resource);
804 status = napi_create_async_work(
805 env, nullptr, resource,
806 [](napi_env env, void *data) {
807 auto context = static_cast<AudioStreamMgrAsyncContext*>(data);
808 if (context->status == SUCCESS) {
809 context->isLowLatencySupported =
810 context->objectInfo->audioStreamMngr_->IsAudioRendererLowLatencySupported(context->audioStreamInfo);
811 context->isTrue = context->isLowLatencySupported;
812 context->status = SUCCESS;
813 }
814 },
815 IsLowLatencySupportedCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
816 if (status != napi_ok) {
817 result = nullptr;
818 } else {
819 status = napi_queue_async_work(env, asyncContext->work);
820 if (status == napi_ok) {
821 asyncContext.release();
822 } else {
823 result = nullptr;
824 }
825 }
826
827 return result;
828 }
829
ParseAudioStreamInfo(napi_env env,napi_value root,AudioStreamInfo & audioStreamInfo)830 bool AudioStreamMgrNapi::ParseAudioStreamInfo(napi_env env, napi_value root, AudioStreamInfo &audioStreamInfo)
831 {
832 napi_value tempValue = nullptr;
833 int32_t intValue = {0};
834
835 if (napi_get_named_property(env, root, "samplingRate", &tempValue) == napi_ok) {
836 napi_get_value_int32(env, tempValue, &intValue);
837 audioStreamInfo.samplingRate = static_cast<AudioSamplingRate>(intValue);
838 }
839
840 if (napi_get_named_property(env, root, "channels", &tempValue) == napi_ok) {
841 napi_get_value_int32(env, tempValue, &intValue);
842 audioStreamInfo.channels = static_cast<AudioChannel>(intValue);
843 }
844
845 if (napi_get_named_property(env, root, "sampleFormat", &tempValue) == napi_ok) {
846 napi_get_value_int32(env, tempValue, &intValue);
847 audioStreamInfo.format = static_cast<OHOS::AudioStandard::AudioSampleFormat>(intValue);
848 }
849
850 if (napi_get_named_property(env, root, "encodingType", &tempValue) == napi_ok) {
851 napi_get_value_int32(env, tempValue, &intValue);
852 audioStreamInfo.encoding = static_cast<AudioEncodingType>(intValue);
853 }
854
855 return true;
856 }
857
CommonCallbackRoutine(napi_env env,AudioStreamMgrAsyncContext * & asyncContext,const napi_value & valueParam)858 void AudioStreamMgrNapi::CommonCallbackRoutine(napi_env env, AudioStreamMgrAsyncContext* &asyncContext,
859 const napi_value &valueParam)
860 {
861 napi_value result[ARGS_TWO] = {0};
862 napi_value retVal;
863
864 if (!asyncContext->status) {
865 napi_get_undefined(env, &result[PARAM0]);
866 result[PARAM1] = valueParam;
867 } else {
868 napi_value message = nullptr;
869 std::string messageValue = AudioCommonNapi::getMessageByCode(asyncContext->status);
870 napi_create_string_utf8(env, messageValue.c_str(), NAPI_AUTO_LENGTH, &message);
871
872 napi_value code = nullptr;
873 napi_create_string_utf8(env, (std::to_string(asyncContext->status)).c_str(), NAPI_AUTO_LENGTH, &code);
874
875 napi_create_error(env, code, message, &result[PARAM0]);
876 napi_get_undefined(env, &result[PARAM1]);
877 }
878
879 if (asyncContext->deferred) {
880 if (!asyncContext->status) {
881 napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]);
882 } else {
883 napi_reject_deferred(env, asyncContext->deferred, result[PARAM0]);
884 }
885 } else {
886 napi_value callback = nullptr;
887 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
888 napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
889 napi_delete_reference(env, asyncContext->callbackRef);
890 }
891 napi_delete_async_work(env, asyncContext->work);
892
893 delete asyncContext;
894 asyncContext = nullptr;
895 }
896
IsLowLatencySupportedCallback(napi_env env,napi_status status,void * data)897 void AudioStreamMgrNapi::IsLowLatencySupportedCallback(napi_env env, napi_status status, void *data)
898 {
899 auto asyncContext = static_cast<AudioStreamMgrAsyncContext*>(data);
900 napi_value valueParam = nullptr;
901
902 if (asyncContext != nullptr) {
903 if (!asyncContext->status) {
904 napi_get_boolean(env, asyncContext->isTrue, &valueParam);
905 }
906 CommonCallbackRoutine(env, asyncContext, valueParam);
907 } else {
908 HiLog::Error(LABEL, "ERROR: AudioStreamMgrAsyncContext* is Null!");
909 }
910 }
911
IsTrueAsyncCallbackComplete(napi_env env,napi_status status,void * data)912 void AudioStreamMgrNapi::IsTrueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
913 {
914 auto asyncContext = static_cast<AudioStreamMgrAsyncContext*>(data);
915 napi_value valueParam = nullptr;
916
917 if (asyncContext != nullptr) {
918 if (!asyncContext->status) {
919 napi_get_boolean(env, asyncContext->isTrue, &valueParam);
920 }
921 CommonCallbackRoutine(env, asyncContext, valueParam);
922 } else {
923 HiLog::Error(LABEL, "ERROR: AudioStreamMgrAsyncContext* is Null!");
924 }
925 }
926
IsStreamActive(napi_env env,napi_callback_info info)927 napi_value AudioStreamMgrNapi::IsStreamActive(napi_env env, napi_callback_info info)
928 {
929 napi_status status;
930 const int32_t refCount = 1;
931 napi_value result = nullptr;
932
933 GET_PARAMS(env, info, ARGS_TWO);
934
935 unique_ptr<AudioStreamMgrAsyncContext> asyncContext = make_unique<AudioStreamMgrAsyncContext>();
936
937 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
938 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
939 if (argc < ARGS_ONE) {
940 asyncContext->status = NAPI_ERR_INVALID_PARAM;
941 }
942 for (size_t i = PARAM0; i < argc; i++) {
943 napi_valuetype valueType = napi_undefined;
944 napi_typeof(env, argv[i], &valueType);
945
946 if (i == PARAM0 && valueType == napi_number) {
947 napi_get_value_int32(env, argv[i], &asyncContext->volType);
948 if (!AudioCommonNapi::IsLegalInputArgumentVolType(asyncContext->volType)) {
949 asyncContext->status = (asyncContext->status ==
950 NAPI_ERR_INVALID_PARAM) ? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED;
951 }
952 } else if (i == PARAM1) {
953 if (valueType == napi_function) {
954 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
955 }
956 break;
957 } else {
958 asyncContext->status = NAPI_ERR_INVALID_PARAM;
959 }
960 }
961
962 if (asyncContext->callbackRef == nullptr) {
963 napi_create_promise(env, &asyncContext->deferred, &result);
964 } else {
965 napi_get_undefined(env, &result);
966 }
967
968 napi_value resource = nullptr;
969 napi_create_string_utf8(env, "IsStreamActive", NAPI_AUTO_LENGTH, &resource);
970
971 status = napi_create_async_work(
972 env, nullptr, resource,
973 [](napi_env env, void *data) {
974 auto context = static_cast<AudioStreamMgrAsyncContext*>(data);
975 if (context->status == SUCCESS) {
976 context->isActive = context->objectInfo->audioStreamMngr_->
977 IsStreamActive(GetNativeAudioVolumeType(context->volType));
978 context->isTrue = context->isActive;
979 context->status = SUCCESS;
980 }
981 },
982 IsTrueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
983 if (status != napi_ok) {
984 result = nullptr;
985 } else {
986 status = napi_queue_async_work(env, asyncContext->work);
987 if (status == napi_ok) {
988 asyncContext.release();
989 } else {
990 result = nullptr;
991 }
992 }
993 }
994
995 return result;
996 }
997
IsStreamActiveSync(napi_env env,napi_callback_info info)998 napi_value AudioStreamMgrNapi::IsStreamActiveSync(napi_env env, napi_callback_info info)
999 {
1000 napi_status status;
1001 napi_value result = nullptr;
1002 void *native = nullptr;
1003
1004 GET_PARAMS(env, info, ARGS_ONE);
1005
1006 if (argc < ARGS_ONE) {
1007 AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
1008 return result;
1009 }
1010
1011 status = napi_unwrap(env, thisVar, &native);
1012 auto *audioStreamMgrNapi = reinterpret_cast<AudioStreamMgrNapi *>(native);
1013 if (status != napi_ok || audioStreamMgrNapi == nullptr) {
1014 AUDIO_ERR_LOG("IsStreamActiveSync unwrap failure!");
1015 return result;
1016 }
1017
1018 napi_valuetype valueType = napi_undefined;
1019 napi_typeof(env, argv[PARAM0], &valueType);
1020 if (valueType != napi_number) {
1021 AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
1022 return result;
1023 }
1024
1025 int32_t volType;
1026 napi_get_value_int32(env, argv[PARAM0], &volType);
1027 if (!AudioCommonNapi::IsLegalInputArgumentVolType(volType)) {
1028 AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
1029 return result;
1030 }
1031
1032 bool isActive = audioStreamMgrNapi->audioStreamMngr_->IsStreamActive(GetNativeAudioVolumeType(volType));
1033 napi_get_boolean(env, isActive, &result);
1034
1035 return result;
1036 }
1037
GetEffectInfoArrayCallbackComplete(napi_env env,napi_status status,void * data)1038 void AudioStreamMgrNapi::GetEffectInfoArrayCallbackComplete(napi_env env, napi_status status, void *data)
1039 {
1040 uint32_t i;
1041 auto asyncContext = static_cast<AudioStreamMgrAsyncContext*>(data);
1042 napi_value result[ARGS_TWO] = {0};
1043 napi_value jsEffectInofObj = nullptr;
1044 napi_value retVal;
1045 if (!asyncContext->status) {
1046 napi_create_array_with_length(env, asyncContext->audioSceneEffectInfo.mode.size(), &result[PARAM1]);
1047 napi_create_object(env, &jsEffectInofObj);
1048 for (i = 0; i < asyncContext->audioSceneEffectInfo.mode.size(); i++) {
1049 napi_create_uint32(env, asyncContext->audioSceneEffectInfo.mode[i], &jsEffectInofObj);
1050 napi_set_element(env, result[PARAM1], i, jsEffectInofObj);
1051 }
1052 napi_get_undefined(env, &result[PARAM0]);
1053 } else {
1054 napi_value message = nullptr;
1055 std::string messageValue = AudioCommonNapi::getMessageByCode(asyncContext->status);
1056 napi_create_string_utf8(env, messageValue.c_str(), NAPI_AUTO_LENGTH, &message);
1057 napi_value code = nullptr;
1058 napi_create_string_utf8(env, (std::to_string(asyncContext->status)).c_str(), NAPI_AUTO_LENGTH, &code);
1059 napi_create_error(env, code, message, &result[PARAM0]);
1060 napi_get_undefined(env, &result[PARAM1]);
1061 }
1062 if (asyncContext->deferred) {
1063 if (!asyncContext->status) {
1064 napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]);
1065 } else {
1066 napi_reject_deferred(env, asyncContext->deferred, result[PARAM0]);
1067 }
1068 } else {
1069 napi_value callback = nullptr;
1070 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
1071 napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
1072 napi_delete_reference(env, asyncContext->callbackRef);
1073 }
1074 napi_delete_async_work(env, asyncContext->work);
1075 delete asyncContext;
1076 }
1077
AsyncGetEffectInfoArray(napi_env env,void * data)1078 void AudioStreamMgrNapi::AsyncGetEffectInfoArray(napi_env env, void *data)
1079 {
1080 auto context = static_cast<AudioStreamMgrAsyncContext *>(data);
1081 if (context->status == SUCCESS) {
1082 StreamUsage streamUsage = static_cast<StreamUsage>(context->streamUsage);
1083 context->status =
1084 context->objectInfo->audioStreamMngr_->GetEffectInfoArray(context->audioSceneEffectInfo, streamUsage);
1085 }
1086 }
1087
GetEffectInfoArrayResult(napi_env env,unique_ptr<AudioStreamMgrAsyncContext> & asyncContext,napi_status status,napi_value & result)1088 void AudioStreamMgrNapi::GetEffectInfoArrayResult(napi_env env, unique_ptr<AudioStreamMgrAsyncContext> &asyncContext,
1089 napi_status status, napi_value &result)
1090 {
1091 if (status != napi_ok) {
1092 result = nullptr;
1093 } else {
1094 status = napi_queue_async_work(env, asyncContext->work);
1095 if (status == napi_ok) {
1096 asyncContext.release();
1097 } else {
1098 result = nullptr;
1099 }
1100 }
1101 }
1102
GetEffectInfoArray(napi_env env,napi_callback_info info)1103 napi_value AudioStreamMgrNapi::GetEffectInfoArray(napi_env env, napi_callback_info info)
1104 {
1105 napi_status status;
1106 const int32_t refCount = 1;
1107 napi_value result = nullptr;
1108 GET_PARAMS(env, info, ARGS_TWO);
1109 unique_ptr<AudioStreamMgrAsyncContext> asyncContext = make_unique<AudioStreamMgrAsyncContext>();
1110
1111 CHECK_AND_RETURN_RET_LOG(asyncContext != nullptr, result, "AudioStreamMgrNapi:Audio manager async context failed");
1112 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1113 if (status != napi_ok || asyncContext->objectInfo == nullptr
1114 || asyncContext->objectInfo->audioStreamMngr_ == nullptr) {
1115 return result;
1116 }
1117
1118 if (argc < ARGS_ONE) {
1119 asyncContext->status = NAPI_ERR_INPUT_INVALID;
1120 }
1121 for (size_t i = PARAM0; i < argc; i++) {
1122 napi_valuetype valueType = napi_undefined;
1123 napi_typeof(env, argv[i], &valueType);
1124 if (i == PARAM0 && valueType == napi_number) {
1125 napi_get_value_int32(env, argv[i], &asyncContext->streamUsage);
1126 if (!AudioCommonNapi::IsLegalInputArgumentStreamUsage(asyncContext->streamUsage)) {
1127 asyncContext->status = (asyncContext->status ==
1128 NAPI_ERR_INPUT_INVALID) ? NAPI_ERR_INPUT_INVALID : NAPI_ERR_INVALID_PARAM;
1129 }
1130 } else if (i == PARAM1) {
1131 if (valueType == napi_function) {
1132 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
1133 } else {
1134 asyncContext->status = NAPI_ERR_INPUT_INVALID;
1135 }
1136 break;
1137 } else {
1138 asyncContext->status = NAPI_ERR_INPUT_INVALID;
1139 }
1140 }
1141
1142 if (asyncContext->callbackRef == nullptr) {
1143 napi_create_promise(env, &asyncContext->deferred, &result);
1144 } else {
1145 napi_get_undefined(env, &result);
1146 }
1147
1148 napi_value resource = nullptr;
1149 napi_create_string_utf8(env, "getEffectInfoArray", NAPI_AUTO_LENGTH, &resource);
1150 status = napi_create_async_work(env, nullptr, resource, AsyncGetEffectInfoArray,
1151 GetEffectInfoArrayCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1152 GetEffectInfoArrayResult(env, asyncContext, status, result);
1153
1154 return result;
1155 }
1156
GetEffectInfoArraySync(napi_env env,napi_callback_info info)1157 napi_value AudioStreamMgrNapi::GetEffectInfoArraySync(napi_env env, napi_callback_info info)
1158 {
1159 napi_status status;
1160 napi_value result = nullptr;
1161 void *native = nullptr;
1162
1163 GET_PARAMS(env, info, ARGS_ONE);
1164
1165 if (argc < ARGS_ONE) {
1166 AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
1167 return result;
1168 }
1169
1170 status = napi_unwrap(env, thisVar, &native);
1171 auto *audioStreamMgrNapi = reinterpret_cast<AudioStreamMgrNapi *>(native);
1172 if (status != napi_ok || audioStreamMgrNapi == nullptr) {
1173 AUDIO_ERR_LOG("GetEffectInfoArraySync unwrap failure!");
1174 return result;
1175 }
1176
1177 napi_valuetype valueType = napi_undefined;
1178 napi_typeof(env, argv[PARAM0], &valueType);
1179 if (valueType != napi_number) {
1180 AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
1181 return result;
1182 }
1183
1184 int32_t streamUsage;
1185 napi_get_value_int32(env, argv[PARAM0], &streamUsage);
1186 if (!AudioCommonNapi::IsLegalInputArgumentStreamUsage(streamUsage)) {
1187 AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
1188 return result;
1189 }
1190
1191 AudioSceneEffectInfo audioSceneEffectInfo;
1192 int32_t ret = audioStreamMgrNapi->audioStreamMngr_->GetEffectInfoArray(audioSceneEffectInfo,
1193 static_cast<StreamUsage>(streamUsage));
1194 if (ret != AUDIO_OK) {
1195 AUDIO_ERR_LOG("GetEffectInfoArray failure!");
1196 return result;
1197 }
1198
1199 napi_value jsEffectInofObj = nullptr;
1200 napi_create_array_with_length(env, audioSceneEffectInfo.mode.size(), &result);
1201 napi_create_object(env, &jsEffectInofObj);
1202 for (int32_t i = 0; i < audioSceneEffectInfo.mode.size(); i++) {
1203 napi_create_uint32(env, audioSceneEffectInfo.mode[i], &jsEffectInofObj);
1204 napi_set_element(env, result, i, jsEffectInofObj);
1205 }
1206
1207 return result;
1208 }
1209 } // namespace AudioStandard
1210 } // namespace OHOS
1211