1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef LOG_TAG
16 #define LOG_TAG "NapiAudioVolumeManager"
17 #endif
18 
19 #include "napi_audio_volume_manager.h"
20 #include "napi_audio_volume_group_manager.h"
21 #include "napi_audio_enum.h"
22 #include "napi_audio_error.h"
23 #include "napi_param_utils.h"
24 #include "audio_errors.h"
25 #include "audio_manager_log.h"
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 static __thread napi_ref g_volumeManagerConstructor = nullptr;
30 
NapiAudioVolumeManager()31 NapiAudioVolumeManager::NapiAudioVolumeManager()
32     : audioSystemMngr_(nullptr), env_(nullptr) {}
33 
34 NapiAudioVolumeManager::~NapiAudioVolumeManager() = default;
35 
CheckContextStatus(std::shared_ptr<AudioVolumeManagerAsyncContext> context)36 bool NapiAudioVolumeManager::CheckContextStatus(std::shared_ptr<AudioVolumeManagerAsyncContext> context)
37 {
38     CHECK_AND_RETURN_RET_LOG(context != nullptr, false, "context object is nullptr.");
39     if (context->native == nullptr) {
40         context->SignError(NAPI_ERR_SYSTEM);
41         AUDIO_ERR_LOG("context object state is error.");
42         return false;
43     }
44     return true;
45 }
46 
CheckAudioVolumeManagerStatus(NapiAudioVolumeManager * napi,std::shared_ptr<AudioVolumeManagerAsyncContext> context)47 bool NapiAudioVolumeManager::CheckAudioVolumeManagerStatus(NapiAudioVolumeManager *napi,
48     std::shared_ptr<AudioVolumeManagerAsyncContext> context)
49 {
50     CHECK_AND_RETURN_RET_LOG(napi != nullptr, false, "napi object is nullptr.");
51     if (napi->audioSystemMngr_ == nullptr) {
52         context->SignError(NAPI_ERR_SYSTEM);
53         AUDIO_ERR_LOG("context object state is error.");
54         return false;
55     }
56     return true;
57 }
58 
GetParamWithSync(const napi_env & env,napi_callback_info info,size_t & argc,napi_value * args)59 NapiAudioVolumeManager* NapiAudioVolumeManager::GetParamWithSync(const napi_env &env, napi_callback_info info,
60     size_t &argc, napi_value *args)
61 {
62     NapiAudioVolumeManager *napiAudioVolumeManager = nullptr;
63     napi_value jsThis = nullptr;
64 
65     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
66     CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr,
67         "GetParamWithSync fail to napi_get_cb_info");
68 
69     status = napi_unwrap(env, jsThis, (void **)&napiAudioVolumeManager);
70     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "napi_unwrap failed");
71     CHECK_AND_RETURN_RET_LOG(napiAudioVolumeManager != nullptr && napiAudioVolumeManager->audioSystemMngr_ !=
72         nullptr, napiAudioVolumeManager, "GetParamWithSync fail to napi_unwrap");
73     return napiAudioVolumeManager;
74 }
75 
Destructor(napi_env env,void * nativeObject,void * finalizeHint)76 void NapiAudioVolumeManager::Destructor(napi_env env, void *nativeObject, void *finalizeHint)
77 {
78     if (nativeObject != nullptr) {
79         auto obj = static_cast<NapiAudioVolumeManager *>(nativeObject);
80         ObjectRefMap<NapiAudioVolumeManager>::DecreaseRef(obj);
81     }
82     AUDIO_INFO_LOG("Destructor is successful");
83 }
84 
Construct(napi_env env,napi_callback_info info)85 napi_value NapiAudioVolumeManager::Construct(napi_env env, napi_callback_info info)
86 {
87     AUDIO_PRERELEASE_LOGI("Construct");
88     napi_status status;
89     napi_value result = nullptr;
90     napi_get_undefined(env, &result);
91 
92     size_t argc = ARGS_TWO;
93     napi_value argv[ARGS_TWO] = {0};
94     napi_value thisVar = nullptr;
95     void *data = nullptr;
96 
97     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
98     std::unique_ptr<NapiAudioVolumeManager> napiAudioVolumeManager = std::make_unique<NapiAudioVolumeManager>();
99     CHECK_AND_RETURN_RET_LOG(napiAudioVolumeManager != nullptr, result, "No memory");
100 
101     napiAudioVolumeManager->audioSystemMngr_ = AudioSystemManager::GetInstance();
102     napiAudioVolumeManager->env_ = env;
103     napiAudioVolumeManager->cachedClientId_ = getpid();
104     ObjectRefMap<NapiAudioVolumeManager>::Insert(napiAudioVolumeManager.get());
105 
106     status = napi_wrap(env, thisVar, static_cast<void*>(napiAudioVolumeManager.get()),
107         NapiAudioVolumeManager::Destructor, nullptr, nullptr);
108     if (status != napi_ok) {
109         ObjectRefMap<NapiAudioVolumeManager>::Erase(napiAudioVolumeManager.get());
110         return result;
111     }
112     napiAudioVolumeManager.release();
113     return thisVar;
114 }
115 
CreateVolumeManagerWrapper(napi_env env)116 napi_value NapiAudioVolumeManager::CreateVolumeManagerWrapper(napi_env env)
117 {
118     napi_status status;
119     napi_value result = nullptr;
120     napi_value constructor;
121 
122     status = napi_get_reference_value(env, g_volumeManagerConstructor, &constructor);
123     if (status != napi_ok) {
124         AUDIO_ERR_LOG("Failed in CreateVolumeManagerWrapper, %{public}d", status);
125         goto fail;
126     }
127     status = napi_new_instance(env, constructor, PARAM0, nullptr, &result);
128     if (status != napi_ok) {
129         AUDIO_ERR_LOG("napi_new_instance failed, status:%{public}d", status);
130         goto fail;
131     }
132     return result;
133 
134 fail:
135     napi_get_undefined(env, &result);
136     return result;
137 }
138 
Init(napi_env env,napi_value exports)139 napi_value NapiAudioVolumeManager::Init(napi_env env, napi_value exports)
140 {
141     napi_status status;
142     napi_value constructor;
143     napi_value result = nullptr;
144     const int32_t refCount = ARGS_ONE;
145     napi_get_undefined(env, &result);
146 
147     napi_property_descriptor audio_volume_manager_properties[] = {
148         DECLARE_NAPI_FUNCTION("getVolumeGroupInfos", GetVolumeGroupInfos),
149         DECLARE_NAPI_FUNCTION("getVolumeGroupInfosSync", GetVolumeGroupInfosSync),
150         DECLARE_NAPI_FUNCTION("getVolumeGroupManager", GetVolumeGroupManager),
151         DECLARE_NAPI_FUNCTION("getVolumeGroupManagerSync", GetVolumeGroupManagerSync),
152         DECLARE_NAPI_FUNCTION("on", On),
153         DECLARE_NAPI_FUNCTION("off", Off),
154     };
155 
156     status = napi_define_class(env, AUDIO_VOLUME_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct, nullptr,
157         sizeof(audio_volume_manager_properties) / sizeof(audio_volume_manager_properties[PARAM0]),
158         audio_volume_manager_properties, &constructor);
159     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_define_class fail");
160     status = napi_create_reference(env, constructor, refCount, &g_volumeManagerConstructor);
161     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_reference fail");
162     status = napi_set_named_property(env, exports, AUDIO_VOLUME_MANAGER_NAPI_CLASS_NAME.c_str(), constructor);
163     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_set_named_property fail");
164     return exports;
165 }
166 
GetVolumeGroupInfos(napi_env env,napi_callback_info info)167 napi_value NapiAudioVolumeManager::GetVolumeGroupInfos(napi_env env, napi_callback_info info)
168 {
169     auto context = std::make_shared<AudioVolumeManagerAsyncContext>();
170     if (context == nullptr) {
171         AUDIO_ERR_LOG("GetVolumeGroupInfos failed : no memory");
172         NapiAudioError::ThrowError(env, "GetVolumeGroupInfos failed : no memory", NAPI_ERR_NO_MEMORY);
173         return NapiParamUtils::GetUndefinedValue(env);
174     }
175 
176     auto inputParser = [env, context](size_t argc, napi_value *argv) {
177         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
178         napi_valuetype valueType = napi_undefined;
179         napi_typeof(env, argv[PARAM0], &valueType);
180         NAPI_CHECK_ARGS_RETURN_VOID(context, valueType == napi_string, "invaild valueType", NAPI_ERR_INVALID_PARAM);
181         context->networkId = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
182     };
183     context->GetCbInfo(env, info, inputParser);
184 
185     auto executor = [context]() {
186         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
187         auto obj = reinterpret_cast<NapiAudioVolumeManager*>(context->native);
188         ObjectRefMap objectGuard(obj);
189         auto *napiAudioVolumeManager = objectGuard.GetPtr();
190         CHECK_AND_RETURN_LOG(CheckAudioVolumeManagerStatus(napiAudioVolumeManager, context),
191             "audio volume group manager state is error.");
192         context->intValue = napiAudioVolumeManager->audioSystemMngr_->GetVolumeGroups(
193             context->networkId, context->volumeGroupInfos);
194         NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "getvolumegroups failed", NAPI_ERR_SYSTEM);
195     };
196 
197     auto complete = [env, context](napi_value &output) {
198         NapiParamUtils::SetVolumeGroupInfos(env, context->volumeGroupInfos, output);
199     };
200     return NapiAsyncWork::Enqueue(env, context, "GetVolumeGroupInfos", executor, complete);
201 }
202 
GetVolumeGroupInfosSync(napi_env env,napi_callback_info info)203 napi_value NapiAudioVolumeManager::GetVolumeGroupInfosSync(napi_env env, napi_callback_info info)
204 {
205     AUDIO_INFO_LOG("GetVolumeGroupInfosSync");
206     napi_value result = nullptr;
207     size_t argc = ARGS_ONE;
208     napi_value args[ARGS_ONE] = {};
209     auto *napiAudioVolumeManager = GetParamWithSync(env, info, argc, args);
210     CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
211         "mandatory parameters are left unspecified"), "invalid arguments");
212 
213     napi_valuetype valueType = napi_undefined;
214     napi_typeof(env, args[PARAM0], &valueType);
215     CHECK_AND_RETURN_RET_LOG(valueType == napi_string, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
216         "incorrect parameter types: The type of networkId must be string"), "invalid valueType");
217 
218     std::string networkId = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
219     CHECK_AND_RETURN_RET_LOG(!networkId.empty(), NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
220         "parameter verification failed: The param of networkId is empty"), "get networkid failed");
221 
222     std::vector<sptr<VolumeGroupInfo>> volumeGroupInfos;
223     if (napiAudioVolumeManager == nullptr || napiAudioVolumeManager->audioSystemMngr_ == nullptr) {
224         AUDIO_ERR_LOG("napiAudioVolumeManager or audioSystemMngr  is nullptr!");
225         return nullptr;
226     }
227     int32_t ret = napiAudioVolumeManager->audioSystemMngr_->GetVolumeGroups(networkId, volumeGroupInfos);
228     CHECK_AND_RETURN_RET_LOG(ret == AUDIO_OK, result, "GetVolumeGroups failure!");
229 
230     NapiParamUtils::SetVolumeGroupInfos(env, volumeGroupInfos, result);
231     return result;
232 }
233 
GetVolumeGroupManager(napi_env env,napi_callback_info info)234 napi_value NapiAudioVolumeManager::GetVolumeGroupManager(napi_env env, napi_callback_info info)
235 {
236     auto context = std::make_shared<AudioVolumeManagerAsyncContext>();
237     if (context == nullptr) {
238         AUDIO_ERR_LOG("GetVolumeGroupManager failed : no memory");
239         NapiAudioError::ThrowError(env, "GetVolumeGroupManager failed : no memory", NAPI_ERR_NO_MEMORY);
240         return NapiParamUtils::GetUndefinedValue(env);
241     }
242 
243     auto inputParser = [env, context](size_t argc, napi_value *argv) {
244         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", NAPI_ERR_INVALID_PARAM);
245         context->status = NapiParamUtils::GetValueInt32(env, context->groupId, argv[PARAM0]);
246         NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get groupId failed", NAPI_ERR_INVALID_PARAM);
247     };
248     context->GetCbInfo(env, info, inputParser);
249 
250     auto complete = [env, context](napi_value &output) {
251         output = NapiAudioVolumeGroupManager::CreateAudioVolumeGroupManagerWrapper(env, context->groupId);
252         NapiAudioVolumeGroupManager::isConstructSuccess_ = SUCCESS;
253     };
254     return NapiAsyncWork::Enqueue(env, context, "GetVolumeGroupManager", nullptr, complete);
255 }
256 
GetVolumeGroupManagerSync(napi_env env,napi_callback_info info)257 napi_value NapiAudioVolumeManager::GetVolumeGroupManagerSync(napi_env env, napi_callback_info info)
258 {
259     napi_value result = nullptr;
260     size_t argc = ARGS_ONE;
261     napi_value args[ARGS_ONE] = {};
262     napi_status status = NapiParamUtils::GetParam(env, info, argc, args);
263     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "getparam failed");
264     CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
265         "mandatory parameters are left unspecified"), "invalid arguments");
266 
267     napi_valuetype valueType = napi_undefined;
268     napi_typeof(env, args[PARAM0], &valueType);
269     CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
270         "incorrect parameter types: The type of groupId must be number"), "invalid valueType");
271 
272     int32_t groupId;
273     NapiParamUtils::GetValueInt32(env, groupId, args[PARAM0]);
274 
275     result = NapiAudioVolumeGroupManager::CreateAudioVolumeGroupManagerWrapper(env, groupId);
276 
277     napi_value undefinedValue = nullptr;
278     napi_get_undefined(env, &undefinedValue);
279     bool isEqual = false;
280     napi_strict_equals(env, result, undefinedValue, &isEqual);
281     if (isEqual) {
282         AUDIO_ERR_LOG("The audio volume group manager is undefined!");
283         NapiAudioError::ThrowError(env, "GetVolumeGroupManagerSync failed: invalid param", NAPI_ERR_INVALID_PARAM);
284         return result;
285     }
286 
287     return result;
288 }
289 
RegisterCallback(napi_env env,napi_value jsThis,size_t argc,napi_value * args,const std::string & cbName)290 napi_value NapiAudioVolumeManager::RegisterCallback(napi_env env, napi_value jsThis, size_t argc, napi_value *args,
291     const std::string &cbName)
292 {
293     napi_value undefinedResult = nullptr;
294     NapiAudioVolumeManager *napiVolumeManager = nullptr;
295     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiVolumeManager));
296     CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM),
297         "status error");
298     CHECK_AND_RETURN_RET_LOG(napiVolumeManager != nullptr, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY),
299         "napiVolumeManager is nullptr");
300     CHECK_AND_RETURN_RET_LOG(napiVolumeManager->audioSystemMngr_ != nullptr, NapiAudioError::ThrowErrorAndReturn(
301         env, NAPI_ERR_NO_MEMORY), "audioSystemMngr_ is nullptr");
302 
303     if (!cbName.compare(VOLUME_KEY_EVENT_CALLBACK_NAME)) {
304         if (napiVolumeManager->volumeKeyEventCallbackNapi_ == nullptr) {
305             napiVolumeManager->volumeKeyEventCallbackNapi_ = std::make_shared<NapiAudioVolumeKeyEvent>(env);
306             int32_t ret = napiVolumeManager->audioSystemMngr_->RegisterVolumeKeyEventCallback(
307                 napiVolumeManager->cachedClientId_, napiVolumeManager->volumeKeyEventCallbackNapi_);
308             napiVolumeManager->volumeKeyEventCallbackNapiList_.push_back(
309                 std::static_pointer_cast<NapiAudioVolumeKeyEvent>(napiVolumeManager->volumeKeyEventCallbackNapi_));
310             if (ret) {
311                 AUDIO_ERR_LOG("RegisterVolumeKeyEventCallback Failed");
312             }
313         }
314         std::shared_ptr<NapiAudioVolumeKeyEvent> cb =
315             std::static_pointer_cast<NapiAudioVolumeKeyEvent>(napiVolumeManager->volumeKeyEventCallbackNapi_);
316         cb->SaveCallbackReference(cbName, args[PARAM1]);
317     } else {
318         AUDIO_ERR_LOG("No such callback supported");
319         NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
320             "parameter verification failed: The param of type is not supported");
321     }
322     return undefinedResult;
323 }
324 
On(napi_env env,napi_callback_info info)325 napi_value NapiAudioVolumeManager::On(napi_env env, napi_callback_info info)
326 {
327     napi_value undefinedResult = nullptr;
328     napi_get_undefined(env, &undefinedResult);
329 
330     const size_t minArgCount = ARGS_TWO;
331     size_t argCount = ARGS_THREE;
332     napi_value args[minArgCount + PARAM1] = {nullptr, nullptr, nullptr};
333     napi_value jsThis = nullptr;
334     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
335     if (status != napi_ok || argCount < minArgCount) {
336         AUDIO_ERR_LOG("On fail to napi_get_cb_info/Requires min 2 parameters");
337         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified");
338     }
339 
340     napi_valuetype eventType = napi_undefined;
341     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
342         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
343             "incorrect parameter types: The type of eventType must be string");
344         return undefinedResult;
345     }
346     std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
347     AUDIO_INFO_LOG("On callbackName: %{public}s", callbackName.c_str());
348 
349     napi_valuetype handler = napi_undefined;
350     if (napi_typeof(env, args[PARAM1], &handler) != napi_ok || handler != napi_function) {
351         AUDIO_ERR_LOG("On type mismatch for parameter 2");
352         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
353             "incorrect parameter types: The type of callback must be function");
354         return undefinedResult;
355     }
356 
357     return RegisterCallback(env, jsThis, argCount, args, callbackName);
358 }
359 
Off(napi_env env,napi_callback_info info)360 napi_value NapiAudioVolumeManager::Off(napi_env env, napi_callback_info info)
361 {
362     napi_value undefinedResult = nullptr;
363     napi_get_undefined(env, &undefinedResult);
364 
365     const size_t minArgCount = ARGS_ONE;
366     size_t argc = ARGS_TWO;
367     napi_value args[minArgCount + PARAM2] = {nullptr, nullptr, nullptr};
368     napi_value jsThis = nullptr;
369     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
370     if (status != napi_ok || argc < minArgCount) {
371         AUDIO_ERR_LOG("Off fail to napi_get_cb_info/Requires min 1 parameters");
372         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified");
373     }
374     napi_valuetype eventType = napi_undefined;
375     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
376         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
377             "incorrect parameter types: The type of eventType must be string");
378         return undefinedResult;
379     }
380     std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
381     AUDIO_INFO_LOG("Off callbackName: %{public}s", callbackName.c_str());
382 
383     return UnregisterCallback(env, jsThis, argc, args, callbackName);
384 }
385 
UnregisterCallback(napi_env env,napi_value jsThis,size_t argc,napi_value * args,const std::string & cbName)386 napi_value NapiAudioVolumeManager::UnregisterCallback(napi_env env, napi_value jsThis,
387     size_t argc, napi_value *args, const std::string &cbName)
388 {
389     napi_value undefinedResult = nullptr;
390     NapiAudioVolumeManager *napiVolumeManager = nullptr;
391     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiVolumeManager));
392     CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM),
393         "status error");
394     CHECK_AND_RETURN_RET_LOG(napiVolumeManager != nullptr, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY),
395         "napiVolumeManager is nullptr");
396     CHECK_AND_RETURN_RET_LOG(napiVolumeManager->audioSystemMngr_ != nullptr, NapiAudioError::ThrowErrorAndReturn(
397         env, NAPI_ERR_NO_MEMORY), "audioSystemMngr_ is nullptr");
398 
399     if (!cbName.compare(VOLUME_KEY_EVENT_CALLBACK_NAME)) {
400         napi_value callback = nullptr;
401         if (argc == ARGS_TWO) {
402             callback = args[PARAM1];
403         }
404         if (callback != nullptr) {
405             std::shared_ptr<NapiAudioVolumeKeyEvent> cb = GetVolumeEventNapiCallback(callback, napiVolumeManager);
406             CHECK_AND_RETURN_RET_LOG(cb != nullptr, undefinedResult, "NapiAudioVolumeKeyEvent is nullptr");
407             int32_t ret = napiVolumeManager->audioSystemMngr_->UnregisterVolumeKeyEventCallback(
408                 napiVolumeManager->cachedClientId_, cb);
409             CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, undefinedResult, "Unset of VolumeKeyEventCallback failed");
410             napiVolumeManager->volumeKeyEventCallbackNapiList_.remove(cb);
411             napiVolumeManager->volumeKeyEventCallbackNapi_.reset();
412             napiVolumeManager->volumeKeyEventCallbackNapi_ = nullptr;
413             return undefinedResult;
414         } else {
415             int32_t ret = napiVolumeManager->audioSystemMngr_->UnregisterVolumeKeyEventCallback(
416                 napiVolumeManager->cachedClientId_);
417             CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, undefinedResult, "Unset of VolumeKeyEventCallback failed");
418             napiVolumeManager->volumeKeyEventCallbackNapiList_.clear();
419             napiVolumeManager->volumeKeyEventCallbackNapi_.reset();
420             napiVolumeManager->volumeKeyEventCallbackNapi_ = nullptr;
421             return undefinedResult;
422         }
423     } else {
424         AUDIO_ERR_LOG("No such callback supported");
425         NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
426             "parameter verification failed: The param of type is not supported");
427     }
428     return undefinedResult;
429 }
430 
GetVolumeEventNapiCallback(napi_value argv,NapiAudioVolumeManager * napiVolumeManager)431 std::shared_ptr<NapiAudioVolumeKeyEvent> NapiAudioVolumeManager::GetVolumeEventNapiCallback(napi_value argv,
432     NapiAudioVolumeManager *napiVolumeManager)
433 {
434     std::shared_ptr<NapiAudioVolumeKeyEvent> cb = nullptr;
435     for (auto &iter : napiVolumeManager->volumeKeyEventCallbackNapiList_) {
436         if (iter->ContainSameJsCallback(argv)) {
437             cb = iter;
438         }
439     }
440     return cb;
441 }
442 }  // namespace AudioStandard
443 }  // namespace OHOS