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