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 "NapiAudioRenderer"
17 #endif
18
19 #include "napi_audio_renderer.h"
20 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
21 #include "errors.h"
22 #else
23 #ifdef FEATURE_HIVIEW_ENABLE
24 #include "xpower_event_js.h"
25 #endif
26 #endif
27 #include "napi_param_utils.h"
28 #include "napi_audio_error.h"
29 #include "napi_audio_enum.h"
30 #include "napi_audio_renderer_callback.h"
31 #include "napi_renderer_position_callback.h"
32 #include "napi_renderer_data_request_callback.h"
33 #include "napi_renderer_period_position_callback.h"
34 #include "napi_audio_renderer_write_data_callback.h"
35 #include "napi_audio_renderer_device_change_callback.h"
36 #include "napi_audio_renderer_policy_service_died_callback.h"
37
38 namespace OHOS {
39 namespace AudioStandard {
40 static __thread napi_ref g_rendererConstructor = nullptr;
41 mutex NapiAudioRenderer::createMutex_;
42 int32_t NapiAudioRenderer::isConstructSuccess_ = SUCCESS;
43 std::unique_ptr<AudioRendererOptions> NapiAudioRenderer::sRendererOptions_ = nullptr;
44
NapiAudioRenderer()45 NapiAudioRenderer::NapiAudioRenderer()
46 : audioRenderer_(nullptr), contentType_(CONTENT_TYPE_MUSIC), streamUsage_(STREAM_USAGE_MEDIA), env_(nullptr) {}
47
Destructor(napi_env env,void * nativeObject,void * finalizeHint)48 void NapiAudioRenderer::Destructor(napi_env env, void *nativeObject, void *finalizeHint)
49 {
50 if (nativeObject == nullptr) {
51 AUDIO_WARNING_LOG("Native object is null");
52 return;
53 }
54 auto obj = static_cast<NapiAudioRenderer *>(nativeObject);
55 ObjectRefMap<NapiAudioRenderer>::DecreaseRef(obj);
56 AUDIO_INFO_LOG("Decrease obj count");
57 }
58
InitNapiAudioRenderer(napi_env env,napi_value & constructor)59 napi_status NapiAudioRenderer::InitNapiAudioRenderer(napi_env env, napi_value &constructor)
60 {
61 napi_property_descriptor audio_renderer_properties[] = {
62 DECLARE_NAPI_FUNCTION("setRenderRate", SetRenderRate),
63 DECLARE_NAPI_FUNCTION("getRenderRate", GetRenderRate),
64 DECLARE_NAPI_FUNCTION("getRenderRateSync", GetRenderRateSync),
65 DECLARE_NAPI_FUNCTION("setRendererSamplingRate", SetRendererSamplingRate),
66 DECLARE_NAPI_FUNCTION("getRendererSamplingRate", GetRendererSamplingRate),
67 DECLARE_NAPI_FUNCTION("start", Start),
68 DECLARE_NAPI_FUNCTION("write", Write),
69 DECLARE_NAPI_FUNCTION("getAudioTime", GetAudioTime),
70 DECLARE_NAPI_FUNCTION("getAudioTimeSync", GetAudioTimeSync),
71 DECLARE_NAPI_FUNCTION("drain", Drain),
72 DECLARE_NAPI_FUNCTION("flush", Flush),
73 DECLARE_NAPI_FUNCTION("pause", Pause),
74 DECLARE_NAPI_FUNCTION("stop", Stop),
75 DECLARE_NAPI_FUNCTION("release", Release),
76 DECLARE_NAPI_FUNCTION("getBufferSize", GetBufferSize),
77 DECLARE_NAPI_FUNCTION("getBufferSizeSync", GetBufferSizeSync),
78 DECLARE_NAPI_FUNCTION("getAudioStreamId", GetAudioStreamId),
79 DECLARE_NAPI_FUNCTION("getAudioStreamIdSync", GetAudioStreamIdSync),
80 DECLARE_NAPI_FUNCTION("setVolume", SetVolume),
81 DECLARE_NAPI_FUNCTION("getVolume", GetVolume),
82 DECLARE_NAPI_FUNCTION("getRendererInfo", GetRendererInfo),
83 DECLARE_NAPI_FUNCTION("getRendererInfoSync", GetRendererInfoSync),
84 DECLARE_NAPI_FUNCTION("getStreamInfo", GetStreamInfo),
85 DECLARE_NAPI_FUNCTION("getStreamInfoSync", GetStreamInfoSync),
86 DECLARE_NAPI_FUNCTION("setInterruptMode", SetInterruptMode),
87 DECLARE_NAPI_FUNCTION("setInterruptModeSync", SetInterruptModeSync),
88 DECLARE_NAPI_FUNCTION("getMinStreamVolume", GetMinStreamVolume),
89 DECLARE_NAPI_FUNCTION("getMinStreamVolumeSync", GetMinStreamVolumeSync),
90 DECLARE_NAPI_FUNCTION("getMaxStreamVolume", GetMaxStreamVolume),
91 DECLARE_NAPI_FUNCTION("getMaxStreamVolumeSync", GetMaxStreamVolumeSync),
92 DECLARE_NAPI_FUNCTION("getCurrentOutputDevices", GetCurrentOutputDevices),
93 DECLARE_NAPI_FUNCTION("getCurrentOutputDevicesSync", GetCurrentOutputDevicesSync),
94 DECLARE_NAPI_FUNCTION("getUnderflowCount", GetUnderflowCount),
95 DECLARE_NAPI_FUNCTION("getUnderflowCountSync", GetUnderflowCountSync),
96 DECLARE_NAPI_FUNCTION("getAudioEffectMode", GetAudioEffectMode),
97 DECLARE_NAPI_FUNCTION("setAudioEffectMode", SetAudioEffectMode),
98 DECLARE_NAPI_FUNCTION("setChannelBlendMode", SetChannelBlendMode),
99 DECLARE_NAPI_FUNCTION("setVolumeWithRamp", SetVolumeWithRamp),
100 DECLARE_NAPI_FUNCTION("setSpeed", SetSpeed),
101 DECLARE_NAPI_FUNCTION("getSpeed", GetSpeed),
102 DECLARE_NAPI_GETTER("state", GetState),
103 DECLARE_NAPI_FUNCTION("on", On),
104 DECLARE_NAPI_FUNCTION("off", Off),
105 DECLARE_NAPI_FUNCTION("setSilentModeAndMixWithOthers", SetSilentModeAndMixWithOthers),
106 DECLARE_NAPI_FUNCTION("getSilentModeAndMixWithOthers", GetSilentModeAndMixWithOthers),
107 DECLARE_NAPI_FUNCTION("getAudioTimestampInfo", GetAudioTimestampInfo),
108 DECLARE_NAPI_FUNCTION("getAudioTimestampInfoSync", GetAudioTimestampInfoSync),
109 DECLARE_NAPI_FUNCTION("setDefaultOutputDevice", SetDefaultOutputDevice),
110 };
111
112 napi_status status = napi_define_class(env, NAPI_AUDIO_RENDERER_CLASS_NAME.c_str(),
113 NAPI_AUTO_LENGTH, Construct, nullptr,
114 sizeof(audio_renderer_properties) / sizeof(audio_renderer_properties[PARAM0]),
115 audio_renderer_properties, &constructor);
116 return status;
117 }
118
Init(napi_env env,napi_value exports)119 napi_value NapiAudioRenderer::Init(napi_env env, napi_value exports)
120 {
121 napi_status status;
122 napi_value constructor;
123 napi_value result = nullptr;
124 const int32_t refCount = 1;
125 napi_get_undefined(env, &result);
126
127 napi_property_descriptor static_prop[] = {
128 DECLARE_NAPI_STATIC_FUNCTION("createAudioRenderer", CreateAudioRenderer),
129 DECLARE_NAPI_STATIC_FUNCTION("createAudioRendererSync", CreateAudioRendererSync),
130 };
131
132 status = InitNapiAudioRenderer(env, constructor);
133 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "InitNapiAudioRenderer fail");
134
135 status = napi_create_reference(env, constructor, refCount, &g_rendererConstructor);
136 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_reference fail");
137 status = napi_set_named_property(env, exports, NAPI_AUDIO_RENDERER_CLASS_NAME.c_str(), constructor);
138 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_set_named_property fail");
139 status = napi_define_properties(env, exports,
140 sizeof(static_prop) / sizeof(static_prop[PARAM0]), static_prop);
141 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_define_properties fail");
142 return exports;
143 }
144
GetCallback(size_t argc,napi_value * argv)145 napi_value NapiAudioRenderer::GetCallback(size_t argc, napi_value *argv)
146 {
147 napi_value callback = nullptr;
148
149 if (argc == ARGS_TWO) {
150 callback = argv[PARAM1];
151 }
152 return callback;
153 }
154
155 template <typename T>
GetRendererNapiCallback(napi_value callback,const std::string & cbName,std::list<std::shared_ptr<NapiAudioRendererCallbackInner>> audioRendererCallbacks,std::shared_ptr<T> * cb)156 static void GetRendererNapiCallback(napi_value callback, const std::string &cbName,
157 std::list<std::shared_ptr<NapiAudioRendererCallbackInner>> audioRendererCallbacks, std::shared_ptr<T> *cb)
158 {
159 if (audioRendererCallbacks.size() == 0) {
160 AUDIO_ERR_LOG("no callback to get");
161 return;
162 }
163 for (auto &iter : audioRendererCallbacks) {
164 if (!iter->CheckIfTargetCallbackName(cbName)) {
165 continue;
166 }
167 std::shared_ptr<T> temp = std::static_pointer_cast<T>(iter);
168 if (temp->ContainSameJsCallbackInner(cbName, callback)) {
169 *cb = temp;
170 return;
171 }
172 }
173 }
174
175 template <typename T>
UnregisterAudioRendererSingletonCallbackTemplate(napi_env env,napi_value callback,const std::string & cbName,std::shared_ptr<T> cb,std::function<int32_t (std::shared_ptr<T> callbackPtr,napi_value callback)> removeFunction=nullptr)176 static void UnregisterAudioRendererSingletonCallbackTemplate(napi_env env, napi_value callback,
177 const std::string &cbName, std::shared_ptr<T> cb,
178 std::function<int32_t(std::shared_ptr<T> callbackPtr, napi_value callback)> removeFunction = nullptr)
179 {
180 if (callback != nullptr) {
181 CHECK_AND_RETURN_LOG(cb->ContainSameJsCallbackInner(cbName, callback), "callback not exists!");
182 }
183 cb->RemoveCallbackReference(cbName, env, callback);
184
185 if (removeFunction == nullptr) {
186 return;
187 }
188 int32_t ret = removeFunction(cb, callback);
189 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Unset of Renderer info change call failed");
190 return;
191 }
192
CreateRendererFailed()193 void NapiAudioRenderer::CreateRendererFailed()
194 {
195 NapiAudioRenderer::isConstructSuccess_ = NAPI_ERR_SYSTEM;
196 if (AudioRenderer::CheckMaxRendererInstances() == ERR_OVERFLOW) {
197 NapiAudioRenderer::isConstructSuccess_ = NAPI_ERR_STREAM_LIMIT;
198 }
199 AUDIO_ERR_LOG("Renderer Create failed %{public}d", isConstructSuccess_);
200 }
201
CreateAudioRendererNativeObject(napi_env env)202 unique_ptr<NapiAudioRenderer> NapiAudioRenderer::CreateAudioRendererNativeObject(napi_env env)
203 {
204 unique_ptr<NapiAudioRenderer> rendererNapi = make_unique<NapiAudioRenderer>();
205 CHECK_AND_RETURN_RET_LOG(rendererNapi != nullptr, nullptr, "No memory");
206
207 rendererNapi->env_ = env;
208 rendererNapi->contentType_ = sRendererOptions_->rendererInfo.contentType;
209 rendererNapi->streamUsage_ = sRendererOptions_->rendererInfo.streamUsage;
210
211 AudioRendererOptions rendererOptions = *sRendererOptions_;
212 /* NapiAudioRenderer not support other rendererFlags, only support flag 0 */
213 if (rendererOptions.rendererInfo.rendererFlags != 0) {
214 rendererOptions.rendererInfo.rendererFlags = 0;
215 }
216 rendererOptions.rendererInfo.playerType = PLAYER_TYPE_ARKTS_AUDIO_RENDERER;
217 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
218 rendererNapi->audioRenderer_ = AudioRenderer::CreateRenderer(rendererOptions);
219 #else
220 std::string cacheDir = "";
221 rendererNapi->audioRenderer_ = AudioRenderer::Create(cacheDir, rendererOptions);
222 #endif
223 if (rendererNapi->audioRenderer_ == nullptr) {
224 CreateRendererFailed();
225 rendererNapi.release();
226 return nullptr;
227 }
228
229 if (rendererNapi->streamUsage_ == STREAM_USAGE_UNKNOWN) {
230 rendererNapi->audioRenderer_->SetOffloadAllowed(false);
231 }
232
233 if (rendererNapi->audioRenderer_ != nullptr && rendererNapi->callbackNapi_ == nullptr) {
234 rendererNapi->callbackNapi_ = std::make_shared<NapiAudioRendererCallback>(env);
235 CHECK_AND_RETURN_RET_LOG(rendererNapi->callbackNapi_ != nullptr, nullptr, "No memory");
236 int32_t ret = rendererNapi->audioRenderer_->SetRendererCallback(rendererNapi->callbackNapi_);
237 CHECK_AND_RETURN_RET_LOG(!ret, rendererNapi, "Construct SetRendererCallback failed");
238 }
239 ObjectRefMap<NapiAudioRenderer>::Insert(rendererNapi.get());
240 return rendererNapi;
241 }
242
Construct(napi_env env,napi_callback_info info)243 napi_value NapiAudioRenderer::Construct(napi_env env, napi_callback_info info)
244 {
245 napi_value result = nullptr;
246 napi_get_undefined(env, &result);
247
248 size_t argCount = ARGS_TWO;
249 napi_value thisVar = nullptr;
250 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &thisVar, nullptr);
251 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "failed to napi_get_cb_info");
252
253 unique_ptr<NapiAudioRenderer> rendererNapi = CreateAudioRendererNativeObject(env);
254 CHECK_AND_RETURN_RET_LOG(rendererNapi != nullptr, result, "failed to CreateAudioRendererNativeObject");
255
256 status = napi_wrap(env, thisVar, static_cast<void*>(rendererNapi.get()),
257 NapiAudioRenderer::Destructor, nullptr, nullptr);
258 if (status != napi_ok) {
259 ObjectRefMap<NapiAudioRenderer>::Erase(rendererNapi.get());
260 return result;
261 }
262 rendererNapi.release();
263 return thisVar;
264 }
265
CheckContextStatus(std::shared_ptr<AudioRendererAsyncContext> context)266 bool NapiAudioRenderer::CheckContextStatus(std::shared_ptr<AudioRendererAsyncContext> context)
267 {
268 CHECK_AND_RETURN_RET_LOG(context != nullptr, false, "context object is nullptr.");
269 if (context->native == nullptr) {
270 context->SignError(NAPI_ERR_SYSTEM);
271 return false;
272 }
273 return true;
274 }
275
CheckAudioRendererStatus(NapiAudioRenderer * napi,std::shared_ptr<AudioRendererAsyncContext> context)276 bool NapiAudioRenderer::CheckAudioRendererStatus(NapiAudioRenderer *napi,
277 std::shared_ptr<AudioRendererAsyncContext> context)
278 {
279 CHECK_AND_RETURN_RET_LOG(napi != nullptr, false, "napi object is nullptr.");
280 if (napi->audioRenderer_ == nullptr) {
281 context->SignError(NAPI_ERR_SYSTEM);
282 return false;
283 }
284 return true;
285 }
286
GetParamWithSync(const napi_env & env,napi_callback_info info,size_t & argc,napi_value * args)287 NapiAudioRenderer* NapiAudioRenderer::GetParamWithSync(const napi_env &env, napi_callback_info info,
288 size_t &argc, napi_value *args)
289 {
290 NapiAudioRenderer *napiAudioRenderer = nullptr;
291 napi_value jsThis = nullptr;
292
293 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
294 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr,
295 "GetParamWithSync fail to napi_get_cb_info");
296
297 status = napi_unwrap(env, jsThis, (void **)&napiAudioRenderer);
298 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "napi_unwrap failed");
299 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr && napiAudioRenderer->audioRenderer_ != nullptr,
300 napiAudioRenderer, "GetParamWithSync fail to napi_unwrap");
301 return napiAudioRenderer;
302 }
303
CreateAudioRendererWrapper(napi_env env,const AudioRendererOptions rendererOptions)304 napi_value NapiAudioRenderer::CreateAudioRendererWrapper(napi_env env, const AudioRendererOptions rendererOptions)
305 {
306 lock_guard<mutex> lock(createMutex_);
307 napi_value result = nullptr;
308 napi_value constructor;
309
310 napi_status status = napi_get_reference_value(env, g_rendererConstructor, &constructor);
311 if (status != napi_ok) {
312 AUDIO_ERR_LOG("Failed in CreateAudioRendererWrapper, %{public}d", status);
313 goto fail;
314 }
315
316 sRendererOptions_ = make_unique<AudioRendererOptions>();
317 CHECK_AND_RETURN_RET_LOG(sRendererOptions_ != nullptr, result, "sRendererOptions_ create failed");
318 *sRendererOptions_ = rendererOptions;
319 status = napi_new_instance(env, constructor, 0, nullptr, &result);
320 if (status != napi_ok) {
321 AUDIO_ERR_LOG("napi_new_instance failed, status:%{public}d", status);
322 goto fail;
323 }
324 return result;
325
326 fail:
327 napi_get_undefined(env, &result);
328 return result;
329 }
330
CreateAudioRenderer(napi_env env,napi_callback_info info)331 napi_value NapiAudioRenderer::CreateAudioRenderer(napi_env env, napi_callback_info info)
332 {
333 auto context = std::make_shared<AudioRendererAsyncContext>();
334 if (context == nullptr) {
335 AUDIO_ERR_LOG("CreateAudioRenderer failed : no memory");
336 NapiAudioError::ThrowError(env, "CreateAudioRenderer failed : no memory",
337 NAPI_ERR_NO_MEMORY);
338 return NapiParamUtils::GetUndefinedValue(env);
339 }
340
341 auto inputParser = [env, context](size_t argc, napi_value *argv) {
342 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
343 NAPI_ERR_INVALID_PARAM);
344 context->status = NapiParamUtils::GetRendererOptions(env, &context->rendererOptions, argv[PARAM0]);
345 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get audioRendererRate failed",
346 NAPI_ERR_INVALID_PARAM);
347 };
348 context->GetCbInfo(env, info, inputParser);
349
350 auto complete = [env, context](napi_value &output) {
351 output = CreateAudioRendererWrapper(env, context->rendererOptions);
352
353 // IsConstructSuccess_ Used when creating a renderer fails.
354 if (isConstructSuccess_ != SUCCESS) {
355 context->SignError(isConstructSuccess_);
356 isConstructSuccess_ = SUCCESS;
357 }
358 };
359
360 return NapiAsyncWork::Enqueue(env, context, "CreateAudioRenderer", nullptr, complete);
361 }
362
CreateAudioRendererSync(napi_env env,napi_callback_info info)363 napi_value NapiAudioRenderer::CreateAudioRendererSync(napi_env env, napi_callback_info info)
364 {
365 AUDIO_INFO_LOG("CreateAudioRendererSync");
366 size_t argc = ARGS_ONE;
367 napi_value argv[ARGS_ONE] = {};
368 napi_status status = NapiParamUtils::GetParam(env, info, argc, argv);
369 CHECK_AND_RETURN_RET_LOG((argc == ARGS_ONE) && (status == napi_ok),
370 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "GetParam failed");
371
372 napi_valuetype valueType = napi_undefined;
373 napi_typeof(env, argv[PARAM0], &valueType);
374 CHECK_AND_RETURN_RET_LOG(valueType == napi_object,
375 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "valueType invaild");
376
377 AudioRendererOptions rendererOptions;
378 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::GetRendererOptions(env, &rendererOptions, argv[PARAM0]) == napi_ok,
379 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM), "GetRendererOptions failed");
380
381 return NapiAudioRenderer::CreateAudioRendererWrapper(env, rendererOptions);
382 }
383
SetRenderRate(napi_env env,napi_callback_info info)384 napi_value NapiAudioRenderer::SetRenderRate(napi_env env, napi_callback_info info)
385 {
386 auto context = std::make_shared<AudioRendererAsyncContext>();
387 if (context == nullptr) {
388 AUDIO_ERR_LOG("SetRenderRate failed : no memory");
389 NapiAudioError::ThrowError(env, "SetRenderRate failed : no memory", 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_ONE, "invalid arguments",
395 NAPI_ERR_INVALID_PARAM);
396 context->status = NapiParamUtils::GetValueInt32(env, context->audioRendererRate, argv[PARAM0]);
397 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get audioRendererRate failed",
398 NAPI_ERR_INVALID_PARAM);
399 };
400 context->GetCbInfo(env, info, inputParser);
401
402 auto executor = [context]() {
403 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
404 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
405 ObjectRefMap objectGuard(obj);
406 auto *napiAudioRenderer = objectGuard.GetPtr();
407 AudioRendererRate audioRenderRate = static_cast<AudioRendererRate>(context->audioRendererRate);
408 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
409 "context object state is error.");
410 int32_t audioClientInvalidParamsErr = -2;
411 context->intValue = napiAudioRenderer->audioRenderer_->SetRenderRate(audioRenderRate);
412 if (context->intValue != SUCCESS) {
413 if (context->intValue == audioClientInvalidParamsErr) {
414 context->SignError(NAPI_ERR_UNSUPPORTED);
415 } else {
416 context->SignError(NAPI_ERR_SYSTEM);
417 }
418 }
419 };
420 auto complete = [env](napi_value &output) {
421 output = NapiParamUtils::GetUndefinedValue(env);
422 };
423 return NapiAsyncWork::Enqueue(env, context, "SetRenderRate", executor, complete);
424 }
425
GetRenderRate(napi_env env,napi_callback_info info)426 napi_value NapiAudioRenderer::GetRenderRate(napi_env env, napi_callback_info info)
427 {
428 auto context = std::make_shared<AudioRendererAsyncContext>();
429 if (context == nullptr) {
430 AUDIO_ERR_LOG("GetRenderRate failed : no memory");
431 NapiAudioError::ThrowError(env, "GetRenderRate failed : no memory", NAPI_ERR_NO_MEMORY);
432 return NapiParamUtils::GetUndefinedValue(env);
433 }
434
435 context->GetCbInfo(env, info);
436
437 auto executor = [context]() {
438 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
439 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
440 ObjectRefMap objectGuard(obj);
441 auto *napiAudioRenderer = objectGuard.GetPtr();
442 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
443 "context object state is error.");
444 context->intValue = napiAudioRenderer->audioRenderer_->GetRenderRate();
445 };
446 auto complete = [env, context](napi_value &output) {
447 NapiParamUtils::SetValueInt32(env, context->intValue, output);
448 };
449 return NapiAsyncWork::Enqueue(env, context, "GetRenderRate", executor, complete);
450 }
451
GetRenderRateSync(napi_env env,napi_callback_info info)452 napi_value NapiAudioRenderer::GetRenderRateSync(napi_env env, napi_callback_info info)
453 {
454 napi_value result = nullptr;
455 size_t argc = PARAM0;
456 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
457 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
458 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
459
460 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
461 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
462 AudioRendererRate rendererRate = napiAudioRenderer->audioRenderer_->GetRenderRate();
463 NapiParamUtils::SetValueInt32(env, static_cast<int32_t>(rendererRate), result);
464 return result;
465 }
466
SetRendererSamplingRate(napi_env env,napi_callback_info info)467 napi_value NapiAudioRenderer::SetRendererSamplingRate(napi_env env, napi_callback_info info)
468 {
469 auto context = std::make_shared<AudioRendererAsyncContext>();
470 if (context == nullptr) {
471 AUDIO_ERR_LOG("SetRendererSamplingRate failed : no memory");
472 NapiAudioError::ThrowError(env, "SetRendererSamplingRate failed : no memory",
473 NAPI_ERR_NO_MEMORY);
474 return NapiParamUtils::GetUndefinedValue(env);
475 }
476
477 auto inputParser = [env, context](size_t argc, napi_value *argv) {
478 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
479 NAPI_ERR_INVALID_PARAM);
480 context->status = NapiParamUtils::GetValueUInt32(env, context->rendererSampleRate, argv[PARAM0]);
481 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get RendererSamplingRate failed",
482 NAPI_ERR_INVALID_PARAM);
483 };
484
485 context->GetCbInfo(env, info, inputParser);
486
487 auto executor = [context]() {
488 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
489 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
490 ObjectRefMap objectGuard(obj);
491 auto *napiAudioRenderer = objectGuard.GetPtr();
492 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
493 "context object state is error.");
494 if (context->rendererSampleRate <= 0) {
495 context->SignError(NAPI_ERR_UNSUPPORTED);
496 return;
497 }
498 context->intValue =
499 napiAudioRenderer->audioRenderer_->SetRendererSamplingRate(context->rendererSampleRate);
500 if (context->intValue != SUCCESS) {
501 context->SignError(NAPI_ERR_SYSTEM);
502 }
503 };
504
505 auto complete = [env](napi_value &output) {
506 output = NapiParamUtils::GetUndefinedValue(env);
507 };
508 return NapiAsyncWork::Enqueue(env, context, "SetRendererSamplingRate", executor, complete);
509 }
510
GetRendererSamplingRate(napi_env env,napi_callback_info info)511 napi_value NapiAudioRenderer::GetRendererSamplingRate(napi_env env, napi_callback_info info)
512 {
513 auto context = std::make_shared<AudioRendererAsyncContext>();
514 if (context == nullptr) {
515 AUDIO_ERR_LOG("GetRendererSamplingRate failed : no memory");
516 NapiAudioError::ThrowError(env, "GetRendererSamplingRate failed : no memory",
517 NAPI_ERR_NO_MEMORY);
518 return NapiParamUtils::GetUndefinedValue(env);
519 }
520
521 context->GetCbInfo(env, info);
522
523 auto executor = [context]() {
524 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
525 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
526 ObjectRefMap objectGuard(obj);
527 auto *napiAudioRenderer = objectGuard.GetPtr();
528 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
529 "context object state is error.");
530 context->rendererSampleRate = napiAudioRenderer->audioRenderer_->GetRendererSamplingRate();
531 };
532
533 auto complete = [env, context](napi_value &output) {
534 NapiParamUtils::SetValueUInt32(env, context->rendererSampleRate, output);
535 };
536 return NapiAsyncWork::Enqueue(env, context, "GetRendererSamplingRate", executor, complete);
537 }
538
Start(napi_env env,napi_callback_info info)539 napi_value NapiAudioRenderer::Start(napi_env env, napi_callback_info info)
540 {
541 auto context = std::make_shared<AudioRendererAsyncContext>();
542 if (context == nullptr) {
543 AUDIO_ERR_LOG("Start failed : no memory");
544 NapiAudioError::ThrowError(env, "Start failed : no memory", NAPI_ERR_NO_MEMORY);
545 return NapiParamUtils::GetUndefinedValue(env);
546 }
547
548 context->GetCbInfo(env, info);
549 #ifdef FEATURE_HIVIEW_ENABLE
550 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
551 HiviewDFX::ReportXPowerJsStackSysEvent(env, "STREAM_CHANGE", "SRC=Audio");
552 #endif
553 #endif
554
555 auto executor = [context]() {
556 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
557 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
558 ObjectRefMap objectGuard(obj);
559 auto *napiAudioRenderer = objectGuard.GetPtr();
560 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
561 "context object state is error.");
562 context->isTrue = napiAudioRenderer->audioRenderer_->Start();
563 context->status = context->isTrue ? napi_ok : napi_generic_failure;
564 if (context->status != napi_ok) {
565 context->SignError(NAPI_ERR_SYSTEM);
566 }
567 };
568
569 auto complete = [env](napi_value &output) {
570 output = NapiParamUtils::GetUndefinedValue(env);
571 };
572 return NapiAsyncWork::Enqueue(env, context, "Start", executor, complete);
573 }
574
Write(napi_env env,napi_callback_info info)575 napi_value NapiAudioRenderer::Write(napi_env env, napi_callback_info info)
576 {
577 auto context = std::make_shared<AudioRendererAsyncContext>();
578 if (context == nullptr) {
579 AUDIO_ERR_LOG("Write failed : no memory");
580 NapiAudioError::ThrowError(env, "Write failed : no memory", NAPI_ERR_NO_MEMORY);
581 return NapiParamUtils::GetUndefinedValue(env);
582 }
583
584 auto inputParser = [env, context](size_t argc, napi_value *argv) {
585 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
586 NAPI_ERR_INVALID_PARAM);
587 context->status = NapiParamUtils::GetArrayBuffer(env, context->data, context->bufferLen, argv[PARAM0]);
588 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get buffer failed",
589 NAPI_ERR_INVALID_PARAM);
590 };
591
592 context->GetCbInfo(env, info, inputParser);
593
594 auto executor = [context]() {
595 context->status = WriteArrayBufferToNative(context);
596 if (context->status != napi_ok) {
597 context->SignError(NAPI_ERR_SYSTEM);
598 }
599 };
600
601 auto complete = [env, context](napi_value &output) {
602 NapiParamUtils::SetValueUInt32(env, context->totalBytesWritten, output);
603 };
604 return NapiAsyncWork::Enqueue(env, context, "Write", executor, complete);
605 }
606
WriteArrayBufferToNative(std::shared_ptr<AudioRendererAsyncContext> context)607 napi_status NapiAudioRenderer::WriteArrayBufferToNative(std::shared_ptr<AudioRendererAsyncContext> context)
608 {
609 CHECK_AND_RETURN_RET_LOG(CheckContextStatus(context), napi_generic_failure, "context object state is error.");
610 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
611 ObjectRefMap objectGuard(obj);
612 auto *napiAudioRenderer = objectGuard.GetPtr();
613 CHECK_AND_RETURN_RET_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
614 napi_generic_failure, "context object state is error.");
615 size_t bufferLen = context->bufferLen;
616 context->status = napi_generic_failure;
617 auto buffer = std::make_unique<uint8_t[]>(bufferLen);
618 CHECK_AND_RETURN_RET_LOG(buffer != nullptr, napi_generic_failure, "Renderer write buffer allocation failed");
619 if (memcpy_s(buffer.get(), bufferLen, context->data, bufferLen)) {
620 AUDIO_ERR_LOG("Renderer mem copy failed");
621 return napi_generic_failure;
622 }
623 int32_t bytesWritten = 0;
624 size_t totalBytesWritten = 0;
625 size_t minBytes = 4;
626 while ((totalBytesWritten < bufferLen) && ((bufferLen - totalBytesWritten) > minBytes)) {
627 bytesWritten = napiAudioRenderer->audioRenderer_->Write(buffer.get() + totalBytesWritten,
628 bufferLen - totalBytesWritten);
629 if (bytesWritten < 0) {
630 AUDIO_ERR_LOG("Write length < 0,break.");
631 break;
632 }
633 totalBytesWritten += static_cast<size_t>(bytesWritten);
634 }
635 context->status = napi_ok;
636 context->totalBytesWritten = totalBytesWritten;
637 return context->status;
638 }
639
GetAudioTime(napi_env env,napi_callback_info info)640 napi_value NapiAudioRenderer::GetAudioTime(napi_env env, napi_callback_info info)
641 {
642 auto context = std::make_shared<AudioRendererAsyncContext>();
643 if (context == nullptr) {
644 AUDIO_ERR_LOG("GetAudioTime failed : no memory");
645 NapiAudioError::ThrowError(env, "GetAudioTime failed : no memory", NAPI_ERR_NO_MEMORY);
646 return NapiParamUtils::GetUndefinedValue(env);
647 }
648
649 context->GetCbInfo(env, info);
650
651 auto executor = [context]() {
652 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
653 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
654 ObjectRefMap objectGuard(obj);
655 auto *napiAudioRenderer = objectGuard.GetPtr();
656 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
657 "context object state is error.");
658 Timestamp timestamp;
659 if (napiAudioRenderer->audioRenderer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC)) {
660 const uint64_t secToNanosecond = 1000000000;
661 context->time = static_cast<uint64_t>(timestamp.time.tv_nsec) +
662 static_cast<uint64_t>(timestamp.time.tv_sec) * secToNanosecond;
663 context->status = napi_ok;
664 } else {
665 context->SignError(NAPI_ERR_SYSTEM);
666 }
667 };
668
669 auto complete = [env, context](napi_value &output) {
670 NapiParamUtils::SetValueInt64(env, context->time, output);
671 };
672 return NapiAsyncWork::Enqueue(env, context, "GetAudioTime", executor, complete);
673 }
674
GetAudioTimeSync(napi_env env,napi_callback_info info)675 napi_value NapiAudioRenderer::GetAudioTimeSync(napi_env env, napi_callback_info info)
676 {
677 napi_value result = nullptr;
678 size_t argc = PARAM0;
679 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
680 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
681 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
682
683 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
684 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
685 Timestamp timestamp;
686 bool ret = napiAudioRenderer->audioRenderer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC);
687 CHECK_AND_RETURN_RET_LOG(ret, result, "GetAudioTime failure!");
688
689 const uint64_t secToNanosecond = 1000000000;
690 uint64_t time = static_cast<uint64_t>(timestamp.time.tv_nsec) +
691 static_cast<uint64_t>(timestamp.time.tv_sec) * secToNanosecond;
692
693 NapiParamUtils::SetValueInt64(env, time, result);
694 return result;
695 }
696
GetAudioTimestampInfo(napi_env env,napi_callback_info info)697 napi_value NapiAudioRenderer::GetAudioTimestampInfo(napi_env env, napi_callback_info info)
698 {
699 auto context = std::make_shared<AudioRendererAsyncContext>();
700 if (context == nullptr) {
701 AUDIO_ERR_LOG("GetAudioTimestampInfo failed : no memory");
702 NapiAudioError::ThrowError(env, "GetAudioTimestampInfo failed : no memory", NAPI_ERR_NO_MEMORY);
703 return NapiParamUtils::GetUndefinedValue(env);
704 }
705
706 context->GetCbInfo(env, info);
707
708 auto executor = [context]() {
709 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
710 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
711 ObjectRefMap objectGuard(obj);
712 auto *napiAudioRenderer = objectGuard.GetPtr();
713 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
714 "context object state is error.");
715 int32_t ret = napiAudioRenderer->audioRenderer_->GetAudioTimestampInfo(context->timeStamp,
716 Timestamp::Timestampbase::MONOTONIC);
717 if (ret != SUCCESS) {
718 context->SignError(NAPI_ERR_SYSTEM);
719 }
720 };
721
722 auto complete = [env, context](napi_value &output) {
723 NapiParamUtils::SetTimeStampInfo(env, context->timeStamp, output);
724 };
725
726 return NapiAsyncWork::Enqueue(env, context, "GetAudioTimestampInfo", executor, complete);
727 }
728
GetAudioTimestampInfoSync(napi_env env,napi_callback_info info)729 napi_value NapiAudioRenderer::GetAudioTimestampInfoSync(napi_env env, napi_callback_info info)
730 {
731 napi_value result = nullptr;
732 size_t argc = PARAM0;
733 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
734 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
735 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
736
737 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
738 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
739
740 Timestamp timeStamp;
741 int32_t ret = napiAudioRenderer->audioRenderer_->GetAudioTimestampInfo(timeStamp,
742 Timestamp::Timestampbase::MONOTONIC);
743 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetAudioTimeStamp failure!");
744
745 NapiParamUtils::SetTimeStampInfo(env, timeStamp, result);
746 return result;
747 }
748
Drain(napi_env env,napi_callback_info info)749 napi_value NapiAudioRenderer::Drain(napi_env env, napi_callback_info info)
750 {
751 auto context = std::make_shared<AudioRendererAsyncContext>();
752 if (context == nullptr) {
753 AUDIO_ERR_LOG("Drain failed : no memory");
754 NapiAudioError::ThrowError(env, "Drain failed : no memory", NAPI_ERR_NO_MEMORY);
755 return NapiParamUtils::GetUndefinedValue(env);
756 }
757
758 context->GetCbInfo(env, info);
759
760 auto executor = [context]() {
761 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
762 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
763 ObjectRefMap objectGuard(obj);
764 auto *napiAudioRenderer = objectGuard.GetPtr();
765 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
766 "context object state is error.");
767 context->isTrue = napiAudioRenderer->audioRenderer_->Drain();
768 if (!context->isTrue) {
769 context->SignError(NAPI_ERR_SYSTEM);
770 }
771 };
772 auto complete = [env](napi_value &output) {
773 output = NapiParamUtils::GetUndefinedValue(env);
774 };
775 return NapiAsyncWork::Enqueue(env, context, "Drain", executor, complete);
776 }
777
Flush(napi_env env,napi_callback_info info)778 napi_value NapiAudioRenderer::Flush(napi_env env, napi_callback_info info)
779 {
780 auto context = std::make_shared<AudioRendererAsyncContext>();
781 if (context == nullptr) {
782 AUDIO_ERR_LOG("Flush failed : no memory");
783 NapiAudioError::ThrowError(env, "Flush failed : no memory", NAPI_ERR_NO_MEMORY);
784 return NapiParamUtils::GetUndefinedValue(env);
785 }
786
787 context->GetCbInfo(env, info, nullptr, true);
788
789 auto executor = [context]() {
790 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
791 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
792 ObjectRefMap objectGuard(obj);
793 auto *napiAudioRenderer = objectGuard.GetPtr();
794 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
795 "context object state is error.");
796 context->isTrue = napiAudioRenderer->audioRenderer_->Flush();
797 if (!context->isTrue) {
798 context->SignError(NAPI_ERR_ILLEGAL_STATE);
799 }
800 };
801 auto complete = [env](napi_value &output) {
802 output = NapiParamUtils::GetUndefinedValue(env);
803 };
804 return NapiAsyncWork::Enqueue(env, context, "Flush", executor, complete);
805 }
806
Pause(napi_env env,napi_callback_info info)807 napi_value NapiAudioRenderer::Pause(napi_env env, napi_callback_info info)
808 {
809 auto context = std::make_shared<AudioRendererAsyncContext>();
810 if (context == nullptr) {
811 AUDIO_ERR_LOG("Pause failed : no memory");
812 NapiAudioError::ThrowError(env, "Pause failed : no memory", NAPI_ERR_NO_MEMORY);
813 return NapiParamUtils::GetUndefinedValue(env);
814 }
815
816 context->GetCbInfo(env, info);
817
818 auto executor = [context]() {
819 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
820 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
821 ObjectRefMap objectGuard(obj);
822 auto *napiAudioRenderer = objectGuard.GetPtr();
823 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
824 "context object state is error.");
825 context->isTrue = napiAudioRenderer->audioRenderer_->Pause();
826 if (!context->isTrue) {
827 context->SignError(NAPI_ERR_SYSTEM);
828 }
829 };
830 auto complete = [env](napi_value &output) {
831 output = NapiParamUtils::GetUndefinedValue(env);
832 };
833 return NapiAsyncWork::Enqueue(env, context, "Pause", executor, complete);
834 }
835
Stop(napi_env env,napi_callback_info info)836 napi_value NapiAudioRenderer::Stop(napi_env env, napi_callback_info info)
837 {
838 auto context = std::make_shared<AudioRendererAsyncContext>();
839 if (context == nullptr) {
840 AUDIO_ERR_LOG("Stop failed : no memory");
841 NapiAudioError::ThrowError(env, "Stop failed : no memory", NAPI_ERR_NO_MEMORY);
842 return NapiParamUtils::GetUndefinedValue(env);
843 }
844
845 context->GetCbInfo(env, info);
846
847 auto executor = [context]() {
848 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
849 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
850 ObjectRefMap objectGuard(obj);
851 auto *napiAudioRenderer = objectGuard.GetPtr();
852 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
853 "context object state is error.");
854 context->isTrue = napiAudioRenderer->audioRenderer_->Stop();
855 if (!context->isTrue) {
856 context->SignError(NAPI_ERR_SYSTEM);
857 }
858 };
859 auto complete = [env](napi_value &output) {
860 output = NapiParamUtils::GetUndefinedValue(env);
861 };
862 return NapiAsyncWork::Enqueue(env, context, "Stop", executor, complete);
863 }
864
Release(napi_env env,napi_callback_info info)865 napi_value NapiAudioRenderer::Release(napi_env env, napi_callback_info info)
866 {
867 auto context = std::make_shared<AudioRendererAsyncContext>();
868 if (context == nullptr) {
869 AUDIO_ERR_LOG("Release failed : no memory");
870 NapiAudioError::ThrowError(env, "Release failed : no memory", NAPI_ERR_NO_MEMORY);
871 return NapiParamUtils::GetUndefinedValue(env);
872 }
873
874 context->GetCbInfo(env, info);
875
876 auto executor = [context]() {
877 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
878 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
879 ObjectRefMap objectGuard(obj);
880 auto *napiAudioRenderer = objectGuard.GetPtr();
881 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
882 "context object state is error.");
883 context->isTrue = napiAudioRenderer->audioRenderer_->Release();
884 if (!context->isTrue) {
885 context->SignError(NAPI_ERR_SYSTEM);
886 }
887 };
888 auto complete = [env](napi_value &output) {
889 output = NapiParamUtils::GetUndefinedValue(env);
890 };
891 return NapiAsyncWork::Enqueue(env, context, "Release", executor, complete);
892 }
893
GetBufferSize(napi_env env,napi_callback_info info)894 napi_value NapiAudioRenderer::GetBufferSize(napi_env env, napi_callback_info info)
895 {
896 auto context = std::make_shared<AudioRendererAsyncContext>();
897 if (context == nullptr) {
898 AUDIO_ERR_LOG("GetBufferSize failed : no memory");
899 NapiAudioError::ThrowError(env, "GetBufferSize failed : no memory", NAPI_ERR_NO_MEMORY);
900 return NapiParamUtils::GetUndefinedValue(env);
901 }
902
903 context->GetCbInfo(env, info);
904
905 auto executor = [context]() {
906 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
907 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
908 ObjectRefMap objectGuard(obj);
909 auto *napiAudioRenderer = objectGuard.GetPtr();
910 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
911 "context object state is error.");
912 size_t bufferSize;
913 context->intValue = napiAudioRenderer->audioRenderer_->GetBufferSize(bufferSize);
914 if (context->intValue != SUCCESS) {
915 context->SignError(NAPI_ERR_SYSTEM);
916 } else {
917 context->bufferSize = bufferSize;
918 }
919 };
920 auto complete = [env, context](napi_value &output) {
921 NapiParamUtils::SetValueUInt32(env, context->bufferSize, output);
922 };
923 return NapiAsyncWork::Enqueue(env, context, "GetBufferSize", executor, complete);
924 }
925
GetBufferSizeSync(napi_env env,napi_callback_info info)926 napi_value NapiAudioRenderer::GetBufferSizeSync(napi_env env, napi_callback_info info)
927 {
928 napi_value result = nullptr;
929 size_t argc = PARAM0;
930 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
931 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
932 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
933
934 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
935 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
936 size_t bufferSize;
937 int32_t ret = napiAudioRenderer->audioRenderer_->GetBufferSize(bufferSize);
938 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetBufferSize failure!");
939
940 NapiParamUtils::SetValueUInt32(env, bufferSize, result);
941 return result;
942 }
943
GetAudioStreamId(napi_env env,napi_callback_info info)944 napi_value NapiAudioRenderer::GetAudioStreamId(napi_env env, napi_callback_info info)
945 {
946 auto context = std::make_shared<AudioRendererAsyncContext>();
947 if (context == nullptr) {
948 AUDIO_ERR_LOG("GetAudioStreamId failed : no memory");
949 NapiAudioError::ThrowError(env, "GetAudioStreamId failed : no memory", NAPI_ERR_NO_MEMORY);
950 return NapiParamUtils::GetUndefinedValue(env);
951 }
952
953 context->GetCbInfo(env, info);
954
955 auto executor = [context]() {
956 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
957 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
958 ObjectRefMap objectGuard(obj);
959 auto *napiAudioRenderer = objectGuard.GetPtr();
960 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
961 "context object state is error.");
962 context->intValue = napiAudioRenderer->audioRenderer_->GetAudioStreamId(context->audioStreamId);
963 if (context->intValue == ERR_INVALID_INDEX) {
964 context->SignError(NAPI_ERR_SYSTEM);
965 } else if (context->intValue == ERR_ILLEGAL_STATE) {
966 context->SignError(NAPI_ERR_ILLEGAL_STATE);
967 }
968 };
969 auto complete = [env, context](napi_value &output) {
970 NapiParamUtils::SetValueUInt32(env, context->audioStreamId, output);
971 };
972 return NapiAsyncWork::Enqueue(env, context, "GetAudioStreamId", executor, complete);
973 }
974
GetAudioStreamIdSync(napi_env env,napi_callback_info info)975 napi_value NapiAudioRenderer::GetAudioStreamIdSync(napi_env env, napi_callback_info info)
976 {
977 napi_value result = nullptr;
978 size_t argc = PARAM0;
979 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
980 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
981 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
982
983 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
984 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
985 uint32_t audioStreamId;
986 int32_t streamIdStatus = napiAudioRenderer->audioRenderer_->GetAudioStreamId(audioStreamId);
987 CHECK_AND_RETURN_RET_LOG(streamIdStatus == SUCCESS, result, "GetAudioStreamId failure!");
988
989 NapiParamUtils::SetValueUInt32(env, audioStreamId, result);
990 return result;
991 }
992
SetVolume(napi_env env,napi_callback_info info)993 napi_value NapiAudioRenderer::SetVolume(napi_env env, napi_callback_info info)
994 {
995 auto context = std::make_shared<AudioRendererAsyncContext>();
996 if (context == nullptr) {
997 AUDIO_ERR_LOG("SetVolume failed : no memory");
998 NapiAudioError::ThrowError(env, "SetVolume failed : no memory", NAPI_ERR_NO_MEMORY);
999 return NapiParamUtils::GetUndefinedValue(env);
1000 }
1001
1002 auto inputParser = [env, context](size_t argc, napi_value *argv) {
1003 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
1004 NAPI_ERR_INVALID_PARAM);
1005 context->status = NapiParamUtils::GetValueDouble(env, context->volLevel, argv[PARAM0]);
1006 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get RendererSamplingRate failed",
1007 NAPI_ERR_INVALID_PARAM);
1008 };
1009
1010 context->GetCbInfo(env, info, inputParser);
1011
1012 auto executor = [context]() {
1013 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1014 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1015 ObjectRefMap objectGuard(obj);
1016 auto *napiAudioRenderer = objectGuard.GetPtr();
1017 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1018 "context object state is error.");
1019 if (context->volLevel < MIN_VOLUME_IN_DOUBLE || context->volLevel > MAX_VOLUME_IN_DOUBLE) {
1020 context->SignError(NAPI_ERR_UNSUPPORTED);
1021 return;
1022 }
1023 context->intValue = napiAudioRenderer->audioRenderer_->SetVolume(static_cast<float>(context->volLevel));
1024 if (context->intValue != SUCCESS) {
1025 context->SignError(NAPI_ERR_SYSTEM);
1026 }
1027 };
1028
1029 auto complete = [env](napi_value &output) {
1030 output = NapiParamUtils::GetUndefinedValue(env);
1031 };
1032 return NapiAsyncWork::Enqueue(env, context, "SetVolume", executor, complete);
1033 }
1034
GetVolume(napi_env env,napi_callback_info info)1035 napi_value NapiAudioRenderer::GetVolume(napi_env env, napi_callback_info info)
1036 {
1037 napi_value result = nullptr;
1038 size_t argc = PARAM0;
1039 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
1040 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1041 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1042
1043 double volLevel = napiAudioRenderer->audioRenderer_->GetVolume();
1044 NapiParamUtils::SetValueDouble(env, volLevel, result);
1045 return result;
1046 }
1047
GetRendererInfo(napi_env env,napi_callback_info info)1048 napi_value NapiAudioRenderer::GetRendererInfo(napi_env env, napi_callback_info info)
1049 {
1050 auto context = std::make_shared<AudioRendererAsyncContext>();
1051 if (context == nullptr) {
1052 AUDIO_ERR_LOG("GetRendererInfo failed : no memory");
1053 NapiAudioError::ThrowError(env, "GetRendererInfo failed : no memory", NAPI_ERR_NO_MEMORY);
1054 return NapiParamUtils::GetUndefinedValue(env);
1055 }
1056
1057 context->GetCbInfo(env, info);
1058
1059 auto executor = [context]() {
1060 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1061 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1062 ObjectRefMap objectGuard(obj);
1063 auto *napiAudioRenderer = objectGuard.GetPtr();
1064 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1065 "context object state is error.");
1066 context->intValue = napiAudioRenderer->audioRenderer_->GetRendererInfo(context->rendererInfo);
1067 if (context->intValue != SUCCESS) {
1068 context->SignError(NAPI_ERR_SYSTEM);
1069 }
1070 };
1071
1072 auto complete = [env, context](napi_value &output) {
1073 NapiParamUtils::SetRendererInfo(env, context->rendererInfo, output);
1074 };
1075 return NapiAsyncWork::Enqueue(env, context, "GetRendererInfo", executor, complete);
1076 }
1077
GetRendererInfoSync(napi_env env,napi_callback_info info)1078 napi_value NapiAudioRenderer::GetRendererInfoSync(napi_env env, napi_callback_info info)
1079 {
1080 napi_value result = nullptr;
1081 size_t argc = PARAM0;
1082 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
1083 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
1084 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
1085
1086 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1087 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1088 AudioRendererInfo rendererInfo = {};
1089 int32_t ret = napiAudioRenderer->audioRenderer_->GetRendererInfo(rendererInfo);
1090 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetRendererInfo failure!");
1091 NapiParamUtils::SetRendererInfo(env, rendererInfo, result);
1092 return result;
1093 }
1094
GetStreamInfo(napi_env env,napi_callback_info info)1095 napi_value NapiAudioRenderer::GetStreamInfo(napi_env env, napi_callback_info info)
1096 {
1097 auto context = std::make_shared<AudioRendererAsyncContext>();
1098 if (context == nullptr) {
1099 AUDIO_ERR_LOG("GetStreamInfo failed : no memory");
1100 NapiAudioError::ThrowError(env, "GetStreamInfo failed : no memory", NAPI_ERR_NO_MEMORY);
1101 return NapiParamUtils::GetUndefinedValue(env);
1102 }
1103
1104 context->GetCbInfo(env, info);
1105
1106 auto executor = [context]() {
1107 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1108 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1109 ObjectRefMap objectGuard(obj);
1110 auto *napiAudioRenderer = objectGuard.GetPtr();
1111 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1112 "context object state is error.");
1113 context->intValue = napiAudioRenderer->audioRenderer_->GetStreamInfo(context->streamInfo);
1114 if (context->intValue != SUCCESS) {
1115 context->SignError(NAPI_ERR_SYSTEM);
1116 }
1117 };
1118
1119 auto complete = [env, context](napi_value &output) {
1120 NapiParamUtils::SetStreamInfo(env, context->streamInfo, output);
1121 };
1122 return NapiAsyncWork::Enqueue(env, context, "GetStreamInfo", executor, complete);
1123 }
1124
GetStreamInfoSync(napi_env env,napi_callback_info info)1125 napi_value NapiAudioRenderer::GetStreamInfoSync(napi_env env, napi_callback_info info)
1126 {
1127 napi_value result = nullptr;
1128 size_t argc = PARAM0;
1129 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
1130 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
1131 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
1132
1133 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1134 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1135
1136 AudioStreamInfo streamInfo;
1137 int32_t ret = napiAudioRenderer->audioRenderer_->GetStreamInfo(streamInfo);
1138 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetStreamInfo failure!");
1139 NapiParamUtils::SetStreamInfo(env, streamInfo, result);
1140 return result;
1141 }
1142
SetInterruptMode(napi_env env,napi_callback_info info)1143 napi_value NapiAudioRenderer::SetInterruptMode(napi_env env, napi_callback_info info)
1144 {
1145 auto context = std::make_shared<AudioRendererAsyncContext>();
1146 if (context == nullptr) {
1147 AUDIO_ERR_LOG("SetInterruptMode failed : no memory");
1148 NapiAudioError::ThrowError(env, "SetInterruptMode failed : no memory", NAPI_ERR_NO_MEMORY);
1149 return NapiParamUtils::GetUndefinedValue(env);
1150 }
1151
1152 auto inputParser = [env, context](size_t argc, napi_value *argv) {
1153 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
1154 NAPI_ERR_INVALID_PARAM);
1155 context->status = NapiParamUtils::GetValueInt32(env, context->interruptMode, argv[PARAM0]);
1156 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get interruptMode failed",
1157 NAPI_ERR_INVALID_PARAM);
1158 };
1159 context->GetCbInfo(env, info, inputParser);
1160
1161 auto executor = [context]() {
1162 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1163 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1164 ObjectRefMap objectGuard(obj);
1165 auto *napiAudioRenderer = objectGuard.GetPtr();
1166 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1167 "context object state is error.");
1168 InterruptMode interruptMode = NapiAudioEnum::GetNativeInterruptMode(context->interruptMode);
1169 napiAudioRenderer->audioRenderer_->SetInterruptMode(interruptMode);
1170 };
1171
1172 auto complete = [env](napi_value &output) {
1173 output = NapiParamUtils::GetUndefinedValue(env);
1174 };
1175 return NapiAsyncWork::Enqueue(env, context, "SetInterruptMode", executor, complete);
1176 }
1177
SetInterruptModeSync(napi_env env,napi_callback_info info)1178 napi_value NapiAudioRenderer::SetInterruptModeSync(napi_env env, napi_callback_info info)
1179 {
1180 AUDIO_INFO_LOG("SetInterruptModeSync");
1181 napi_value result = nullptr;
1182 size_t argc = ARGS_ONE;
1183 napi_value args[ARGS_ONE] = {};
1184 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, args);
1185 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
1186 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argcCount invaild");
1187
1188 napi_valuetype valueType = napi_undefined;
1189 napi_typeof(env, args[PARAM0], &valueType);
1190 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
1191 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of mode must be number"),
1192 "valueType invaild");
1193
1194 int32_t interruptMode;
1195 NapiParamUtils::GetValueInt32(env, interruptMode, args[PARAM0]);
1196
1197 if (!NapiAudioEnum::IsLegalInputArgumentInterruptMode(interruptMode)) {
1198 NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
1199 "parameter verification failed: The param of mode must be enum InterruptMode");
1200 return result;
1201 }
1202 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1203 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1204 napiAudioRenderer->audioRenderer_->SetInterruptMode(NapiAudioEnum::GetNativeInterruptMode(interruptMode));
1205
1206 return result;
1207 }
1208
GetMinStreamVolume(napi_env env,napi_callback_info info)1209 napi_value NapiAudioRenderer::GetMinStreamVolume(napi_env env, napi_callback_info info)
1210 {
1211 auto context = std::make_shared<AudioRendererAsyncContext>();
1212 if (context == nullptr) {
1213 AUDIO_ERR_LOG("GetMinStreamVolume failed : no memory");
1214 NapiAudioError::ThrowError(env, "GetMinStreamVolume failed : no memory", NAPI_ERR_NO_MEMORY);
1215 return NapiParamUtils::GetUndefinedValue(env);
1216 }
1217
1218 context->GetCbInfo(env, info);
1219
1220 auto executor = [context]() {
1221 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1222 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1223 ObjectRefMap objectGuard(obj);
1224 auto *napiAudioRenderer = objectGuard.GetPtr();
1225 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1226 "context object state is error.");
1227 context->volLevel = napiAudioRenderer->audioRenderer_->GetMinStreamVolume();
1228 };
1229
1230 auto complete = [env, context](napi_value &output) {
1231 NapiParamUtils::SetValueDouble(env, context->volLevel, output);
1232 };
1233 return NapiAsyncWork::Enqueue(env, context, "GetMinStreamVolume", executor, complete);
1234 }
1235
GetMinStreamVolumeSync(napi_env env,napi_callback_info info)1236 napi_value NapiAudioRenderer::GetMinStreamVolumeSync(napi_env env, napi_callback_info info)
1237 {
1238 napi_value result = nullptr;
1239 size_t argc = PARAM0;
1240 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
1241 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
1242 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
1243
1244 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1245 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1246
1247 double volLevel = napiAudioRenderer->audioRenderer_->GetMinStreamVolume();
1248 NapiParamUtils::SetValueDouble(env, volLevel, result);
1249 return result;
1250 }
1251
GetMaxStreamVolume(napi_env env,napi_callback_info info)1252 napi_value NapiAudioRenderer::GetMaxStreamVolume(napi_env env, napi_callback_info info)
1253 {
1254 auto context = std::make_shared<AudioRendererAsyncContext>();
1255 if (context == nullptr) {
1256 AUDIO_ERR_LOG("GetMaxStreamVolume failed : no memory");
1257 NapiAudioError::ThrowError(env, "GetMaxStreamVolume failed : no memory", NAPI_ERR_NO_MEMORY);
1258 return NapiParamUtils::GetUndefinedValue(env);
1259 }
1260
1261 context->GetCbInfo(env, info);
1262
1263 auto executor = [context]() {
1264 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1265 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1266 ObjectRefMap objectGuard(obj);
1267 auto *napiAudioRenderer = objectGuard.GetPtr();
1268 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1269 "context object state is error.");
1270 context->volLevel = napiAudioRenderer->audioRenderer_->GetMaxStreamVolume();
1271 };
1272
1273 auto complete = [env, context](napi_value &output) {
1274 NapiParamUtils::SetValueDouble(env, context->volLevel, output);
1275 };
1276 return NapiAsyncWork::Enqueue(env, context, "GetMaxStreamVolume", executor, complete);
1277 }
1278
GetMaxStreamVolumeSync(napi_env env,napi_callback_info info)1279 napi_value NapiAudioRenderer::GetMaxStreamVolumeSync(napi_env env, napi_callback_info info)
1280 {
1281 napi_value result = nullptr;
1282 size_t argc = PARAM0;
1283 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
1284 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
1285 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
1286
1287 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1288 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1289
1290 double volLevel = napiAudioRenderer->audioRenderer_->GetMaxStreamVolume();
1291 NapiParamUtils::SetValueDouble(env, volLevel, result);
1292 return result;
1293 }
1294
GetCurrentOutputDevices(napi_env env,napi_callback_info info)1295 napi_value NapiAudioRenderer::GetCurrentOutputDevices(napi_env env, napi_callback_info info)
1296 {
1297 auto context = std::make_shared<AudioRendererAsyncContext>();
1298 if (context == nullptr) {
1299 AUDIO_ERR_LOG("GetCurrentOutputDevices failed : no memory");
1300 NapiAudioError::ThrowError(env, "GetCurrentOutputDevices failed : no memory",
1301 NAPI_ERR_NO_MEMORY);
1302 return NapiParamUtils::GetUndefinedValue(env);
1303 }
1304
1305 context->GetCbInfo(env, info);
1306
1307 auto executor = [context]() {
1308 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1309 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1310 ObjectRefMap objectGuard(obj);
1311 auto *napiAudioRenderer = objectGuard.GetPtr();
1312 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1313 "context object state is error.");
1314 AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
1315 context->intValue = napiAudioRenderer->audioRenderer_->GetCurrentOutputDevices(deviceInfo);
1316 if (context->intValue == ERR_INVALID_PARAM) {
1317 context->SignError(NAPI_ERROR_INVALID_PARAM);
1318 return;
1319 }
1320 context->deviceInfo = deviceInfo;
1321 };
1322
1323 auto complete = [env, context](napi_value &output) {
1324 NapiParamUtils::SetValueDeviceInfo(env, context->deviceInfo, output);
1325 };
1326 return NapiAsyncWork::Enqueue(env, context, "GetCurrentOutputDevices", executor, complete);
1327 }
1328
GetCurrentOutputDevicesSync(napi_env env,napi_callback_info info)1329 napi_value NapiAudioRenderer::GetCurrentOutputDevicesSync(napi_env env, napi_callback_info info)
1330 {
1331 napi_value result = nullptr;
1332 size_t argc = PARAM0;
1333 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
1334 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
1335 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
1336
1337 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1338 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1339
1340 AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
1341 int32_t ret = napiAudioRenderer->audioRenderer_->GetCurrentOutputDevices(deviceInfo);
1342 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetCurrentOutputDevices failure!");
1343
1344 NapiParamUtils::SetValueDeviceInfo(env, deviceInfo, result);
1345 return result;
1346 }
1347
GetUnderflowCount(napi_env env,napi_callback_info info)1348 napi_value NapiAudioRenderer::GetUnderflowCount(napi_env env, napi_callback_info info)
1349 {
1350 auto context = std::make_shared<AudioRendererAsyncContext>();
1351 if (context == nullptr) {
1352 AUDIO_ERR_LOG("GetUnderflowCount failed : no memory");
1353 NapiAudioError::ThrowError(env, "GetUnderflowCount failed : no memory", NAPI_ERR_NO_MEMORY);
1354 return NapiParamUtils::GetUndefinedValue(env);
1355 }
1356
1357 context->GetCbInfo(env, info);
1358
1359 auto executor = [context]() {
1360 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1361 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1362 ObjectRefMap objectGuard(obj);
1363 auto *napiAudioRenderer = objectGuard.GetPtr();
1364 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1365 "context object state is error.");
1366 context->underflowCount = napiAudioRenderer->audioRenderer_->GetUnderflowCount();
1367 };
1368
1369 auto complete = [env, context](napi_value &output) {
1370 NapiParamUtils::SetValueUInt32(env, context->underflowCount, output);
1371 };
1372 return NapiAsyncWork::Enqueue(env, context, "GetUnderflowCount", executor, complete);
1373 }
1374
GetUnderflowCountSync(napi_env env,napi_callback_info info)1375 napi_value NapiAudioRenderer::GetUnderflowCountSync(napi_env env, napi_callback_info info)
1376 {
1377 napi_value result = nullptr;
1378 size_t argc = PARAM0;
1379 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
1380 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
1381 NAPI_ERR_INPUT_INVALID), "argcCount invaild");
1382
1383 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1384 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1385
1386 uint32_t underflowCount = napiAudioRenderer->audioRenderer_->GetUnderflowCount();
1387 NapiParamUtils::SetValueUInt32(env, underflowCount, result);
1388 return result;
1389 }
1390
GetAudioEffectMode(napi_env env,napi_callback_info info)1391 napi_value NapiAudioRenderer::GetAudioEffectMode(napi_env env, napi_callback_info info)
1392 {
1393 auto context = std::make_shared<AudioRendererAsyncContext>();
1394 if (context == nullptr) {
1395 NapiAudioError::ThrowError(env, "GetAudioEffectMode failed : no memory", NAPI_ERR_NO_MEMORY);
1396 return NapiParamUtils::GetUndefinedValue(env);
1397 }
1398
1399 context->GetCbInfo(env, info);
1400
1401 auto executor = [context]() {
1402 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1403 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1404 ObjectRefMap objectGuard(obj);
1405 auto *napiAudioRenderer = objectGuard.GetPtr();
1406 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1407 "context object state is error.");
1408 context->intValue = napiAudioRenderer->audioRenderer_->GetAudioEffectMode();
1409 };
1410
1411 auto complete = [env, context](napi_value &output) {
1412 NapiParamUtils::SetValueInt32(env, context->intValue, output);
1413 };
1414 return NapiAsyncWork::Enqueue(env, context, "GetAudioEffectMode", executor, complete);
1415 }
1416
SetAudioEffectMode(napi_env env,napi_callback_info info)1417 napi_value NapiAudioRenderer::SetAudioEffectMode(napi_env env, napi_callback_info info)
1418 {
1419 auto context = std::make_shared<AudioRendererAsyncContext>();
1420 if (context == nullptr) {
1421 NapiAudioError::ThrowError(env, "SetAudioEffectMode failed : no memory", NAPI_ERR_NO_MEMORY);
1422 return NapiParamUtils::GetUndefinedValue(env);
1423 }
1424
1425 auto inputParser = [env, context](size_t argc, napi_value *argv) {
1426 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
1427 NAPI_ERR_INPUT_INVALID);
1428 context->status = NapiParamUtils::GetValueInt32(env, context->audioEffectMode, argv[PARAM0]);
1429 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
1430 "incorrect parameter types: The type of mode must be number", NAPI_ERR_INPUT_INVALID);
1431 NAPI_CHECK_ARGS_RETURN_VOID(context,
1432 NapiAudioEnum::IsLegalInputArgumentAudioEffectMode(context->audioEffectMode),
1433 "parameter verification failed: The param of mode must be enum AudioEffectMode",
1434 NAPI_ERR_INVALID_PARAM);
1435 };
1436 context->GetCbInfo(env, info, inputParser);
1437
1438 if ((context->status != napi_ok) && (context->errCode == NAPI_ERR_INPUT_INVALID)) {
1439 NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
1440 return NapiParamUtils::GetUndefinedValue(env);
1441 }
1442
1443 auto executor = [context]() {
1444 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1445 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1446 ObjectRefMap objectGuard(obj);
1447 auto *napiAudioRenderer = objectGuard.GetPtr();
1448 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1449 "context object state is error.");
1450 AudioEffectMode audioEffectMode = static_cast<AudioEffectMode>(context->audioEffectMode);
1451 context->intValue = napiAudioRenderer->audioRenderer_->SetAudioEffectMode(audioEffectMode);
1452 if (context->intValue != SUCCESS) {
1453 context->SignError(NAPI_ERR_SYSTEM);
1454 }
1455 };
1456
1457 auto complete = [env](napi_value &output) {
1458 output = NapiParamUtils::GetUndefinedValue(env);
1459 };
1460 return NapiAsyncWork::Enqueue(env, context, "SetAudioEffectMode", executor, complete);
1461 }
1462
SetChannelBlendMode(napi_env env,napi_callback_info info)1463 napi_value NapiAudioRenderer::SetChannelBlendMode(napi_env env, napi_callback_info info)
1464 {
1465 napi_value result = nullptr;
1466 size_t argc = ARGS_ONE;
1467 napi_value argv[ARGS_ONE] = {};
1468 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, argv);
1469 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
1470 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argcCount invaild");
1471
1472 napi_valuetype valueType = napi_undefined;
1473 napi_typeof(env, argv[PARAM0], &valueType);
1474 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
1475 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of mode must be number"),
1476 "valueType params");
1477
1478 int32_t channelBlendMode;
1479 NapiParamUtils::GetValueInt32(env, channelBlendMode, argv[PARAM0]);
1480 CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentChannelBlendMode(channelBlendMode),
1481 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
1482 "parameter verification failed: The param of mode must be enum ChannelBlendMode"), "unsupport params");
1483
1484 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer!= nullptr, result, "napiAudioRenderer is nullptr");
1485 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1486 int32_t ret =
1487 napiAudioRenderer->audioRenderer_->SetChannelBlendMode(static_cast<ChannelBlendMode>(channelBlendMode));
1488 CHECK_AND_RETURN_RET_LOG(ret != ERR_ILLEGAL_STATE,
1489 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_ILLEGAL_STATE), "err illegal state");
1490
1491 return result;
1492 }
1493
SetVolumeWithRamp(napi_env env,napi_callback_info info)1494 napi_value NapiAudioRenderer::SetVolumeWithRamp(napi_env env, napi_callback_info info)
1495 {
1496 AUDIO_INFO_LOG("SetVolumeWithRamp");
1497 napi_value result = nullptr;
1498 size_t argc = ARGS_TWO;
1499 napi_value argv[ARGS_TWO] = {};
1500 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, argv);
1501 CHECK_AND_RETURN_RET_LOG(argc >= ARGS_TWO, NapiAudioError::ThrowErrorAndReturn(env,
1502 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argcCount invaild");
1503
1504 napi_valuetype valueType = napi_undefined;
1505 napi_typeof(env, argv[PARAM0], &valueType);
1506 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
1507 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of volume must be number"),
1508 "valueType param0 invaild");
1509 napi_typeof(env, argv[PARAM1], &valueType);
1510 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
1511 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of duration must be number"),
1512 "valueType param1 invaild");
1513
1514 double volume;
1515 NapiParamUtils::GetValueDouble(env, volume, argv[PARAM0]);
1516 CHECK_AND_RETURN_RET_LOG((volume >= MIN_VOLUME_IN_DOUBLE) && (volume <= MAX_VOLUME_IN_DOUBLE),
1517 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
1518 "parameter verification failed: invaild volume index"), "invaild volume index");
1519
1520 int32_t duration;
1521 NapiParamUtils::GetValueInt32(env, duration, argv[PARAM1]);
1522 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer!= nullptr, result, "napiAudioRenderer is nullptr");
1523 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1524 int32_t ret =
1525 napiAudioRenderer->audioRenderer_->SetVolumeWithRamp(static_cast<float>(volume), duration);
1526 CHECK_AND_RETURN_RET_LOG(ret != ERR_ILLEGAL_STATE,
1527 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_ILLEGAL_STATE), "err illegal state");
1528 return result;
1529 }
1530
SetSpeed(napi_env env,napi_callback_info info)1531 napi_value NapiAudioRenderer::SetSpeed(napi_env env, napi_callback_info info)
1532 {
1533 AUDIO_INFO_LOG("SetSpeed");
1534 napi_value result = nullptr;
1535 size_t argc = ARGS_ONE;
1536 napi_value argv[ARGS_ONE] = {};
1537 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, argv);
1538 CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
1539 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argcCount invaild");
1540
1541 napi_valuetype valueType = napi_undefined;
1542 napi_typeof(env, argv[PARAM0], &valueType);
1543 CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
1544 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of speed must be number"),
1545 "valueType param0 invaild");
1546
1547 double speed;
1548 NapiParamUtils::GetValueDouble(env, speed, argv[PARAM0]);
1549 CHECK_AND_RETURN_RET_LOG((speed >= MIN_STREAM_SPEED_LEVEL) && (speed <= MAX_STREAM_SPEED_LEVEL),
1550 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM),
1551 "parameter verification failed: invaild speed index");
1552
1553 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer!= nullptr, result, "napiAudioRenderer is nullptr");
1554 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1555 int32_t ret = napiAudioRenderer->audioRenderer_->SetSpeed(static_cast<float>(speed));
1556 CHECK_AND_RETURN_RET_LOG(ret != ERR_ILLEGAL_STATE,
1557 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_ILLEGAL_STATE), "err illegal state");
1558 return result;
1559 }
1560
GetSpeed(napi_env env,napi_callback_info info)1561 napi_value NapiAudioRenderer::GetSpeed(napi_env env, napi_callback_info info)
1562 {
1563 AUDIO_INFO_LOG("GetSpeed");
1564 napi_value result = nullptr;
1565 size_t argc = ARGS_ONE;
1566 napi_value argv[ARGS_ONE] = {};
1567 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, argv);
1568 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer!= nullptr, result, "napiAudioRenderer is nullptr");
1569 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1570
1571 double ret = napiAudioRenderer->audioRenderer_->GetSpeed();
1572 napi_create_double(env, ret, &result);
1573 return result;
1574 }
1575
GetState(napi_env env,napi_callback_info info)1576 napi_value NapiAudioRenderer::GetState(napi_env env, napi_callback_info info)
1577 {
1578 napi_value result = nullptr;
1579 size_t argc = PARAM0;
1580 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, nullptr);
1581 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
1582 NAPI_ERR_INPUT_INVALID), "invaild params");
1583
1584 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer!= nullptr, result, "napiAudioRenderer is nullptr");
1585 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1586
1587 uint32_t rendererState = napiAudioRenderer->audioRenderer_->GetStatus();
1588 napi_status status = NapiParamUtils::SetValueInt32(env, rendererState, result);
1589 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "SetValueInt32 failed");
1590 return result;
1591 }
1592
On(napi_env env,napi_callback_info info)1593 napi_value NapiAudioRenderer::On(napi_env env, napi_callback_info info)
1594 {
1595 const size_t requireArgc = ARGS_TWO;
1596 size_t argc = ARGS_THREE;
1597
1598 napi_value argv[requireArgc + 1] = {nullptr, nullptr, nullptr};
1599 napi_value jsThis = nullptr;
1600 napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
1601 CHECK_AND_RETURN_RET_LOG(status == napi_ok,
1602 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM), "status error");
1603 CHECK_AND_RETURN_RET_LOG(argc >= requireArgc, NapiAudioError::ThrowErrorAndReturn(env,
1604 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "requireArgc is invaild");
1605
1606 napi_valuetype eventType = napi_undefined;
1607 napi_typeof(env, argv[PARAM0], &eventType);
1608 CHECK_AND_RETURN_RET_LOG(eventType == napi_string, NapiAudioError::ThrowErrorAndReturn(env,
1609 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of eventType must be string"),
1610 "eventType is invaild");
1611
1612 std::string callbackName = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
1613 AUDIO_DEBUG_LOG("AudioRendererNapi: On callbackName: %{public}s", callbackName.c_str());
1614
1615 napi_valuetype handler = napi_undefined;
1616 if (argc == requireArgc) {
1617 napi_typeof(env, argv[PARAM1], &handler);
1618 CHECK_AND_RETURN_RET_LOG(handler == napi_function, NapiAudioError::ThrowErrorAndReturn(env,
1619 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of callback must be function"),
1620 "handler is invaild");
1621 } else {
1622 napi_valuetype paramArg1 = napi_undefined;
1623 napi_typeof(env, argv[PARAM1], ¶mArg1);
1624 napi_valuetype expectedValType = napi_number; // Default. Reset it with 'callbackName' if check, if required.
1625 CHECK_AND_RETURN_RET_LOG(paramArg1 == expectedValType, NapiAudioError::ThrowErrorAndReturn(env,
1626 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of frame must be number"),
1627 "paramArg1 is invaild");
1628 const int32_t arg2 = ARGS_TWO;
1629 napi_typeof(env, argv[arg2], &handler);
1630 CHECK_AND_RETURN_RET_LOG(handler == napi_function, NapiAudioError::ThrowErrorAndReturn(env,
1631 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of callback must be function"),
1632 "handler2 is invaild");
1633 }
1634
1635 return RegisterCallback(env, jsThis, argv, callbackName);
1636 }
1637
Off(napi_env env,napi_callback_info info)1638 napi_value NapiAudioRenderer::Off(napi_env env, napi_callback_info info)
1639 {
1640 const size_t requireArgc = ARGS_TWO;
1641 size_t argc = ARGS_THREE;
1642
1643 napi_value argv[requireArgc + 1] = {nullptr, nullptr, nullptr};
1644 napi_value jsThis = nullptr;
1645 napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
1646 CHECK_AND_RETURN_RET_LOG(status == napi_ok,
1647 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM), "status error");
1648 CHECK_AND_RETURN_RET_LOG(argc <= requireArgc, NapiAudioError::ThrowErrorAndReturn(env,
1649 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argc is invaild");
1650
1651 napi_valuetype eventType = napi_undefined;
1652 napi_typeof(env, argv[PARAM0], &eventType);
1653 CHECK_AND_RETURN_RET_LOG(eventType == napi_string, NapiAudioError::ThrowErrorAndReturn(env,
1654 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of eventType must be string"),
1655 "eventType is invaild");
1656
1657 std::string callbackName = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
1658 AUDIO_DEBUG_LOG("AudioRendererNapi: Off callbackName: %{public}s", callbackName.c_str());
1659
1660 return UnregisterCallback(env, jsThis, argc, argv, callbackName);
1661 }
1662
SetSilentModeAndMixWithOthers(napi_env env,napi_callback_info info)1663 napi_value NapiAudioRenderer::SetSilentModeAndMixWithOthers(napi_env env, napi_callback_info info)
1664 {
1665 napi_value result = nullptr;
1666 size_t argc = ARGS_ONE;
1667 napi_value argv[ARGS_ONE] = {};
1668 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, argv);
1669 CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
1670 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argcCount invalid");
1671
1672 napi_valuetype valueType = napi_undefined;
1673 napi_typeof(env, argv[PARAM0], &valueType);
1674 CHECK_AND_RETURN_RET_LOG(valueType == napi_boolean, NapiAudioError::ThrowErrorAndReturn(env,
1675 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of on must be bool"),
1676 "valueType param0 invalid");
1677
1678 bool on;
1679 NapiParamUtils::GetValueBoolean(env, on, argv[PARAM0]);
1680
1681 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1682 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1683 napiAudioRenderer->audioRenderer_->SetSilentModeAndMixWithOthers(on);
1684 return result;
1685 }
1686
GetSilentModeAndMixWithOthers(napi_env env,napi_callback_info info)1687 napi_value NapiAudioRenderer::GetSilentModeAndMixWithOthers(napi_env env, napi_callback_info info)
1688 {
1689 napi_value result = nullptr;
1690 size_t argc = ARGS_ONE;
1691 napi_value argv[ARGS_ONE] = {};
1692 auto *napiAudioRenderer = GetParamWithSync(env, info, argc, argv);
1693 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer != nullptr, result, "napiAudioRenderer is nullptr");
1694 CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr");
1695
1696 bool on = napiAudioRenderer->audioRenderer_->GetSilentModeAndMixWithOthers();
1697 napi_get_boolean(env, on, &result);
1698 return result;
1699 }
1700
SetDefaultOutputDevice(napi_env env,napi_callback_info info)1701 napi_value NapiAudioRenderer::SetDefaultOutputDevice(napi_env env, napi_callback_info info)
1702 {
1703 auto context = std::make_shared<AudioRendererAsyncContext>();
1704 if (context == nullptr) {
1705 NapiAudioError::ThrowError(env, "SetDefaultOutputDevice failed : no memory",
1706 NAPI_ERR_NO_MEMORY);
1707 return NapiParamUtils::GetUndefinedValue(env);
1708 }
1709
1710 auto inputParser = [env, context](size_t argc, napi_value *argv) {
1711 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
1712 NAPI_ERR_INPUT_INVALID);
1713 context->status = NapiParamUtils::GetValueInt32(env, context->deviceType, argv[PARAM0]);
1714 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
1715 "incorrect parameter types: The type of mode must be number", NAPI_ERR_INPUT_INVALID);
1716 NAPI_CHECK_ARGS_RETURN_VOID(context,
1717 NapiAudioEnum::IsLegalInputArgumentDefaultOutputDeviceType(context->deviceType),
1718 "parameter verification failed: The param of mode must be enum deviceType",
1719 NAPI_ERR_INVALID_PARAM);
1720 };
1721 context->GetCbInfo(env, info, inputParser);
1722
1723 if ((context->status != napi_ok) && (context->errCode == NAPI_ERR_INPUT_INVALID ||
1724 context->errCode == NAPI_ERR_INVALID_PARAM)) {
1725 NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
1726 return NapiParamUtils::GetUndefinedValue(env);
1727 }
1728
1729 auto executor = [context]() {
1730 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1731 auto obj = reinterpret_cast<NapiAudioRenderer*>(context->native);
1732 ObjectRefMap objectGuard(obj);
1733 auto *napiAudioRenderer = objectGuard.GetPtr();
1734 CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context),
1735 "context object state is error.");
1736 DeviceType deviceType = static_cast<DeviceType>(context->deviceType);
1737 context->intValue = napiAudioRenderer->audioRenderer_->SetDefaultOutputDevice(deviceType);
1738 if (context->intValue != SUCCESS) {
1739 context->SignError(NAPI_ERR_ILLEGAL_STATE);
1740 }
1741 };
1742
1743 auto complete = [env](napi_value &output) {
1744 output = NapiParamUtils::GetUndefinedValue(env);
1745 };
1746 return NapiAsyncWork::Enqueue(env, context, "SetDefaultOutputDevice", executor, complete);
1747 }
1748
RegisterCallback(napi_env env,napi_value jsThis,napi_value * argv,const std::string & cbName)1749 napi_value NapiAudioRenderer::RegisterCallback(napi_env env, napi_value jsThis,
1750 napi_value *argv, const std::string &cbName)
1751 {
1752 NapiAudioRenderer *napiRenderer = nullptr;
1753 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiRenderer));
1754 CHECK_AND_RETURN_RET_LOG(status == napi_ok,
1755 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM), "status error");
1756 CHECK_AND_RETURN_RET_LOG(napiRenderer != nullptr,
1757 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY), "rendererNapi is nullptr");
1758 CHECK_AND_RETURN_RET_LOG(napiRenderer->audioRenderer_ != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
1759 NAPI_ERR_NO_MEMORY), "audioRenderer_ is nullptr");
1760
1761 napi_value result = nullptr;
1762 napi_get_undefined(env, &result);
1763
1764 if (!cbName.compare(INTERRUPT_CALLBACK_NAME) ||
1765 !cbName.compare(AUDIO_INTERRUPT_CALLBACK_NAME) ||
1766 !cbName.compare(STATE_CHANGE_CALLBACK_NAME)) {
1767 result = RegisterRendererCallback(env, argv, cbName, napiRenderer);
1768 } else if (!cbName.compare(MARK_REACH_CALLBACK_NAME)) {
1769 result = RegisterPositionCallback(env, argv, cbName, napiRenderer);
1770 } else if (!cbName.compare(PERIOD_REACH_CALLBACK_NAME)) {
1771 result = RegisterPeriodPositionCallback(env, argv, cbName, napiRenderer);
1772 } else if (!cbName.compare(DATA_REQUEST_CALLBACK_NAME)) {
1773 result = RegisterDataRequestCallback(env, argv, cbName, napiRenderer);
1774 } else if (!cbName.compare(DEVICECHANGE_CALLBACK_NAME)) {
1775 RegisterRendererDeviceChangeCallback(env, argv, cbName, napiRenderer);
1776 } else if (cbName == OUTPUT_DEVICECHANGE_WITH_INFO) {
1777 RegisterRendererOutputDeviceChangeWithInfoCallback(env, argv, cbName, napiRenderer);
1778 } else if (!cbName.compare(WRITE_DATA_CALLBACK_NAME)) {
1779 RegisterRendererWriteDataCallback(env, argv, cbName, napiRenderer);
1780 } else {
1781 bool unknownCallback = true;
1782 CHECK_AND_RETURN_RET_LOG(!unknownCallback, NapiAudioError::ThrowErrorAndReturn(env,
1783 NAPI_ERROR_INVALID_PARAM,
1784 "parameter verification failed: The param of type is not supported"), "audioRenderer_ is nullptr");
1785 }
1786
1787 return result;
1788 }
1789
UnregisterCallback(napi_env env,napi_value jsThis,size_t argc,napi_value * argv,const std::string & cbName)1790 napi_value NapiAudioRenderer::UnregisterCallback(napi_env env, napi_value jsThis, size_t argc, napi_value *argv,
1791 const std::string &cbName)
1792 {
1793 NapiAudioRenderer *napiRenderer = nullptr;
1794 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiRenderer));
1795 CHECK_AND_RETURN_RET_LOG(status == napi_ok,
1796 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM), "status error");
1797 CHECK_AND_RETURN_RET_LOG(napiRenderer != nullptr,
1798 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY), "napiRenderer is nullptr");
1799 CHECK_AND_RETURN_RET_LOG(napiRenderer->audioRenderer_ != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
1800 NAPI_ERR_NO_MEMORY), "audioRenderer_ is nullptr");
1801
1802 if (!cbName.compare(MARK_REACH_CALLBACK_NAME)) {
1803 UnregisterPositionCallback(env, argc, cbName, argv, napiRenderer);
1804 } else if (!cbName.compare(PERIOD_REACH_CALLBACK_NAME)) {
1805 UnregisterPeriodPositionCallback(env, argc, cbName, argv, napiRenderer);
1806 } else if (!cbName.compare(DEVICECHANGE_CALLBACK_NAME)) {
1807 UnregisterRendererDeviceChangeCallback(env, argc, cbName, argv, napiRenderer);
1808 } else if (!cbName.compare(INTERRUPT_CALLBACK_NAME) ||
1809 !cbName.compare(AUDIO_INTERRUPT_CALLBACK_NAME) ||
1810 !cbName.compare(STATE_CHANGE_CALLBACK_NAME)) {
1811 UnregisterRendererCallback(env, argc, cbName, argv, napiRenderer);
1812 } else if (!cbName.compare(DATA_REQUEST_CALLBACK_NAME)) {
1813 UnregisterDataRequestCallback(env, argc, cbName, argv, napiRenderer);
1814 } else if (cbName == OUTPUT_DEVICECHANGE_WITH_INFO) {
1815 UnregisterRendererOutputDeviceChangeWithInfoCallback(env, argc, cbName, argv, napiRenderer);
1816 } else if (!cbName.compare(WRITE_DATA_CALLBACK_NAME)) {
1817 UnregisterRendererWriteDataCallback(env, argc, argv, napiRenderer);
1818 } else {
1819 bool unknownCallback = true;
1820 CHECK_AND_RETURN_RET_LOG(!unknownCallback, NapiAudioError::ThrowErrorAndReturn(env,
1821 NAPI_ERR_INVALID_PARAM,
1822 "parameter verification failed: The param of type is not supported"), "cbName is invaild");
1823 }
1824
1825 napi_value result = nullptr;
1826 napi_get_undefined(env, &result);
1827 return result;
1828 }
1829
RegisterRendererCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioRenderer * napiRenderer)1830 napi_value NapiAudioRenderer::RegisterRendererCallback(napi_env env, napi_value *argv,
1831 const std::string &cbName, NapiAudioRenderer *napiRenderer)
1832 {
1833 CHECK_AND_RETURN_RET_LOG(napiRenderer->callbackNapi_ != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
1834 NAPI_ERR_NO_MEMORY), "callbackNapi_ is nullptr");
1835
1836 std::shared_ptr<NapiAudioRendererCallback> cb =
1837 std::static_pointer_cast<NapiAudioRendererCallback>(napiRenderer->callbackNapi_);
1838 cb->SaveCallbackReference(cbName, argv[PARAM1]);
1839 if (cbName == INTERRUPT_CALLBACK_NAME || cbName == AUDIO_INTERRUPT_CALLBACK_NAME) {
1840 if (!cb->GetArInterruptTsfnFlag()) {
1841 cb->CreateArInterrupt(env);
1842 }
1843 } else if (cbName == STATE_CHANGE_CALLBACK_NAME) {
1844 if (!cb->GetArStateChangeTsfnFlag()) {
1845 cb->CreateArStateChange(env);
1846 }
1847 }
1848
1849 napi_value result = nullptr;
1850 napi_get_undefined(env, &result);
1851 return result;
1852 }
1853
RegisterPositionCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioRenderer * napiRenderer)1854 napi_value NapiAudioRenderer::RegisterPositionCallback(napi_env env, napi_value *argv,
1855 const std::string &cbName, NapiAudioRenderer *napiRenderer)
1856 {
1857 int64_t markPosition = 0;
1858 NapiParamUtils::GetValueInt64(env, markPosition, argv[PARAM1]);
1859
1860 CHECK_AND_RETURN_RET_LOG(markPosition > 0, NapiAudioError::ThrowErrorAndReturn(env,
1861 NAPI_ERR_INPUT_INVALID, "parameter verification failed: The param of frame is not supported"),
1862 "Mark Position value not supported!!");
1863 napiRenderer->positionCbNapi_ = std::make_shared<NapiRendererPositionCallback>(env);
1864 CHECK_AND_RETURN_RET_LOG(napiRenderer->positionCbNapi_ != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
1865 NAPI_ERR_NO_MEMORY), "positionCbNapi_ is nullptr");
1866 int32_t ret = napiRenderer->audioRenderer_->SetRendererPositionCallback(markPosition,
1867 napiRenderer->positionCbNapi_);
1868 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM),
1869 "SetRendererPositionCallback fail");
1870
1871 std::shared_ptr<NapiRendererPositionCallback> cb =
1872 std::static_pointer_cast<NapiRendererPositionCallback>(napiRenderer->positionCbNapi_);
1873 cb->SaveCallbackReference(cbName, argv[PARAM2]);
1874 if (!cb->GetMarkReachedTsfnFlag()) {
1875 cb->CreateMarkReachedTsfn(env);
1876 }
1877
1878 napi_value result = nullptr;
1879 napi_get_undefined(env, &result);
1880 return result;
1881 }
1882
UnregisterPositionCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioRenderer * napiRenderer)1883 void NapiAudioRenderer::UnregisterPositionCallback(napi_env env, size_t argc,
1884 const std::string &cbName, napi_value *argv, NapiAudioRenderer *napiRenderer)
1885 {
1886 CHECK_AND_RETURN_LOG(napiRenderer->positionCbNapi_ != nullptr, "rendererCallbackNapi is nullptr");
1887
1888 std::shared_ptr<NapiRendererPositionCallback> cb =
1889 std::static_pointer_cast<NapiRendererPositionCallback>(napiRenderer->positionCbNapi_);
1890 std::function<int32_t(std::shared_ptr<NapiRendererPositionCallback> callbackPtr,
1891 napi_value callback)> removeFunction =
1892 [&napiRenderer] (std::shared_ptr<NapiRendererPositionCallback> callbackPtr, napi_value callback) {
1893 napiRenderer->audioRenderer_->UnsetRendererPositionCallback();
1894 napiRenderer->positionCbNapi_ = nullptr;
1895 return SUCCESS;
1896 };
1897 auto callback = GetCallback(argc, argv);
1898 UnregisterAudioRendererSingletonCallbackTemplate(env, callback, cbName, cb, removeFunction);
1899 AUDIO_DEBUG_LOG("UnregisterRendererPositionCallback is successful");
1900 }
1901
RegisterPeriodPositionCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioRenderer * napiRenderer)1902 napi_value NapiAudioRenderer::RegisterPeriodPositionCallback(napi_env env, napi_value *argv,
1903 const std::string &cbName, NapiAudioRenderer *napiRenderer)
1904 {
1905 int64_t frameCount = 0;
1906 NapiParamUtils::GetValueInt64(env, frameCount, argv[PARAM1]);
1907
1908 if (frameCount > 0) {
1909 if (napiRenderer->periodPositionCbNapi_ == nullptr) {
1910 napiRenderer->periodPositionCbNapi_ = std::make_shared<NapiRendererPeriodPositionCallback>(env);
1911 CHECK_AND_RETURN_RET_LOG(napiRenderer->periodPositionCbNapi_ != nullptr,
1912 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY),
1913 "periodPositionCbNapi_ is nullptr, No memery");
1914
1915 int32_t ret = napiRenderer->audioRenderer_->SetRendererPeriodPositionCallback(frameCount,
1916 napiRenderer->periodPositionCbNapi_);
1917 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS,
1918 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM),
1919 "SetRendererPeriodPositionCallback failed");
1920
1921 std::shared_ptr<NapiRendererPeriodPositionCallback> cb =
1922 std::static_pointer_cast<NapiRendererPeriodPositionCallback>(napiRenderer->periodPositionCbNapi_);
1923 cb->SaveCallbackReference(cbName, argv[PARAM2]);
1924 cb->CreatePeriodReachTsfn(env);
1925 } else {
1926 AUDIO_DEBUG_LOG("periodReach already subscribed.");
1927 }
1928 } else {
1929 AUDIO_ERR_LOG("frameCount value not supported!!");
1930 }
1931
1932 napi_value result = nullptr;
1933 napi_get_undefined(env, &result);
1934 return result;
1935 }
1936
UnregisterPeriodPositionCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioRenderer * napiRenderer)1937 void NapiAudioRenderer::UnregisterPeriodPositionCallback(napi_env env, size_t argc,
1938 const std::string &cbName, napi_value *argv, NapiAudioRenderer *napiRenderer)
1939 {
1940 CHECK_AND_RETURN_LOG(napiRenderer->periodPositionCbNapi_ != nullptr, "periodPositionCbNapi is nullptr");
1941
1942 std::shared_ptr<NapiRendererPeriodPositionCallback> cb =
1943 std::static_pointer_cast<NapiRendererPeriodPositionCallback>(napiRenderer->periodPositionCbNapi_);
1944 std::function<int32_t(std::shared_ptr<NapiRendererPeriodPositionCallback> callbackPtr,
1945 napi_value callback)> removeFunction =
1946 [&napiRenderer] (std::shared_ptr<NapiRendererPeriodPositionCallback> callbackPtr, napi_value callback) {
1947 napiRenderer->audioRenderer_->UnsetRendererPeriodPositionCallback();
1948 napiRenderer->periodPositionCbNapi_ = nullptr;
1949 return SUCCESS;
1950 };
1951 auto callback = GetCallback(argc, argv);
1952 UnregisterAudioRendererSingletonCallbackTemplate(env, callback, cbName, cb, removeFunction);
1953 AUDIO_DEBUG_LOG("UnregisterRendererPeriodPositionCallback is successful");
1954 }
1955
RegisterDataRequestCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioRenderer * napiRenderer)1956 napi_value NapiAudioRenderer::RegisterDataRequestCallback(napi_env env, napi_value *argv,
1957 const std::string &cbName, NapiAudioRenderer *napiRenderer)
1958 {
1959 CHECK_AND_RETURN_RET_LOG(napiRenderer->dataRequestCbNapi_ == nullptr,
1960 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_ILLEGAL_STATE),
1961 "dataRequest already subscribed.");
1962
1963 napiRenderer->dataRequestCbNapi_ = std::make_shared<NapiRendererDataRequestCallback>(env, napiRenderer);
1964 napiRenderer->audioRenderer_->SetRenderMode(RENDER_MODE_CALLBACK);
1965 CHECK_AND_RETURN_RET_LOG(napiRenderer->dataRequestCbNapi_ != nullptr,
1966 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY), "dataRequestCbNapi_ is nullptr");
1967 int32_t ret = napiRenderer->audioRenderer_->SetRendererWriteCallback(napiRenderer->dataRequestCbNapi_);
1968 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS,
1969 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM), "SetRendererWriteCallback failed");
1970 std::shared_ptr<NapiRendererDataRequestCallback> cb =
1971 std::static_pointer_cast<NapiRendererDataRequestCallback>(napiRenderer->dataRequestCbNapi_);
1972 cb->SaveCallbackReference(cbName, argv[PARAM1]);
1973 cb->CreateWriteDataTsfn(env);
1974
1975 napi_value result = nullptr;
1976 napi_get_undefined(env, &result);
1977 return result;
1978 }
1979
UnregisterDataRequestCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioRenderer * napiRenderer)1980 void NapiAudioRenderer::UnregisterDataRequestCallback(napi_env env, size_t argc,
1981 const std::string &cbName, napi_value *argv, NapiAudioRenderer *napiRenderer)
1982 {
1983 CHECK_AND_RETURN_LOG(napiRenderer->dataRequestCbNapi_ != nullptr, "rendererCallbackNapi is nullptr");
1984
1985 std::shared_ptr<NapiRendererDataRequestCallback> cb =
1986 std::static_pointer_cast<NapiRendererDataRequestCallback>(napiRenderer->dataRequestCbNapi_);
1987 std::function<int32_t(std::shared_ptr<NapiRendererDataRequestCallback> callbackPtr,
1988 napi_value callback)> removeFunction =
1989 [&napiRenderer] (std::shared_ptr<NapiRendererDataRequestCallback> callbackPtr, napi_value callback) {
1990 napiRenderer->dataRequestCbNapi_ = nullptr;
1991 return SUCCESS;
1992 };
1993 auto callback = GetCallback(argc, argv);
1994 UnregisterAudioRendererSingletonCallbackTemplate(env, callback, cbName, cb, removeFunction);
1995 AUDIO_DEBUG_LOG("UnregisterRendererDataRequestCallback is successful");
1996 }
1997
RegisterRendererDeviceChangeCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioRenderer * napiRenderer)1998 void NapiAudioRenderer::RegisterRendererDeviceChangeCallback(napi_env env, napi_value *argv,
1999 const std::string &cbName, NapiAudioRenderer *napiRenderer)
2000 {
2001 if (!napiRenderer->rendererDeviceChangeCallbackNapi_) {
2002 napiRenderer->rendererDeviceChangeCallbackNapi_ = std::make_shared<NapiAudioRendererDeviceChangeCallback>(env);
2003 CHECK_AND_RETURN_LOG(napiRenderer->rendererDeviceChangeCallbackNapi_ != nullptr,
2004 "rendererDeviceChangeCallbackNapi_ is nullptr, No memery");
2005
2006 int32_t ret = napiRenderer->audioRenderer_->RegisterOutputDeviceChangeWithInfoCallback(
2007 napiRenderer->rendererDeviceChangeCallbackNapi_);
2008 CHECK_AND_RETURN_LOG(ret == SUCCESS,
2009 "Registering of Renderer Device Change Callback Failed");
2010 }
2011
2012 if (!napiRenderer->rendererPolicyServiceDiedCallbackNapi_) {
2013 napiRenderer->rendererPolicyServiceDiedCallbackNapi_ =
2014 std::make_shared<NapiAudioRendererPolicyServiceDiedCallback>(napiRenderer);
2015 CHECK_AND_RETURN_LOG(napiRenderer->rendererPolicyServiceDiedCallbackNapi_ != nullptr,
2016 "Registering of Renderer Device Change Callback Failed");
2017
2018 int32_t ret = napiRenderer->audioRenderer_->RegisterAudioPolicyServerDiedCb(getpid(),
2019 napiRenderer->rendererPolicyServiceDiedCallbackNapi_);
2020 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Registering of AudioPolicyService Died Change Callback Failed");
2021 }
2022
2023 std::shared_ptr<NapiAudioRendererDeviceChangeCallback> cb =
2024 std::static_pointer_cast<NapiAudioRendererDeviceChangeCallback>(
2025 napiRenderer->rendererDeviceChangeCallbackNapi_);
2026 cb->SaveCallbackReference(cbName, argv[PARAM1]);
2027 if (!cb->GetRendererDeviceChangeTsfnFlag()) {
2028 cb->CreateRendererDeviceChangeTsfn(env);
2029 }
2030 AUDIO_INFO_LOG("RegisterRendererStateChangeCallback is successful");
2031 }
2032
UnregisterRendererCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioRenderer * napiRenderer)2033 void NapiAudioRenderer::UnregisterRendererCallback(napi_env env, size_t argc,
2034 const std::string &cbName, napi_value *argv, NapiAudioRenderer *napiRenderer)
2035 {
2036 CHECK_AND_RETURN_LOG(napiRenderer->callbackNapi_ != nullptr, "napiRendererCallback is nullptr");
2037
2038 std::shared_ptr<NapiAudioRendererCallback> cb =
2039 std::static_pointer_cast<NapiAudioRendererCallback>(napiRenderer->callbackNapi_);
2040 auto callback = GetCallback(argc, argv);
2041 UnregisterAudioRendererSingletonCallbackTemplate(env, callback, cbName, cb);
2042 AUDIO_DEBUG_LOG("UnregisterRendererCallback is successful");
2043 }
2044
UnregisterRendererDeviceChangeCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioRenderer * napiRenderer)2045 void NapiAudioRenderer::UnregisterRendererDeviceChangeCallback(napi_env env, size_t argc,
2046 const std::string &cbName, napi_value *argv, NapiAudioRenderer *napiRenderer)
2047 {
2048 CHECK_AND_RETURN_LOG(napiRenderer->rendererDeviceChangeCallbackNapi_ != nullptr,
2049 "rendererDeviceChangeCallbackNapi_ is nullptr, return");
2050
2051 CHECK_AND_RETURN_LOG(napiRenderer->rendererPolicyServiceDiedCallbackNapi_ != nullptr,
2052 "rendererPolicyServiceDiedCallbackNapi_ is nullptr, return");
2053
2054 std::shared_ptr<NapiAudioRendererDeviceChangeCallback> cb =
2055 std::static_pointer_cast<NapiAudioRendererDeviceChangeCallback>(
2056 napiRenderer->rendererDeviceChangeCallbackNapi_);
2057
2058 std::function<int32_t(std::shared_ptr<NapiAudioRendererDeviceChangeCallback> callbackPtr,
2059 napi_value callback)> removeFunction =
2060 [&napiRenderer] (std::shared_ptr<NapiAudioRendererDeviceChangeCallback> callbackPtr, napi_value callback) {
2061 if (callback == nullptr || callbackPtr->GetCallbackListSize() == 0) {
2062 int32_t ret = napiRenderer->audioRenderer_->UnregisterOutputDeviceChangeWithInfoCallback(callbackPtr);
2063 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS,
2064 ERR_OPERATION_FAILED, "unregister renderer device change callback failed");
2065 ret = napiRenderer->audioRenderer_->UnregisterAudioPolicyServerDiedCb(getpid());
2066 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS,
2067 ERR_OPERATION_FAILED, "unregister AudioPolicyServerDiedCb failed");
2068 napiRenderer->DestroyNAPICallbacks();
2069 }
2070 AUDIO_INFO_LOG("UnregisterRendererDeviceChangeCallback success");
2071 return SUCCESS;
2072 };
2073 auto callback = GetCallback(argc, argv);
2074 UnregisterAudioRendererSingletonCallbackTemplate(env, callback, cbName, cb, removeFunction);
2075 }
2076
RegisterRendererOutputDeviceChangeWithInfoCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioRenderer * napiRenderer)2077 void NapiAudioRenderer::RegisterRendererOutputDeviceChangeWithInfoCallback(napi_env env, napi_value *argv,
2078 const std::string &cbName, NapiAudioRenderer *napiRenderer)
2079 {
2080 if (!napiRenderer->rendererOutputDeviceChangeWithInfoCallbackNapi_) {
2081 napiRenderer->rendererOutputDeviceChangeWithInfoCallbackNapi_
2082 = std::make_shared<NapiAudioRendererOutputDeviceChangeWithInfoCallback>(env);
2083 CHECK_AND_RETURN_LOG(napiRenderer->rendererOutputDeviceChangeWithInfoCallbackNapi_ != nullptr,
2084 "rendererOutputDeviceChangeWithInfoCallbackNapi_ is nullptr, No memery");
2085
2086 int32_t ret = napiRenderer->audioRenderer_->RegisterOutputDeviceChangeWithInfoCallback(
2087 napiRenderer->rendererOutputDeviceChangeWithInfoCallbackNapi_);
2088 CHECK_AND_RETURN_LOG(ret == SUCCESS,
2089 "Registering of Renderer Device Change Callback Failed");
2090 }
2091
2092 if (!napiRenderer->rendererPolicyServiceDiedCallbackNapi_) {
2093 napiRenderer->rendererPolicyServiceDiedCallbackNapi_ =
2094 std::make_shared<NapiAudioRendererPolicyServiceDiedCallback>(napiRenderer);
2095 CHECK_AND_RETURN_LOG(napiRenderer->rendererPolicyServiceDiedCallbackNapi_ != nullptr,
2096 "Registering of Renderer Device Change Callback Failed");
2097
2098 int32_t ret = napiRenderer->audioRenderer_->RegisterAudioPolicyServerDiedCb(getpid(),
2099 napiRenderer->rendererPolicyServiceDiedCallbackNapi_);
2100 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Registering of AudioPolicyService Died Change Callback Failed");
2101 }
2102
2103 std::shared_ptr<NapiAudioRendererOutputDeviceChangeWithInfoCallback> cb =
2104 napiRenderer->rendererOutputDeviceChangeWithInfoCallbackNapi_;
2105 cb->SaveCallbackReference(cbName, argv[PARAM1]);
2106 if (!cb->GetOutputDeviceChangeTsfnFlag()) {
2107 cb->CreateOutputDeviceChangeTsfn(env);
2108 }
2109 AUDIO_INFO_LOG("Register Callback is successful");
2110 }
2111
UnregisterRendererOutputDeviceChangeWithInfoCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioRenderer * napiRenderer)2112 void NapiAudioRenderer::UnregisterRendererOutputDeviceChangeWithInfoCallback(napi_env env, size_t argc,
2113 const std::string &cbName, napi_value *argv, NapiAudioRenderer *napiRenderer)
2114 {
2115 CHECK_AND_RETURN_LOG(napiRenderer->rendererOutputDeviceChangeWithInfoCallbackNapi_ != nullptr,
2116 "rendererDeviceChangeCallbackNapi_ is nullptr, return");
2117
2118 CHECK_AND_RETURN_LOG(napiRenderer->rendererPolicyServiceDiedCallbackNapi_ != nullptr,
2119 "rendererPolicyServiceDiedCallbackNapi_ is nullptr, return");
2120
2121 std::shared_ptr<NapiAudioRendererOutputDeviceChangeWithInfoCallback> cb =
2122 napiRenderer->rendererOutputDeviceChangeWithInfoCallbackNapi_;
2123 std::function<int32_t(std::shared_ptr<NapiAudioRendererOutputDeviceChangeWithInfoCallback> callbackPtr,
2124 napi_value callback)> removeFunction = [&napiRenderer] (
2125 std::shared_ptr<NapiAudioRendererOutputDeviceChangeWithInfoCallback> callbackPtr, napi_value callback) {
2126 if (callback == nullptr || callbackPtr->GetCallbackListSize() == 0) {
2127 int32_t ret = napiRenderer->audioRenderer_->UnregisterOutputDeviceChangeWithInfoCallback(callbackPtr);
2128 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS,
2129 ERR_OPERATION_FAILED, "unregister renderer outputDevice change with info callback failed");
2130 ret = napiRenderer->audioRenderer_->UnregisterAudioPolicyServerDiedCb(getpid());
2131 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS,
2132 ERR_OPERATION_FAILED, "unregister AudioPolicyServerDiedCb failed");
2133 napiRenderer->DestroyNAPICallbacks();
2134 }
2135 AUDIO_INFO_LOG("UnregisterRendererDeviceChangeCallback success");
2136 return SUCCESS;
2137 };
2138 auto callback = GetCallback(argc, argv);
2139 UnregisterAudioRendererSingletonCallbackTemplate(env, callback, cbName, cb, removeFunction);
2140 }
2141
RegisterRendererWriteDataCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioRenderer * napiRenderer)2142 void NapiAudioRenderer::RegisterRendererWriteDataCallback(napi_env env, napi_value *argv,
2143 const std::string &cbName, NapiAudioRenderer *napiRenderer)
2144 {
2145 if (napiRenderer->rendererWriteDataCallbackNapi_ != nullptr) {
2146 AUDIO_WARNING_LOG("writeData already subscribed. The old writeData function will be overwritten.");
2147 }
2148
2149 napiRenderer->rendererWriteDataCallbackNapi_ = std::make_shared<NapiRendererWriteDataCallback>(env, napiRenderer);
2150 napiRenderer->audioRenderer_->SetRenderMode(RENDER_MODE_CALLBACK);
2151 CHECK_AND_RETURN_LOG(napiRenderer->rendererWriteDataCallbackNapi_ != nullptr, "writeDataCbNapi_ is nullpur");
2152 int32_t ret = napiRenderer->audioRenderer_->SetRendererWriteCallback(napiRenderer->rendererWriteDataCallbackNapi_);
2153 CHECK_AND_RETURN_LOG(ret == SUCCESS, "SetRendererWriteCallback failed");
2154 std::shared_ptr<NapiRendererWriteDataCallback> cb =
2155 std::static_pointer_cast<NapiRendererWriteDataCallback>(napiRenderer->rendererWriteDataCallbackNapi_);
2156 cb->AddCallbackReference(cbName, argv[PARAM1]);
2157 if (!cb->GetWriteDTsfnFlag()) {
2158 cb->CreateWriteDTsfn(env);
2159 }
2160
2161 AUDIO_INFO_LOG("Register Callback is successful");
2162 }
2163
UnregisterRendererWriteDataCallback(napi_env env,size_t argc,const napi_value * argv,NapiAudioRenderer * napiRenderer)2164 void NapiAudioRenderer::UnregisterRendererWriteDataCallback(napi_env env, size_t argc, const napi_value *argv,
2165 NapiAudioRenderer *napiRenderer)
2166 {
2167 napi_value callback = nullptr;
2168
2169 if (argc == ARGS_TWO) {
2170 callback = argv[PARAM1];
2171 }
2172 CHECK_AND_RETURN_LOG(napiRenderer->rendererWriteDataCallbackNapi_ != nullptr,
2173 "napiRendererWriteDataCallback is nullptr, return");
2174
2175 std::shared_ptr<NapiRendererWriteDataCallback> cb =
2176 std::static_pointer_cast<NapiRendererWriteDataCallback>(napiRenderer->rendererWriteDataCallbackNapi_);
2177 cb->RemoveCallbackReference(env, callback);
2178
2179 AUDIO_INFO_LOG("Unregister Callback is successful");
2180 }
2181
DestroyCallbacks()2182 void NapiAudioRenderer::DestroyCallbacks()
2183 {
2184 CHECK_AND_RETURN_LOG(rendererDeviceChangeCallbackNapi_ != nullptr, "rendererDeviceChangeCallbackNapi_ is nullptr");
2185 rendererDeviceChangeCallbackNapi_->RemoveAllCallbacks();
2186 DestroyNAPICallbacks();
2187 }
2188
DestroyNAPICallbacks()2189 void NapiAudioRenderer::DestroyNAPICallbacks()
2190 {
2191 if (rendererDeviceChangeCallbackNapi_ != nullptr) {
2192 rendererDeviceChangeCallbackNapi_.reset();
2193 rendererDeviceChangeCallbackNapi_ = nullptr;
2194 }
2195
2196 if (rendererPolicyServiceDiedCallbackNapi_ != nullptr) {
2197 rendererPolicyServiceDiedCallbackNapi_.reset();
2198 rendererPolicyServiceDiedCallbackNapi_ = nullptr;
2199 }
2200 }
2201 } // namespace AudioStandard
2202 } // namespace OHOS
2203