• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
16 #include "audio_volume_manager_napi.h"
17 #include "audio_volume_group_manager_napi.h"
18 
19 #include "audio_common_napi.h"
20 #include "audio_volume_key_event_napi.h"
21 #include "audio_errors.h"
22 #include "audio_log.h"
23 #include "hilog/log.h"
24 #include "napi_base_context.h"
25 
26 using namespace std;
27 using OHOS::HiviewDFX::HiLog;
28 using OHOS::HiviewDFX::HiLogLabel;
29 
30 namespace OHOS {
31 namespace AudioStandard {
32 static __thread napi_ref g_volumeManagerConstructor = nullptr;
33 
34 namespace {
35     const int ARGS_ONE = 1;
36     const int ARGS_TWO = 2;
37     const int PARAM0 = 0;
38     const int PARAM1 = 1;
39     constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AudioVolumeManagerNapi"};
40     const std::string VOLUME_CHANGE_CALLBACK_NAME = "volumeChange";
41 }
42 
43 struct AudioVolumeManagerAsyncContext {
44     napi_env env;
45     napi_async_work work;
46     napi_deferred deferred;
47     napi_ref callbackRef = nullptr;
48     int32_t deviceFlag;
49     bool bArgTransFlag = true;
50     int32_t status = SUCCESS;
51     int32_t groupId;
52     int32_t intValue;
53     int32_t ringMode;
54     bool isMute;
55     bool isTrue;
56     std::string networkId;
57     AudioVolumeManagerNapi *objectInfo;
58     vector<sptr<VolumeGroupInfo>> volumeGroupInfos;
59 };
60 
AudioVolumeManagerNapi()61 AudioVolumeManagerNapi::AudioVolumeManagerNapi()
62     : audioSystemMngr_(nullptr), env_(nullptr) {}
63 
64 AudioVolumeManagerNapi::~AudioVolumeManagerNapi() = default;
65 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)66 void AudioVolumeManagerNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
67 {
68     if (nativeObject != nullptr) {
69         auto obj = static_cast<AudioVolumeManagerNapi *>(nativeObject);
70         delete obj;
71         obj = nullptr;
72     }
73 }
74 
Construct(napi_env env,napi_callback_info info)75 napi_value AudioVolumeManagerNapi::Construct(napi_env env, napi_callback_info info)
76 {
77     AUDIO_INFO_LOG("Construct");
78     napi_status status;
79     napi_value result = nullptr;
80     napi_get_undefined(env, &result);
81 
82     size_t argc = ARGS_TWO;
83     napi_value argv[ARGS_TWO] = {0};
84     napi_value thisVar = nullptr;
85     void *data = nullptr;
86 
87     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
88     unique_ptr<AudioVolumeManagerNapi> audioVolumeManagerNapi = make_unique<AudioVolumeManagerNapi>();
89     CHECK_AND_RETURN_RET_LOG(audioVolumeManagerNapi != nullptr, result, "No memory");
90 
91     audioVolumeManagerNapi->audioSystemMngr_ = AudioSystemManager::GetInstance();
92     audioVolumeManagerNapi->env_ = env;
93     audioVolumeManagerNapi->cachedClientId_ = getpid();
94 
95     status = napi_wrap(env, thisVar, static_cast<void*>(audioVolumeManagerNapi.get()),
96         AudioVolumeManagerNapi::Destructor, nullptr, nullptr);
97     if (status == napi_ok) {
98         audioVolumeManagerNapi.release();
99         return thisVar;
100     }
101 
102     HiLog::Error(LABEL, "Failed in AudioVolumeManager::Construct()!");
103     return result;
104 }
105 
CreateVolumeManagerWrapper(napi_env env)106 napi_value AudioVolumeManagerNapi::CreateVolumeManagerWrapper(napi_env env)
107 {
108     napi_status status;
109     napi_value result = nullptr;
110     napi_value constructor;
111 
112     status = napi_get_reference_value(env, g_volumeManagerConstructor, &constructor);
113     if (status == napi_ok) {
114         status = napi_new_instance(env, constructor, 0, nullptr, &result);
115         if (status == napi_ok) {
116             return result;
117         }
118     }
119     HiLog::Error(LABEL, "Failed in AudioVolumeManagerNapi::CreateVolumeManagerWrapper!");
120     napi_get_undefined(env, &result);
121 
122     return result;
123 }
124 
Init(napi_env env,napi_value exports)125 napi_value AudioVolumeManagerNapi::Init(napi_env env, napi_value exports)
126 {
127     AUDIO_INFO_LOG("Init");
128     napi_status status;
129     napi_value constructor;
130     napi_value result = nullptr;
131     const int32_t refCount = 1;
132     napi_get_undefined(env, &result);
133 
134     napi_property_descriptor audio_volume_manager_properties[] = {
135         DECLARE_NAPI_FUNCTION("getVolumeGroupInfos", GetVolumeGroupInfos),
136         DECLARE_NAPI_FUNCTION("getVolumeGroupInfosSync", GetVolumeGroupInfosSync),
137         DECLARE_NAPI_FUNCTION("getVolumeGroupManager", GetVolumeGroupManager),
138         DECLARE_NAPI_FUNCTION("getVolumeGroupManagerSync", GetVolumeGroupManagerSync),
139         DECLARE_NAPI_FUNCTION("on", On),
140 
141     };
142 
143     status = napi_define_class(env, AUDIO_VOLUME_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct, nullptr,
144         sizeof(audio_volume_manager_properties) / sizeof(audio_volume_manager_properties[PARAM0]),
145         audio_volume_manager_properties, &constructor);
146     if (status != napi_ok) {
147         return result;
148     }
149     status = napi_create_reference(env, constructor, refCount, &g_volumeManagerConstructor);
150     if (status == napi_ok) {
151         status = napi_set_named_property(env, exports, AUDIO_VOLUME_MANAGER_NAPI_CLASS_NAME.c_str(), constructor);
152         if (status == napi_ok) {
153             return exports;
154         }
155     }
156 
157     HiLog::Error(LABEL, "Failure in AudioVolumeManagerNapi::Init()");
158     return result;
159 }
160 
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int intValue,napi_value & result)161 static void SetValueInt32(const napi_env& env, const std::string& fieldStr, const int intValue, napi_value& result)
162 {
163     napi_value value = nullptr;
164     napi_create_int32(env, intValue, &value);
165     napi_set_named_property(env, result, fieldStr.c_str(), value);
166 }
167 
SetValueString(const napi_env & env,const std::string & fieldStr,const std::string stringValue,napi_value & result)168 static void SetValueString(const napi_env& env, const std::string& fieldStr, const std::string stringValue,
169     napi_value& result)
170 {
171     napi_value value = nullptr;
172     napi_create_string_utf8(env, stringValue.c_str(), NAPI_AUTO_LENGTH, &value);
173     napi_set_named_property(env, result, fieldStr.c_str(), value);
174 }
175 
CommonCallbackRoutine(napi_env env,AudioVolumeManagerAsyncContext * & asyncContext,const napi_value & valueParam)176 static void CommonCallbackRoutine(napi_env env, AudioVolumeManagerAsyncContext *&asyncContext,
177     const napi_value &valueParam)
178 {
179     napi_value result[ARGS_TWO] = {0};
180     napi_value retVal;
181 
182     if (!asyncContext->status) {
183         napi_get_undefined(env, &result[PARAM0]);
184         result[PARAM1] = valueParam;
185     } else {
186         napi_value message = nullptr;
187         std::string messageValue = AudioCommonNapi::getMessageByCode(asyncContext->status);
188         napi_create_string_utf8(env, messageValue.c_str(), NAPI_AUTO_LENGTH, &message);
189 
190         napi_value code = nullptr;
191         napi_create_string_utf8(env, (std::to_string(asyncContext->status)).c_str(), NAPI_AUTO_LENGTH, &code);
192 
193         napi_create_error(env, code, message, &result[PARAM0]);
194         napi_get_undefined(env, &result[PARAM1]);
195     }
196 
197     if (asyncContext->deferred) {
198         if (!asyncContext->status) {
199             napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]);
200         } else {
201             napi_reject_deferred(env, asyncContext->deferred, result[PARAM0]);
202         }
203     } else {
204         napi_value callback = nullptr;
205         napi_get_reference_value(env, asyncContext->callbackRef, &callback);
206         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
207         napi_delete_reference(env, asyncContext->callbackRef);
208     }
209     napi_delete_async_work(env, asyncContext->work);
210 
211     delete asyncContext;
212     asyncContext = nullptr;
213 }
214 
GetVolumeGroupInfosAsyncCallbackComplete(napi_env env,napi_status status,void * data)215 static void GetVolumeGroupInfosAsyncCallbackComplete(napi_env env, napi_status status, void *data)
216 {
217     auto asyncContext = static_cast<AudioVolumeManagerAsyncContext*>(data);
218 
219     napi_value result[ARGS_TWO] = { 0 };
220     napi_value valueParam = nullptr;
221     if (asyncContext != nullptr) {
222         if (asyncContext->status) {
223             napi_get_undefined(env, &valueParam);
224         } else {
225             size_t size = asyncContext->volumeGroupInfos.size();
226             HiLog::Info(LABEL, "number of devices = %{public}zu", size);
227             napi_create_array_with_length(env, size, &result[PARAM1]);
228             for (size_t i = 0; i < size; i++) {
229                 if (asyncContext->volumeGroupInfos[i] != nullptr) {
230                     (void)napi_create_object(env, &valueParam);
231                     SetValueString(env, "networkId", static_cast<std::string>(
232                         asyncContext->volumeGroupInfos[i]->networkId_), valueParam);
233                     SetValueInt32(env, "groupId", static_cast<int32_t>(
234                         asyncContext->volumeGroupInfos[i]->volumeGroupId_), valueParam);
235                     SetValueInt32(env, "mappingId", static_cast<int32_t>(
236                         asyncContext->volumeGroupInfos[i]->mappingId_), valueParam);
237                     SetValueString(env, "groupName", static_cast<std::string>(
238                         asyncContext->volumeGroupInfos[i]->groupName_), valueParam);
239                     SetValueInt32(env, "ConnectType", static_cast<int32_t>(
240                         asyncContext->volumeGroupInfos[i]->connectType_), valueParam);
241                     napi_set_element(env, result[PARAM1], i, valueParam);
242                 }
243             }
244         }
245         CommonCallbackRoutine(env, asyncContext, result[PARAM1]);
246     } else {
247         HiLog::Error(LABEL, "ERROR: AudioRoutingManagerAsyncContext* is Null!");
248     }
249 }
250 
GetVolumeGroupInfos(napi_env env,napi_callback_info info)251 napi_value AudioVolumeManagerNapi::GetVolumeGroupInfos(napi_env env, napi_callback_info info)
252 {
253     HiLog::Info(LABEL, " %{public}s IN", __func__);
254 
255     napi_status status;
256     const int32_t refCount = 1;
257     napi_value result = nullptr;
258 
259     GET_PARAMS(env, info, ARGS_TWO);
260 
261     unique_ptr<AudioVolumeManagerAsyncContext> asyncContext = make_unique<AudioVolumeManagerAsyncContext>();
262     if (argc < ARGS_ONE) {
263         asyncContext->status = NAPI_ERR_INVALID_PARAM;
264     }
265     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
266     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
267         for (size_t i = PARAM0; i < argc; i++) {
268             napi_valuetype valueType = napi_undefined;
269             napi_typeof(env, argv[i], &valueType);
270             if (i == PARAM0 && valueType == napi_string) {
271                 asyncContext->networkId = AudioCommonNapi::GetStringArgument(env, argv[i]);
272             } else if (i == PARAM1) {
273                 if (valueType == napi_function) {
274                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
275                 }
276                 break;
277             } else {
278                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
279             }
280         }
281 
282         if (asyncContext->callbackRef == nullptr) {
283             napi_create_promise(env, &asyncContext->deferred, &result);
284         } else {
285             napi_get_undefined(env, &result);
286         }
287 
288         napi_value resource = nullptr;
289         napi_create_string_utf8(env, "GetVolumeGroupInfos", NAPI_AUTO_LENGTH, &resource);
290 
291         status = napi_create_async_work(
292             env, nullptr, resource,
293             [](napi_env env, void* data) {
294                 auto context = static_cast<AudioVolumeManagerAsyncContext*>(data);
295                 if (!context->status) {
296                     context->status = context->objectInfo->audioSystemMngr_->
297                         GetVolumeGroups(context->networkId, context->volumeGroupInfos);
298                 }
299             },
300             GetVolumeGroupInfosAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
301         if (status != napi_ok) {
302             AudioCommonNapi::throwError(env, NAPI_ERR_SYSTEM);
303             result = nullptr;
304         } else {
305             status = napi_queue_async_work(env, asyncContext->work);
306             if (status == napi_ok) {
307                 asyncContext.release();
308             } else {
309                 result = nullptr;
310             }
311         }
312     }
313 
314     return result;
315 }
316 
GetVolumeGroupInfosSync(napi_env env,napi_callback_info info)317 napi_value AudioVolumeManagerNapi::GetVolumeGroupInfosSync(napi_env env, napi_callback_info info)
318 {
319     HiLog::Info(LABEL, " %{public}s IN", __func__);
320 
321     napi_status status;
322     napi_value result = nullptr;
323     void *native = nullptr;
324 
325     GET_PARAMS(env, info, ARGS_ONE);
326 
327     if (argc < ARGS_ONE) {
328         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
329         return result;
330     }
331 
332     status = napi_unwrap(env, thisVar, &native);
333     auto *audioVolumeManagerNapi = reinterpret_cast<AudioVolumeManagerNapi *>(native);
334     if (status != napi_ok || audioVolumeManagerNapi == nullptr) {
335         AUDIO_ERR_LOG("GetVolumeGroupInfosSync unwrap failure!");
336         return result;
337     }
338 
339     napi_valuetype valueType = napi_undefined;
340     napi_typeof(env, argv[PARAM0], &valueType);
341     if (valueType != napi_string) {
342         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
343         return result;
344     }
345 
346     std::string networkId = AudioCommonNapi::GetStringArgument(env, argv[PARAM0]);
347     if (networkId.empty()) {
348         AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
349         return result;
350     }
351 
352     vector<sptr<VolumeGroupInfo>> volumeGroupInfos;
353     int32_t ret = audioVolumeManagerNapi->audioSystemMngr_->GetVolumeGroups(networkId, volumeGroupInfos);
354     if (ret != AUDIO_OK) {
355         AUDIO_ERR_LOG("GetVolumeGroups failure!");
356         return result;
357     }
358 
359     napi_value valueParam = nullptr;
360     napi_create_array_with_length(env, volumeGroupInfos.size(), &result);
361     for (size_t i = 0; i < volumeGroupInfos.size(); i++) {
362         if (volumeGroupInfos[i] != nullptr) {
363             (void)napi_create_object(env, &valueParam);
364             SetValueString(env, "networkId", static_cast<std::string>(volumeGroupInfos[i]->networkId_), valueParam);
365             SetValueInt32(env, "groupId", static_cast<int32_t>(volumeGroupInfos[i]->volumeGroupId_), valueParam);
366             SetValueInt32(env, "mappingId", static_cast<int32_t>(volumeGroupInfos[i]->mappingId_), valueParam);
367             SetValueString(env, "groupName", static_cast<std::string>(volumeGroupInfos[i]->groupName_), valueParam);
368             SetValueInt32(env, "ConnectType", static_cast<int32_t>(volumeGroupInfos[i]->connectType_), valueParam);
369             napi_set_element(env, result, i, valueParam);
370         }
371     }
372 
373     return result;
374 }
375 
GetGroupMgrAsyncCallbackComplete(napi_env env,napi_status status,void * data)376 static void GetGroupMgrAsyncCallbackComplete(napi_env env, napi_status status, void* data)
377 {
378     napi_value valueParam = nullptr;
379     auto asyncContext = static_cast<AudioVolumeManagerAsyncContext *>(data);
380 
381     if (asyncContext != nullptr) {
382         if (!asyncContext->status) {
383             valueParam = AudioVolumeGroupManagerNapi::CreateAudioVolumeGroupManagerWrapper(env, asyncContext->groupId);
384             asyncContext->status = AudioVolumeGroupManagerNapi::isConstructSuccess_;
385             AudioVolumeGroupManagerNapi::isConstructSuccess_ = SUCCESS;
386         }
387         CommonCallbackRoutine(env, asyncContext, valueParam);
388     } else {
389         HiLog::Error(LABEL, "ERROR: GetStreamMgrAsyncCallbackComplete asyncContext is Null!");
390     }
391 }
392 
GetVolumeGroupManager(napi_env env,napi_callback_info info)393 napi_value AudioVolumeManagerNapi::GetVolumeGroupManager(napi_env env, napi_callback_info info)
394 {
395     HiLog::Info(LABEL, " %{public}s IN", __func__);
396     napi_status status;
397     const int32_t refCount = 1;
398     napi_value result = nullptr;
399 
400     GET_PARAMS(env, info, ARGS_TWO);
401 
402     unique_ptr<AudioVolumeManagerAsyncContext> asyncContext = make_unique<AudioVolumeManagerAsyncContext>();
403     CHECK_AND_RETURN_RET_LOG(asyncContext != nullptr, nullptr, "AudioVolumeManagerAsyncContext object creation failed");
404     if (argc < ARGS_ONE) {
405         asyncContext->status = NAPI_ERR_INVALID_PARAM;
406     }
407     for (size_t i = PARAM0; i < argc; i++) {
408         napi_valuetype valueType = napi_undefined;
409         napi_typeof(env, argv[i], &valueType);
410         if (i == PARAM0 && valueType == napi_number) {
411             napi_get_value_int32(env, argv[i], &asyncContext->groupId);
412         } else if (i == PARAM1) {
413             if (valueType == napi_function) {
414                 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
415             }
416             break;
417         } else {
418             asyncContext->status = NAPI_ERR_INVALID_PARAM;
419         }
420     }
421 
422     if (asyncContext->callbackRef == nullptr) {
423         napi_create_promise(env, &asyncContext->deferred, &result);
424     } else {
425         napi_get_undefined(env, &result);
426     }
427 
428     napi_value resource = nullptr;
429     napi_create_string_utf8(env, "GetVolumeGroupManager", NAPI_AUTO_LENGTH, &resource);
430 
431     status = napi_create_async_work(
432         env, nullptr, resource,
433         [](napi_env env, void *data) {
434             auto context = static_cast<AudioVolumeManagerAsyncContext *>(data);
435             if (!context->status) {
436                 context->status = SUCCESS;
437             }
438         },
439         GetGroupMgrAsyncCallbackComplete, static_cast<void *>(asyncContext.get()), &asyncContext->work);
440     if (status != napi_ok) {
441         result = nullptr;
442     } else {
443         status = napi_queue_async_work(env, asyncContext->work);
444         if (status == napi_ok) {
445             asyncContext.release();
446         } else {
447             result = nullptr;
448         }
449     }
450 
451     return result;
452 }
453 
GetVolumeGroupManagerSync(napi_env env,napi_callback_info info)454 napi_value AudioVolumeManagerNapi::GetVolumeGroupManagerSync(napi_env env, napi_callback_info info)
455 {
456     HiLog::Info(LABEL, " %{public}s IN", __func__);
457 
458     GET_PARAMS(env, info, ARGS_ONE);
459 
460     if (argc < ARGS_ONE) {
461         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
462         return nullptr;
463     }
464 
465     napi_valuetype valueType = napi_undefined;
466     napi_typeof(env, argv[PARAM0], &valueType);
467     if (valueType != napi_number) {
468         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
469         return nullptr;
470     }
471 
472     int32_t groupId;
473     napi_get_value_int32(env, argv[PARAM0], &groupId);
474 
475     return AudioVolumeGroupManagerNapi::CreateAudioVolumeGroupManagerWrapper(env, groupId);
476 }
477 
On(napi_env env,napi_callback_info info)478 napi_value AudioVolumeManagerNapi::On(napi_env env, napi_callback_info info)
479 {
480     napi_value undefinedResult = nullptr;
481     napi_get_undefined(env, &undefinedResult);
482 
483     const size_t minArgCount = 2;
484     size_t argCount = 3;
485     napi_value args[minArgCount + 1] = {nullptr, nullptr, nullptr};
486     napi_value jsThis = nullptr;
487     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
488     if (status != napi_ok || argCount < minArgCount) {
489         AUDIO_ERR_LOG("On fail to napi_get_cb_info/Requires min 2 parameters");
490         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
491     }
492 
493     napi_valuetype eventType = napi_undefined;
494     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
495         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
496         return undefinedResult;
497     }
498     std::string callbackName = AudioCommonNapi::GetStringArgument(env, args[0]);
499     AUDIO_INFO_LOG("On callbackName: %{public}s", callbackName.c_str());
500 
501     AudioVolumeManagerNapi *volumeManagerNapi = nullptr;
502     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&volumeManagerNapi));
503     NAPI_ASSERT(env, status == napi_ok && volumeManagerNapi != nullptr,
504         "Failed to retrieve audio manager napi instance.");
505     NAPI_ASSERT(env, volumeManagerNapi->audioSystemMngr_ != nullptr,
506         "audio system manager instance is null.");
507 
508     napi_valuetype handler = napi_undefined;
509     if (napi_typeof(env, args[PARAM1], &handler) != napi_ok || handler != napi_function) {
510         AUDIO_ERR_LOG("On type mismatch for parameter 2");
511         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
512         return undefinedResult;
513     }
514 
515     if (!callbackName.compare(VOLUME_CHANGE_CALLBACK_NAME)) {
516         if (volumeManagerNapi->volumeKeyEventCallbackNapi_ == nullptr) {
517             volumeManagerNapi->volumeKeyEventCallbackNapi_ = std::make_shared<AudioVolumeKeyEventNapi>(env);
518             int32_t ret = volumeManagerNapi->audioSystemMngr_->RegisterVolumeKeyEventCallback(
519                 volumeManagerNapi->cachedClientId_, volumeManagerNapi->volumeKeyEventCallbackNapi_);
520             if (ret) {
521                 AUDIO_ERR_LOG("RegisterVolumeKeyEventCallback Failed");
522             } else {
523                 AUDIO_DEBUG_LOG("RegisterVolumeKeyEventCallback Success");
524             }
525         }
526         std::shared_ptr<AudioVolumeKeyEventNapi> cb =
527             std::static_pointer_cast<AudioVolumeKeyEventNapi>(volumeManagerNapi->volumeKeyEventCallbackNapi_);
528         cb->SaveCallbackReference(callbackName, args[PARAM1]);
529     } else {
530         AUDIO_ERR_LOG("No such callback supported");
531         AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
532     }
533     return undefinedResult;
534 }
535 } // namespace AudioStandard
536 } // namespace OHOS
537