• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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], &paramArg1);
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