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