1 /*
2 * Copyright (c) 2023 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 "NapiAudioStreamMgr"
17 #endif
18
19 #include "napi_audio_stream_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_renderer_state_callback.h"
26 #include "napi_audio_capturer_state_callback.h"
27
28 namespace OHOS {
29 namespace AudioStandard {
30 using namespace std;
31 using namespace HiviewDFX;
32 static __thread napi_ref g_streamMgrConstructor = nullptr;
33
NapiAudioStreamMgr()34 NapiAudioStreamMgr::NapiAudioStreamMgr()
35 : env_(nullptr), audioStreamMngr_(nullptr) {}
36
37 NapiAudioStreamMgr::~NapiAudioStreamMgr() = default;
38
Destructor(napi_env env,void * nativeObject,void * finalizeHint)39 void NapiAudioStreamMgr::Destructor(napi_env env, void *nativeObject, void *finalizeHint)
40 {
41 if (nativeObject != nullptr) {
42 auto obj = static_cast<NapiAudioStreamMgr *>(nativeObject);
43 ObjectRefMap<NapiAudioStreamMgr>::DecreaseRef(obj);
44 }
45 AUDIO_INFO_LOG("Destructor is successful");
46 }
47
Construct(napi_env env,napi_callback_info info)48 napi_value NapiAudioStreamMgr::Construct(napi_env env, napi_callback_info info)
49 {
50 AUDIO_DEBUG_LOG("Construct");
51 napi_status status;
52 napi_value result = nullptr;
53 NapiParamUtils::GetUndefinedValue(env);
54
55 size_t argc = ARGS_TWO;
56 napi_value argv[ARGS_TWO] = {0};
57 napi_value thisVar = nullptr;
58 void *data = nullptr;
59 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
60 unique_ptr<NapiAudioStreamMgr> napiStreamMgr = make_unique<NapiAudioStreamMgr>();
61 CHECK_AND_RETURN_RET_LOG(napiStreamMgr != nullptr, result, "No memory");
62
63 napiStreamMgr->env_ = env;
64 napiStreamMgr->audioStreamMngr_ = AudioStreamManager::GetInstance();
65 napiStreamMgr->cachedClientId_ = getpid();
66 ObjectRefMap<NapiAudioStreamMgr>::Insert(napiStreamMgr.get());
67
68 status = napi_wrap(env, thisVar, static_cast<void*>(napiStreamMgr.get()),
69 NapiAudioStreamMgr::Destructor, nullptr, nullptr);
70 if (status != napi_ok) {
71 ObjectRefMap<NapiAudioStreamMgr>::Erase(napiStreamMgr.get());
72 return result;
73 }
74 napiStreamMgr.release();
75 return thisVar;
76 }
77
Init(napi_env env,napi_value exports)78 napi_value NapiAudioStreamMgr::Init(napi_env env, napi_value exports)
79 {
80 napi_status status;
81 napi_value constructor;
82 napi_value result = nullptr;
83 const int32_t refCount = ARGS_ONE;
84 napi_get_undefined(env, &result);
85
86 napi_property_descriptor audio_stream_mgr_properties[] = {
87 DECLARE_NAPI_FUNCTION("on", On),
88 DECLARE_NAPI_FUNCTION("off", Off),
89 DECLARE_NAPI_FUNCTION("getCurrentAudioRendererInfoArray", GetCurrentAudioRendererInfos),
90 DECLARE_NAPI_FUNCTION("getCurrentAudioRendererInfoArraySync", GetCurrentAudioRendererInfosSync),
91 DECLARE_NAPI_FUNCTION("getCurrentAudioCapturerInfoArray", GetCurrentAudioCapturerInfos),
92 DECLARE_NAPI_FUNCTION("getCurrentAudioCapturerInfoArraySync", GetCurrentAudioCapturerInfosSync),
93 DECLARE_NAPI_FUNCTION("isAudioRendererLowLatencySupported", IsAudioRendererLowLatencySupported),
94 DECLARE_NAPI_FUNCTION("isActive", IsStreamActive),
95 DECLARE_NAPI_FUNCTION("isActiveSync", IsStreamActiveSync),
96 DECLARE_NAPI_FUNCTION("getAudioEffectInfoArray", GetEffectInfoArray),
97 DECLARE_NAPI_FUNCTION("getAudioEffectInfoArraySync", GetEffectInfoArraySync),
98 DECLARE_NAPI_FUNCTION("getHardwareOutputSamplingRate", GetHardwareOutputSamplingRate),
99 };
100
101 status = napi_define_class(env, AUDIO_STREAM_MGR_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct, nullptr,
102 sizeof(audio_stream_mgr_properties) / sizeof(audio_stream_mgr_properties[PARAM0]),
103 audio_stream_mgr_properties, &constructor);
104 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_define_class fail");
105
106 status = napi_create_reference(env, constructor, refCount, &g_streamMgrConstructor);
107 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_reference fail");
108 status = napi_set_named_property(env, exports, AUDIO_STREAM_MGR_NAPI_CLASS_NAME.c_str(), constructor);
109 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_set_named_property fail");
110 return exports;
111 }
112
CreateStreamManagerWrapper(napi_env env)113 napi_value NapiAudioStreamMgr::CreateStreamManagerWrapper(napi_env env)
114 {
115 napi_status status;
116 napi_value result = nullptr;
117 napi_value constructor;
118
119 status = napi_get_reference_value(env, g_streamMgrConstructor, &constructor);
120 if (status != napi_ok) {
121 AUDIO_ERR_LOG("Failed in CreateStreamManagerWrapper, %{public}d", status);
122 goto fail;
123 }
124 status = napi_new_instance(env, constructor, PARAM0, nullptr, &result);
125 if (status != napi_ok) {
126 AUDIO_ERR_LOG("napi_new_instance failed, status:%{public}d", status);
127 goto fail;
128 }
129 return result;
130
131 fail:
132 napi_get_undefined(env, &result);
133 return result;
134 }
135
CheckContextStatus(std::shared_ptr<AudioStreamMgrAsyncContext> context)136 bool NapiAudioStreamMgr::CheckContextStatus(std::shared_ptr<AudioStreamMgrAsyncContext> context)
137 {
138 CHECK_AND_RETURN_RET_LOG(context != nullptr, false, "context object is nullptr.");
139 if (context->native == nullptr) {
140 context->SignError(NAPI_ERR_SYSTEM);
141 return false;
142 }
143 return true;
144 }
145
CheckAudioStreamManagerStatus(NapiAudioStreamMgr * napi,std::shared_ptr<AudioStreamMgrAsyncContext> context)146 bool NapiAudioStreamMgr::CheckAudioStreamManagerStatus(NapiAudioStreamMgr *napi,
147 std::shared_ptr<AudioStreamMgrAsyncContext> context)
148 {
149 CHECK_AND_RETURN_RET_LOG(napi != nullptr, false, "napi object is nullptr.");
150 if (napi->audioStreamMngr_ == nullptr) {
151 context->SignError(NAPI_ERR_SYSTEM);
152 return false;
153 }
154 return true;
155 }
156
GetParamWithSync(const napi_env & env,napi_callback_info info,size_t & argc,napi_value * args)157 NapiAudioStreamMgr* NapiAudioStreamMgr::GetParamWithSync(const napi_env &env, napi_callback_info info,
158 size_t &argc, napi_value *args)
159 {
160 napi_status status;
161 NapiAudioStreamMgr *napiStreamMgr = nullptr;
162 napi_value jsThis = nullptr;
163 status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
164 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr,
165 "GetParamWithSync fail to napi_get_cb_info");
166
167 status = napi_unwrap(env, jsThis, (void **)&napiStreamMgr);
168 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "napi_unwrap failed");
169 CHECK_AND_RETURN_RET_LOG(napiStreamMgr != nullptr && napiStreamMgr->audioStreamMngr_ !=
170 nullptr, napiStreamMgr, "GetParamWithSync fail to napi_unwrap");
171 return napiStreamMgr;
172 }
173
GetCurrentAudioRendererInfos(napi_env env,napi_callback_info info)174 napi_value NapiAudioStreamMgr::GetCurrentAudioRendererInfos(napi_env env, napi_callback_info info)
175 {
176 auto context = std::make_shared<AudioStreamMgrAsyncContext>();
177 if (context == nullptr) {
178 AUDIO_ERR_LOG("GetCurrentAudioRendererInfos failed : no memory");
179 NapiAudioError::ThrowError(env, "GetCurrentAudioRendererInfos failed : no memory", NAPI_ERR_NO_MEMORY);
180 return NapiParamUtils::GetUndefinedValue(env);
181 }
182
183 context->GetCbInfo(env, info);
184
185 auto executor = [context]() {
186 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
187 auto obj = reinterpret_cast<NapiAudioStreamMgr*>(context->native);
188 ObjectRefMap objectGuard(obj);
189 auto *napiStreamMgr = objectGuard.GetPtr();
190 CHECK_AND_RETURN_LOG(CheckAudioStreamManagerStatus(napiStreamMgr, context),
191 "context object state is error.");
192 context->intValue = napiStreamMgr->audioStreamMngr_->GetCurrentRendererChangeInfos(
193 context->audioRendererChangeInfos);
194 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS,
195 "GetCurrentAudioRendererInfos failed", NAPI_ERR_SYSTEM);
196 };
197
198 auto complete = [env, context](napi_value &output) {
199 NapiParamUtils::SetRendererChangeInfos(env, context->audioRendererChangeInfos, output);
200 };
201 return NapiAsyncWork::Enqueue(env, context, "GetCurrentAudioRendererInfos", executor, complete);
202 }
203
GetCurrentAudioRendererInfosSync(napi_env env,napi_callback_info info)204 napi_value NapiAudioStreamMgr::GetCurrentAudioRendererInfosSync(napi_env env, napi_callback_info info)
205 {
206 AUDIO_INFO_LOG("GetCurrentAudioRendererInfosSync");
207 napi_value result = nullptr;
208 size_t argc = PARAM0;
209 auto *napiStreamMgr = GetParamWithSync(env, info, argc, nullptr);
210 if (argc > 0) {
211 NapiAudioError::ThrowError(env, NAPI_ERROR_INVALID_PARAM);
212 }
213 CHECK_AND_RETURN_RET_LOG(napiStreamMgr!= nullptr, result, "napiStreamMgr is nullptr");
214
215 vector<std::unique_ptr<AudioRendererChangeInfo>> audioRendererChangeInfos;
216 int32_t ret = napiStreamMgr->audioStreamMngr_->GetCurrentRendererChangeInfos(audioRendererChangeInfos);
217 CHECK_AND_RETURN_RET_LOG(ret == AUDIO_OK, result, "GetCurrentRendererChangeInfos failure!");
218
219 NapiParamUtils::SetRendererChangeInfos(env, audioRendererChangeInfos, result);
220
221 return result;
222 }
223
GetCurrentAudioCapturerInfos(napi_env env,napi_callback_info info)224 napi_value NapiAudioStreamMgr::GetCurrentAudioCapturerInfos(napi_env env, napi_callback_info info)
225 {
226 auto context = std::make_shared<AudioStreamMgrAsyncContext>();
227 if (context == nullptr) {
228 AUDIO_ERR_LOG("GetCurrentAudioCapturerInfos failed : no memory");
229 NapiAudioError::ThrowError(env, "GetCurrentAudioCapturerInfos failed : no memory", NAPI_ERR_NO_MEMORY);
230 return NapiParamUtils::GetUndefinedValue(env);
231 }
232
233 context->GetCbInfo(env, info);
234
235 auto executor = [context]() {
236 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
237 auto obj = reinterpret_cast<NapiAudioStreamMgr*>(context->native);
238 ObjectRefMap objectGuard(obj);
239 auto *napiStreamMgr = objectGuard.GetPtr();
240 CHECK_AND_RETURN_LOG(CheckAudioStreamManagerStatus(napiStreamMgr, context),
241 "context object state is error.");
242 napiStreamMgr->audioStreamMngr_->GetCurrentCapturerChangeInfos(
243 context->audioCapturerChangeInfos);
244 };
245
246 auto complete = [env, context](napi_value &output) {
247 NapiParamUtils::SetCapturerChangeInfos(env, context->audioCapturerChangeInfos, output);
248 };
249 return NapiAsyncWork::Enqueue(env, context, "GetCurrentAudioCapturerInfos", executor, complete);
250 }
251
GetCurrentAudioCapturerInfosSync(napi_env env,napi_callback_info info)252 napi_value NapiAudioStreamMgr::GetCurrentAudioCapturerInfosSync(napi_env env, napi_callback_info info)
253 {
254 AUDIO_INFO_LOG("GetCurrentAudioCapturerInfosSync");
255 napi_value result = nullptr;
256 size_t argc = PARAM0;
257 auto *napiStreamMgr = GetParamWithSync(env, info, argc, nullptr);
258 if (argc > 0) {
259 NapiAudioError::ThrowError(env, NAPI_ERROR_INVALID_PARAM);
260 }
261 CHECK_AND_RETURN_RET_LOG(napiStreamMgr!= nullptr, result, "napiStreamMgr is nullptr");
262
263 vector<std::unique_ptr<AudioCapturerChangeInfo>> audioCapturerChangeInfos;
264 int32_t ret = napiStreamMgr->audioStreamMngr_->GetCurrentCapturerChangeInfos(audioCapturerChangeInfos);
265 if (ret != AUDIO_OK) {
266 AUDIO_ERR_LOG("GetCurrentCapturerChangeInfos failure!");
267 return result;
268 }
269 NapiParamUtils::SetCapturerChangeInfos(env, audioCapturerChangeInfos, result);
270
271 return result;
272 }
273
IsAudioRendererLowLatencySupported(napi_env env,napi_callback_info info)274 napi_value NapiAudioStreamMgr::IsAudioRendererLowLatencySupported(napi_env env, napi_callback_info info)
275 {
276 auto context = std::make_shared<AudioStreamMgrAsyncContext>();
277 if (context == nullptr) {
278 AUDIO_ERR_LOG("IsAudioRendererLowLatencySupported failed : no memory");
279 NapiAudioError::ThrowError(env, "IsAudioRendererLowLatencySupported failed : no memory", NAPI_ERR_NO_MEMORY);
280 return NapiParamUtils::GetUndefinedValue(env);
281 }
282
283 auto inputParser = [env, context](size_t argc, napi_value *argv) {
284 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
285 context->status = NapiParamUtils::GetStreamInfo(env, &context->audioStreamInfo, argv[PARAM0]);
286 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "getstreaminfo failed",
287 NAPI_ERR_INVALID_PARAM);
288 };
289 context->GetCbInfo(env, info, inputParser);
290
291 auto executor = [context]() {
292 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
293 auto obj = reinterpret_cast<NapiAudioStreamMgr*>(context->native);
294 ObjectRefMap objectGuard(obj);
295 auto *napiStreamMgr = objectGuard.GetPtr();
296 CHECK_AND_RETURN_LOG(CheckAudioStreamManagerStatus(napiStreamMgr, context),
297 "context object state is error.");
298 context->isLowLatencySupported = napiStreamMgr->audioStreamMngr_->IsAudioRendererLowLatencySupported(
299 context->audioStreamInfo);
300 context->isTrue = context->isLowLatencySupported;
301 };
302
303 auto complete = [env, context](napi_value &output) {
304 NapiParamUtils::SetValueBoolean(env, context->isTrue, output);
305 };
306 return NapiAsyncWork::Enqueue(env, context, "IsAudioRendererLowLatencySupported", executor, complete);
307 }
308
IsStreamActive(napi_env env,napi_callback_info info)309 napi_value NapiAudioStreamMgr::IsStreamActive(napi_env env, napi_callback_info info)
310 {
311 auto context = std::make_shared<AudioStreamMgrAsyncContext>();
312 if (context == nullptr) {
313 AUDIO_ERR_LOG("IsStreamActive failed : no memory");
314 NapiAudioError::ThrowError(env, "IsStreamActive failed : no memory", NAPI_ERR_NO_MEMORY);
315 return NapiParamUtils::GetUndefinedValue(env);
316 }
317
318 auto inputParser = [env, context](size_t argc, napi_value *argv) {
319 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
320 context->status = NapiParamUtils::GetValueInt32(env, context->volType, argv[PARAM0]);
321 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "getvoltype failed",
322 NAPI_ERR_INVALID_PARAM);
323 if (!NapiAudioEnum::IsLegalInputArgumentVolType(context->volType)) {
324 context->SignError(context->errCode ==
325 NAPI_ERR_INVALID_PARAM? NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED);
326 }
327 };
328 context->GetCbInfo(env, info, inputParser);
329
330 auto executor = [context]() {
331 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
332 auto obj = reinterpret_cast<NapiAudioStreamMgr*>(context->native);
333 ObjectRefMap objectGuard(obj);
334 auto *napiStreamMgr = objectGuard.GetPtr();
335 CHECK_AND_RETURN_LOG(CheckAudioStreamManagerStatus(napiStreamMgr, context),
336 "context object state is error.");
337 context->isActive = napiStreamMgr->audioStreamMngr_->IsStreamActive(
338 NapiAudioEnum::GetNativeAudioVolumeType(context->volType));
339 context->isTrue = context->isActive;
340 };
341
342 auto complete = [env, context](napi_value &output) {
343 NapiParamUtils::SetValueBoolean(env, context->isTrue, output);
344 };
345 return NapiAsyncWork::Enqueue(env, context, "IsStreamActive", executor, complete);
346 }
347
IsStreamActiveSync(napi_env env,napi_callback_info info)348 napi_value NapiAudioStreamMgr::IsStreamActiveSync(napi_env env, napi_callback_info info)
349 {
350 napi_value result = nullptr;
351 size_t argc = ARGS_ONE;
352 napi_value args[ARGS_ONE] = {};
353 auto *napiStreamMgr = GetParamWithSync(env, info, argc, args);
354 CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
355 "mandatory parameters are left unspecified"), "invalid arguments");
356
357 napi_valuetype valueType = napi_undefined;
358 napi_typeof(env, args[PARAM0], &valueType);
359 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
360 "incorrect parameter types: The type of volumeType must be number"), "invalid valueType");
361
362 int32_t volType;
363 NapiParamUtils::GetValueInt32(env, volType, args[PARAM0]);
364 CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentVolType(volType),
365 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
366 "parameter verification failed: The param of volumeType must be enum AudioVolumeType"), "get volType failed");
367
368 CHECK_AND_RETURN_RET_LOG(napiStreamMgr != nullptr, result, "napiStreamMgr is nullptr");
369 CHECK_AND_RETURN_RET_LOG(napiStreamMgr->audioStreamMngr_ != nullptr, result,
370 "audioStreamMngr_ is nullptr");
371 bool isActive = napiStreamMgr->audioStreamMngr_->
372 IsStreamActive(NapiAudioEnum::GetNativeAudioVolumeType(volType));
373 NapiParamUtils::SetValueBoolean(env, isActive, result);
374 return result;
375 }
376
GetEffectInfoArray(napi_env env,napi_callback_info info)377 napi_value NapiAudioStreamMgr::GetEffectInfoArray(napi_env env, napi_callback_info info)
378 {
379 auto context = std::make_shared<AudioStreamMgrAsyncContext>();
380 if (context == nullptr) {
381 AUDIO_ERR_LOG("GetEffectInfoArray failed : no memory");
382 NapiAudioError::ThrowError(env, "GetEffectInfoArray failed : no memory", NAPI_ERR_NO_MEMORY);
383 return NapiParamUtils::GetUndefinedValue(env);
384 }
385
386 auto inputParser = [env, context](size_t argc, napi_value *argv) {
387 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
388 NAPI_ERR_INPUT_INVALID);
389 context->status = NapiParamUtils::GetValueInt32(env, context->streamUsage, argv[PARAM0]);
390 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
391 "incorrect parameter types: The type of usage must be number", NAPI_ERR_INPUT_INVALID);
392 if (!NapiAudioEnum::IsLegalInputArgumentStreamUsage(context->streamUsage)) {
393 context->SignError(NAPI_ERR_INVALID_PARAM,
394 "parameter verification failed: The param of usage must be enum StreamUsage");
395 }
396 };
397 context->GetCbInfo(env, info, inputParser);
398
399 if ((context->status != napi_ok) && (context->errCode == NAPI_ERR_INPUT_INVALID)) {
400 NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
401 return NapiParamUtils::GetUndefinedValue(env);
402 }
403
404 auto executor = [context]() {
405 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
406 auto obj = reinterpret_cast<NapiAudioStreamMgr*>(context->native);
407 ObjectRefMap objectGuard(obj);
408 auto *napiStreamMgr = objectGuard.GetPtr();
409 CHECK_AND_RETURN_LOG(CheckAudioStreamManagerStatus(napiStreamMgr, context),
410 "context object state is error.");
411 StreamUsage streamUsage = static_cast<StreamUsage>(context->streamUsage);
412 context->intValue = napiStreamMgr->audioStreamMngr_->GetEffectInfoArray(
413 context->audioSceneEffectInfo, streamUsage);
414 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "GetEffectInfoArray failed",
415 NAPI_ERR_SYSTEM);
416 };
417
418 auto complete = [env, context](napi_value &output) {
419 NapiParamUtils::SetEffectInfo(env, context->audioSceneEffectInfo, output);
420 };
421 return NapiAsyncWork::Enqueue(env, context, "GetEffectInfoArray", executor, complete);
422 }
423
GetEffectInfoArraySync(napi_env env,napi_callback_info info)424 napi_value NapiAudioStreamMgr::GetEffectInfoArraySync(napi_env env, napi_callback_info info)
425 {
426 napi_value result = nullptr;
427 size_t argc = ARGS_ONE;
428 napi_value args[ARGS_ONE] = {};
429 auto *napiStreamMgr = GetParamWithSync(env, info, argc, args);
430 CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
431 "mandatory parameters are left unspecified"), "invalid arguments");
432
433 napi_valuetype valueType = napi_undefined;
434 napi_typeof(env, args[PARAM0], &valueType);
435 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
436 "incorrect parameter types: The type of usage must be number"), "invalid valueType");
437
438 int32_t streamUsage;
439 NapiParamUtils::GetValueInt32(env, streamUsage, args[PARAM0]);
440 CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentStreamUsage(streamUsage),
441 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
442 "parameter verification failed: The param of usage must be enum StreamUsage"), "get streamUsage failed");
443
444 CHECK_AND_RETURN_RET_LOG(napiStreamMgr != nullptr, result, "napiStreamMgr is nullptr");
445 CHECK_AND_RETURN_RET_LOG(napiStreamMgr->audioStreamMngr_ != nullptr, result,
446 "audioStreamMngr_ is nullptr");
447 AudioSceneEffectInfo audioSceneEffectInfo;
448 int32_t ret = napiStreamMgr->audioStreamMngr_->GetEffectInfoArray(audioSceneEffectInfo,
449 static_cast<StreamUsage>(streamUsage));
450 CHECK_AND_RETURN_RET_LOG(ret == AUDIO_OK, result, "GetEffectInfoArray failure!");
451 NapiParamUtils::SetEffectInfo(env, audioSceneEffectInfo, result);
452 return result;
453 }
454
GetHardwareOutputSamplingRate(napi_env env,napi_callback_info info)455 napi_value NapiAudioStreamMgr::GetHardwareOutputSamplingRate(napi_env env, napi_callback_info info)
456 {
457 napi_value result = nullptr;
458 sptr<AudioDeviceDescriptor> deviceDescriptor = nullptr;
459 size_t argc = ARGS_ONE;
460 napi_value args[ARGS_ONE] = {};
461 auto *napiStreamMgr = GetParamWithSync(env, info, argc, args);
462 CHECK_AND_RETURN_RET_LOG(napiStreamMgr != nullptr, result, "napiStreamMgr is nullptr");
463 CHECK_AND_RETURN_RET_LOG(napiStreamMgr->audioStreamMngr_ != nullptr, result,
464 "audioStreamMngr_ is nullptr");
465
466 if (argc < ARGS_ONE) {
467 int32_t rate = napiStreamMgr->audioStreamMngr_->GetHardwareOutputSamplingRate(deviceDescriptor);
468 NapiParamUtils::SetValueInt32(env, rate, result);
469 return result;
470 }
471
472 deviceDescriptor = new (std::nothrow) AudioDeviceDescriptor();
473 CHECK_AND_RETURN_RET_LOG(deviceDescriptor != nullptr, result, "AudioDeviceDescriptor alloc failed!");
474
475 bool argTransFlag = false;
476 NapiParamUtils::GetAudioDeviceDescriptor(env, deviceDescriptor, argTransFlag, args[PARAM0]);
477 CHECK_AND_RETURN_RET_LOG(argTransFlag && NapiAudioEnum::IsLegalOutputDeviceType(deviceDescriptor->deviceType_) &&
478 (deviceDescriptor->deviceRole_ == DeviceRole::OUTPUT_DEVICE),
479 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM), "invalid deviceDescriptor");
480
481 int32_t rate = napiStreamMgr->audioStreamMngr_->GetHardwareOutputSamplingRate(deviceDescriptor);
482 NapiParamUtils::SetValueInt32(env, rate, result);
483 return result;
484 }
485
RegisterCallback(napi_env env,napi_value jsThis,napi_value * args,const std::string & cbName)486 void NapiAudioStreamMgr::RegisterCallback(napi_env env, napi_value jsThis,
487 napi_value *args, const std::string &cbName)
488 {
489 NapiAudioStreamMgr *napiStreamMgr = nullptr;
490 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiStreamMgr));
491 CHECK_AND_RETURN_LOG((status == napi_ok) && (napiStreamMgr != nullptr) &&
492 (napiStreamMgr->audioStreamMngr_ != nullptr), "Failed to retrieve stream mgr napi instance.");
493
494 if (!cbName.compare(RENDERERCHANGE_CALLBACK_NAME)) {
495 RegisterRendererStateChangeCallback(env, args, cbName, napiStreamMgr);
496 } else if (!cbName.compare(CAPTURERCHANGE_CALLBACK_NAME)) {
497 RegisterCapturerStateChangeCallback(env, args, cbName, napiStreamMgr);
498 } else {
499 AUDIO_ERR_LOG("NapiAudioStreamMgr::No such callback supported");
500 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
501 "parameter verification failed: The param of type is not supported");
502 }
503 }
504
RegisterRendererStateChangeCallback(napi_env env,napi_value * args,const std::string & cbName,NapiAudioStreamMgr * napiStreamMgr)505 void NapiAudioStreamMgr::RegisterRendererStateChangeCallback(napi_env env, napi_value *args,
506 const std::string &cbName, NapiAudioStreamMgr *napiStreamMgr)
507 {
508 if (!napiStreamMgr->rendererStateChangeCallbackNapi_) {
509 napiStreamMgr->rendererStateChangeCallbackNapi_ = std::make_shared<NapiAudioRendererStateCallback>(env);
510 CHECK_AND_RETURN_LOG(napiStreamMgr->rendererStateChangeCallbackNapi_ != nullptr,
511 "NapiAudioStreamMgr: Memory Allocation Failed !!");
512
513 int32_t ret =
514 napiStreamMgr->audioStreamMngr_->RegisterAudioRendererEventListener(napiStreamMgr->cachedClientId_,
515 napiStreamMgr->rendererStateChangeCallbackNapi_);
516 CHECK_AND_RETURN_LOG(ret == SUCCESS,
517 "NapiAudioStreamMgr: Registering of Renderer State Change Callback Failed");
518 }
519
520 std::shared_ptr<NapiAudioRendererStateCallback> cb =
521 std::static_pointer_cast<NapiAudioRendererStateCallback>(napiStreamMgr->rendererStateChangeCallbackNapi_);
522 cb->SaveCallbackReference(args[PARAM1]);
523
524 AUDIO_INFO_LOG("OnRendererStateChangeCallback is successful");
525 }
526
RegisterCapturerStateChangeCallback(napi_env env,napi_value * args,const std::string & cbName,NapiAudioStreamMgr * napiStreamMgr)527 void NapiAudioStreamMgr::RegisterCapturerStateChangeCallback(napi_env env, napi_value *args,
528 const std::string &cbName, NapiAudioStreamMgr *napiStreamMgr)
529 {
530 if (!napiStreamMgr->capturerStateChangeCallbackNapi_) {
531 napiStreamMgr->capturerStateChangeCallbackNapi_ = std::make_shared<NapiAudioCapturerStateCallback>(env);
532 CHECK_AND_RETURN_LOG(napiStreamMgr->capturerStateChangeCallbackNapi_ != nullptr,
533 "Memory Allocation Failed !!");
534
535 int32_t ret =
536 napiStreamMgr->audioStreamMngr_->RegisterAudioCapturerEventListener(napiStreamMgr->cachedClientId_,
537 napiStreamMgr->capturerStateChangeCallbackNapi_);
538 CHECK_AND_RETURN_LOG(ret == SUCCESS,
539 "Registering of Capturer State Change Callback Failed");
540 }
541 std::lock_guard<std::mutex> lock(napiStreamMgr->capturerStateChangeCallbackNapi_->cbMutex_);
542
543 std::shared_ptr<NapiAudioCapturerStateCallback> cb =
544 std::static_pointer_cast<NapiAudioCapturerStateCallback>(napiStreamMgr->capturerStateChangeCallbackNapi_);
545 cb->SaveCallbackReference(args[PARAM1]);
546
547 AUDIO_INFO_LOG("OnCapturerStateChangeCallback is successful");
548 }
549
On(napi_env env,napi_callback_info info)550 napi_value NapiAudioStreamMgr::On(napi_env env, napi_callback_info info)
551 {
552 const size_t requireArgc = ARGS_TWO;
553 size_t argc = ARGS_THREE;
554
555 napi_value undefinedResult = nullptr;
556 napi_get_undefined(env, &undefinedResult);
557
558 napi_value args[requireArgc + PARAM1] = {nullptr, nullptr, nullptr};
559 napi_value jsThis = nullptr;
560 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
561 CHECK_AND_RETURN_RET_LOG(status == napi_ok && argc == requireArgc, NapiAudioError::ThrowErrorAndReturn(env,
562 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "status or arguments error");
563
564 napi_valuetype eventType = napi_undefined;
565 napi_typeof(env, args[PARAM0], &eventType);
566 CHECK_AND_RETURN_RET_LOG(eventType == napi_string, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
567 "incorrect parameter types: The type of eventType must be string"), "eventType error");
568
569 std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
570 AUDIO_DEBUG_LOG("AudioStreamMgrNapi: On callbackName: %{public}s", callbackName.c_str());
571
572 napi_valuetype handler = napi_undefined;
573
574 napi_typeof(env, args[PARAM1], &handler);
575 CHECK_AND_RETURN_RET_LOG(handler == napi_function, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
576 "incorrect parameter types: The type of callback must be function"), "handler is invalid");
577
578 RegisterCallback(env, jsThis, args, callbackName);
579 return undefinedResult;
580 }
581
UnregisterCallback(napi_env env,napi_value jsThis,const std::string & cbName)582 void NapiAudioStreamMgr::UnregisterCallback(napi_env env, napi_value jsThis, const std::string &cbName)
583 {
584 AUDIO_INFO_LOG("UnregisterCallback");
585 NapiAudioStreamMgr *napiStreamMgr = nullptr;
586 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiStreamMgr));
587 CHECK_AND_RETURN_LOG((status == napi_ok) && (napiStreamMgr != nullptr) &&
588 (napiStreamMgr->audioStreamMngr_ != nullptr), "Failed to retrieve stream mgr napi instance.");
589
590 if (!cbName.compare(RENDERERCHANGE_CALLBACK_NAME)) {
591 int32_t ret = napiStreamMgr->audioStreamMngr_->
592 UnregisterAudioRendererEventListener(napiStreamMgr->cachedClientId_);
593 CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnRegistering of Renderer State Change Callback Failed");
594
595 if (napiStreamMgr->rendererStateChangeCallbackNapi_ != nullptr) {
596 std::shared_ptr<NapiAudioRendererStateCallback> cb =
597 std::static_pointer_cast<NapiAudioRendererStateCallback>(napiStreamMgr->
598 rendererStateChangeCallbackNapi_);
599 cb->RemoveCallbackReference();
600 napiStreamMgr->rendererStateChangeCallbackNapi_.reset();
601 }
602 AUDIO_INFO_LOG("UnRegistering of renderer State Change Callback successful");
603 } else if (!cbName.compare(CAPTURERCHANGE_CALLBACK_NAME)) {
604 int32_t ret = napiStreamMgr->audioStreamMngr_->
605 UnregisterAudioCapturerEventListener(napiStreamMgr->cachedClientId_);
606 if (ret) {
607 AUDIO_ERR_LOG("UnRegistering of capturer State Change Callback Failed");
608 return;
609 }
610 if (napiStreamMgr->capturerStateChangeCallbackNapi_ != nullptr) {
611 std::lock_guard<std::mutex> lock(napiStreamMgr->capturerStateChangeCallbackNapi_->cbMutex_);
612 napiStreamMgr->capturerStateChangeCallbackNapi_.reset();
613 napiStreamMgr->capturerStateChangeCallbackNapi_ = nullptr;
614 }
615 AUDIO_INFO_LOG("UnRegistering of capturer State Change Callback successful");
616 } else {
617 AUDIO_ERR_LOG("No such callback supported");
618 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
619 "parameter verification failed: The param of type is not supported");
620 }
621 }
622
Off(napi_env env,napi_callback_info info)623 napi_value NapiAudioStreamMgr::Off(napi_env env, napi_callback_info info)
624 {
625 const size_t requireArgc = ARGS_ONE;
626 size_t argc = ARGS_ONE;
627
628 napi_value undefinedResult = nullptr;
629 napi_get_undefined(env, &undefinedResult);
630
631 napi_value args[requireArgc] = {nullptr};
632 napi_value jsThis = nullptr;
633 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
634 CHECK_AND_RETURN_RET_LOG(status == napi_ok && argc >= requireArgc, NapiAudioError::ThrowErrorAndReturn(env,
635 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "status or arguments error");
636
637 napi_valuetype eventType = napi_undefined;
638 napi_typeof(env, args[PARAM0], &eventType);
639 CHECK_AND_RETURN_RET_LOG(eventType == napi_string, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
640 "incorrect parameter types: The type of eventType must be string"), "eventType error");
641
642 std::string callbackName = NapiParamUtils::GetStringArgument(env, args[0]);
643 AUDIO_DEBUG_LOG("NapiAudioStreamMgr: Off callbackName: %{public}s", callbackName.c_str());
644
645 UnregisterCallback(env, jsThis, callbackName);
646 return undefinedResult;
647 }
648 } // namespace AudioStandard
649 } // namespace OHOS
650