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