• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "audio_haptic_player_napi.h"
17 
18 #include "audio_haptic_log.h"
19 
20 namespace {
21 /* Constants for array index */
22 const int32_t PARAM0 = 0;
23 const int32_t PARAM1 = 1;
24 
25 /* Constants for array size */
26 const int32_t ARGS_ONE = 1;
27 const int32_t ARGS_TWO = 2;
28 
29 const std::string AUDIO_INTERRUPT_CALLBACK_NAME = "audioInterrupt";
30 const std::string END_OF_STREAM_CALLBACK_NAME = "endOfStream";
31 
32 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO_NAPI, "AudioHapticPlayerNapi"};
33 }
34 
35 namespace OHOS {
36 namespace Media {
37 thread_local napi_ref AudioHapticPlayerNapi::sConstructor_ = nullptr;
38 std::shared_ptr<AudioHapticPlayer> AudioHapticPlayerNapi::sAudioHapticPlayer_ = nullptr;
39 
AudioHapticPlayerNapi()40 AudioHapticPlayerNapi::AudioHapticPlayerNapi() : env_(nullptr) {}
41 
42 AudioHapticPlayerNapi::~AudioHapticPlayerNapi() = default;
43 
Init(napi_env env,napi_value exports)44 napi_value AudioHapticPlayerNapi::Init(napi_env env, napi_value exports)
45 {
46     napi_status status;
47     napi_value ctorObj;
48     int32_t refCount = 1;
49 
50     napi_property_descriptor audioHapticPlayerProp[] = {
51         DECLARE_NAPI_FUNCTION("isMuted", IsMuted),
52         DECLARE_NAPI_FUNCTION("start", Start),
53         DECLARE_NAPI_FUNCTION("stop", Stop),
54         DECLARE_NAPI_FUNCTION("release", Release),
55         DECLARE_NAPI_FUNCTION("on", On),
56         DECLARE_NAPI_FUNCTION("off", Off),
57     };
58 
59     status = napi_define_class(env, AUDIO_HAPTIC_PLAYER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor,
60         nullptr, sizeof(audioHapticPlayerProp) / sizeof(audioHapticPlayerProp[0]), audioHapticPlayerProp, &ctorObj);
61     if (status == napi_ok) {
62         if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
63             status = napi_set_named_property(env, exports, AUDIO_HAPTIC_PLAYER_NAPI_CLASS_NAME.c_str(), ctorObj);
64             if (status == napi_ok) {
65                 return exports;
66             }
67         }
68     }
69 
70     return nullptr;
71 }
72 
Constructor(napi_env env,napi_callback_info info)73 napi_value AudioHapticPlayerNapi::Constructor(napi_env env, napi_callback_info info)
74 {
75     napi_status status;
76     napi_value result = nullptr;
77     napi_value thisVar = nullptr;
78 
79     napi_get_undefined(env, &result);
80     status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
81     if (status == napi_ok && thisVar != nullptr) {
82         std::unique_ptr<AudioHapticPlayerNapi> obj = std::make_unique<AudioHapticPlayerNapi>();
83         if (obj != nullptr) {
84             obj->env_ = env;
85             if (obj->sAudioHapticPlayer_ != nullptr) {
86                 obj->audioHapticPlayer_ = move(obj->sAudioHapticPlayer_);
87             } else {
88                 MEDIA_LOGE("Failed to create sAudioHapticPlayer_ instance.");
89                 return result;
90             }
91 
92             if (obj->audioHapticPlayer_ != nullptr && obj->callbackNapi_ == nullptr) {
93                 obj->callbackNapi_ = std::make_shared<AudioHapticPlayerCallbackNapi>(env);
94                 CHECK_AND_RETURN_RET_LOG(obj->callbackNapi_ != nullptr, result, "No memory");
95                 int32_t ret = obj->audioHapticPlayer_->SetAudioHapticPlayerCallback(obj->callbackNapi_);
96                 MEDIA_LOGI("Constructor: SetAudioHapticPlayerCallback %{public}s",
97                     ret == 0 ? "succeess" : "failed");
98             }
99 
100             status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
101                 AudioHapticPlayerNapi::Destructor, nullptr, nullptr);
102             if (status == napi_ok) {
103                 obj.release();
104                 return thisVar;
105             } else {
106                 MEDIA_LOGE("Failed to wrap the native audioHapticPlayer object with JS.");
107             }
108         }
109     }
110 
111     return result;
112 }
113 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)114 void AudioHapticPlayerNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
115 {
116     AudioHapticPlayerNapi *audioHapticPlayerHelper = reinterpret_cast<AudioHapticPlayerNapi*>(nativeObject);
117     if (audioHapticPlayerHelper != nullptr) {
118         audioHapticPlayerHelper->~AudioHapticPlayerNapi();
119     }
120 }
121 
CreatePlayerInstance(napi_env env,std::shared_ptr<AudioHapticPlayer> & audioHapticPlayer)122 napi_value AudioHapticPlayerNapi::CreatePlayerInstance(napi_env env,
123     std::shared_ptr<AudioHapticPlayer> &audioHapticPlayer)
124 {
125     napi_status status;
126     napi_value result = nullptr;
127     napi_value ctor;
128 
129     status = napi_get_reference_value(env, sConstructor_, &ctor);
130     if (status == napi_ok) {
131         sAudioHapticPlayer_ = audioHapticPlayer;
132         status = napi_new_instance(env, ctor, 0, nullptr, &result);
133         if (status == napi_ok) {
134             return result;
135         } else {
136             MEDIA_LOGE("CreatePlayerInstance: New instance could not be obtained.");
137         }
138     }
139 
140     napi_get_undefined(env, &result);
141     return result;
142 }
143 
IsMuted(napi_env env,napi_callback_info info)144 napi_value AudioHapticPlayerNapi::IsMuted(napi_env env, napi_callback_info info)
145 {
146     napi_value result = nullptr;
147     napi_get_boolean(env, false, &result);
148 
149     size_t argc = ARGS_ONE;
150     napi_value argv[ARGS_ONE] = {0};
151     napi_value thisVar = nullptr;
152 
153     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
154     CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result, "IsMuted: napi_get_cb_info fail");
155     if (argc != ARGS_ONE) {
156         MEDIA_LOGE("IsMuted: requires 1 parameters");
157         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified");
158         return result;
159     }
160 
161     void *native = nullptr;
162     status = napi_unwrap(env, thisVar, &native);
163     auto *audioHapticPlayerNapi = reinterpret_cast<AudioHapticPlayerNapi *>(native);
164     if (status != napi_ok || audioHapticPlayerNapi == nullptr) {
165         MEDIA_LOGE("IsMuted: unwrap failure!");
166         return result;
167     }
168 
169     napi_valuetype valueType = napi_undefined;
170     napi_typeof(env, argv[PARAM0], &valueType);
171     int32_t jsAudioHapticType = -1;
172     if (valueType == napi_number) {
173         napi_get_value_int32(env, argv[PARAM0], &jsAudioHapticType);
174     }
175     if (!IsLegalAudioHapticType(jsAudioHapticType)) {
176         MEDIA_LOGE("IsMuted: the param type mismatch");
177         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID,
178             "parameter verification failed: The param of type must be enum AudioHapticType");
179         return result;
180     }
181 
182     AudioHapticType audioHapticType = static_cast<AudioHapticType>(jsAudioHapticType);
183     bool isMuted = audioHapticPlayerNapi->audioHapticPlayer_->IsMuted(audioHapticType);
184     napi_get_boolean(env, isMuted, &result);
185 
186     return result;
187 }
188 
IsLegalAudioHapticType(int32_t audioHapticType)189 bool AudioHapticPlayerNapi::IsLegalAudioHapticType(int32_t audioHapticType)
190 {
191     switch (audioHapticType) {
192         case AUDIO_HAPTIC_TYPE_AUDIO:
193         case AUDIO_HAPTIC_TYPE_HAPTIC:
194             return true;
195         default:
196             break;
197     }
198     MEDIA_LOGE("IsLegalAudioHapticType: audioHapticType %{public}d is invalid", audioHapticType);
199     return false;
200 }
201 
CommonAsyncCallbackComp(napi_env env,napi_status status,void * data)202 void AudioHapticPlayerNapi::CommonAsyncCallbackComp(napi_env env, napi_status status, void *data)
203 {
204     auto context = static_cast<AudioHapticPlayerAsyncContext *>(data);
205     napi_value result[2] = {};
206 
207     napi_get_undefined(env, &result[PARAM1]);
208     if (!context->status) {
209         napi_get_undefined(env, &result[PARAM0]);
210     } else {
211         napi_value message = nullptr;
212         napi_create_string_utf8(env, "Error: Operation is not supported or failed", NAPI_AUTO_LENGTH, &message);
213         napi_create_error(env, nullptr, message, &result[PARAM0]);
214     }
215 
216     if (context->deferred) {
217         if (!context->status) {
218             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
219         } else {
220             napi_reject_deferred(env, context->deferred, result[PARAM0]);
221         }
222     }
223     napi_delete_async_work(env, context->work);
224 
225     delete context;
226     context = nullptr;
227 }
228 
Start(napi_env env,napi_callback_info info)229 napi_value AudioHapticPlayerNapi::Start(napi_env env, napi_callback_info info)
230 {
231     napi_value result = nullptr;
232     napi_value resource = nullptr;
233     size_t argc = ARGS_ONE;
234     napi_value argv[ARGS_ONE] = {0};
235     napi_value thisVar = nullptr;
236 
237     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
238     napi_get_undefined(env, &result);
239     CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result, "Start: napi_get_cb_info fail");
240     if (argc != 0) {
241         MEDIA_LOGE("Start: requires 0 parameters");
242         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
243         return result;
244     }
245 
246     std::unique_ptr<AudioHapticPlayerAsyncContext> asyncContext = std::make_unique<AudioHapticPlayerAsyncContext>();
247     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
248     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
249         napi_create_promise(env, &asyncContext->deferred, &result);
250         napi_create_string_utf8(env, "Start", NAPI_AUTO_LENGTH, &resource);
251         status = napi_create_async_work(env, nullptr, resource,
252             [](napi_env env, void *data) {
253                 AudioHapticPlayerAsyncContext *context = static_cast<AudioHapticPlayerAsyncContext*>(data);
254                 context->status = context->objectInfo->audioHapticPlayer_->Start();
255             },
256             CommonAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
257         if (status != napi_ok) {
258             MEDIA_LOGE("Start: Failed to get create async work");
259             napi_get_undefined(env, &result);
260         } else {
261             napi_queue_async_work(env, asyncContext->work);
262             asyncContext.release();
263         }
264     }
265 
266     return result;
267 }
268 
Stop(napi_env env,napi_callback_info info)269 napi_value AudioHapticPlayerNapi::Stop(napi_env env, napi_callback_info info)
270 {
271     napi_value result = nullptr;
272     napi_value resource = nullptr;
273     size_t argc = ARGS_ONE;
274     napi_value argv[ARGS_ONE] = {0};
275     napi_value thisVar = nullptr;
276 
277     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
278     napi_get_undefined(env, &result);
279     CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result, "Stop: napi_get_cb_info fail");
280     if (argc != 0) {
281         MEDIA_LOGE("Stop: requires 0 parameters");
282         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
283         return result;
284     }
285 
286     std::unique_ptr<AudioHapticPlayerAsyncContext> asyncContext = std::make_unique<AudioHapticPlayerAsyncContext>();
287     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
288     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
289         napi_create_promise(env, &asyncContext->deferred, &result);
290         napi_create_string_utf8(env, "Stop", NAPI_AUTO_LENGTH, &resource);
291         status = napi_create_async_work(env, nullptr, resource,
292             [](napi_env env, void *data) {
293                 AudioHapticPlayerAsyncContext *context = static_cast<AudioHapticPlayerAsyncContext*>(data);
294                 context->status = context->objectInfo->audioHapticPlayer_->Stop();
295             },
296             CommonAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
297         if (status != napi_ok) {
298             MEDIA_LOGE("Stop: Failed to get create async work");
299             napi_get_undefined(env, &result);
300         } else {
301             napi_queue_async_work(env, asyncContext->work);
302             asyncContext.release();
303         }
304     }
305 
306     return result;
307 }
308 
Release(napi_env env,napi_callback_info info)309 napi_value AudioHapticPlayerNapi::Release(napi_env env, napi_callback_info info)
310 {
311     napi_value result = nullptr;
312     napi_value resource = nullptr;
313     size_t argc = ARGS_ONE;
314     napi_value argv[ARGS_ONE] = {0};
315     napi_value thisVar = nullptr;
316 
317     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
318     napi_get_undefined(env, &result);
319     CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result, "Release: napi_get_cb_info fail");
320     if (argc != 0) {
321         MEDIA_LOGE("Release: requires 0 parameters");
322         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
323         return result;
324     }
325 
326     std::unique_ptr<AudioHapticPlayerAsyncContext> asyncContext = std::make_unique<AudioHapticPlayerAsyncContext>();
327     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
328     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
329         napi_create_promise(env, &asyncContext->deferred, &result);
330         napi_create_string_utf8(env, "Release", NAPI_AUTO_LENGTH, &resource);
331         status = napi_create_async_work(env, nullptr, resource,
332             [](napi_env env, void *data) {
333                 AudioHapticPlayerAsyncContext *context = static_cast<AudioHapticPlayerAsyncContext*>(data);
334                 context->status = context->objectInfo->audioHapticPlayer_->Release();
335             },
336             CommonAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
337         if (status != napi_ok) {
338             MEDIA_LOGE("Release: Failed to get create async work");
339             napi_get_undefined(env, &result);
340         } else {
341             napi_queue_async_work(env, asyncContext->work);
342             asyncContext.release();
343         }
344     }
345 
346     return result;
347 }
348 
On(napi_env env,napi_callback_info info)349 napi_value AudioHapticPlayerNapi::On(napi_env env, napi_callback_info info)
350 {
351     napi_value result = nullptr;
352     size_t argc = ARGS_TWO;
353     napi_value argv[ARGS_TWO] = {nullptr};
354     napi_value jsThis = nullptr;
355     napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
356     CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, result, "On: napi_get_cb_info fail");
357     if (argc != ARGS_TWO) {
358         MEDIA_LOGE("On: requires 2 parameters");
359         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
360         return result;
361     }
362 
363     napi_valuetype argvType = napi_undefined;
364     napi_typeof(env, argv[PARAM0], &argvType);
365     if (argvType != napi_string) {
366         MEDIA_LOGE("On: the first parameter must be napi_string");
367         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
368         return result;
369     }
370     std::string callbackName = AudioHapticCommonNapi::GetStringArgument(env, argv[0]);
371     MEDIA_LOGI("On: callbackName: %{public}s", callbackName.c_str());
372 
373     napi_typeof(env, argv[PARAM1], &argvType);
374     if (argvType != napi_function) {
375         MEDIA_LOGE("On: the second parameter must be napi_function");
376         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
377         return result;
378     }
379 
380     return RegisterCallback(env, jsThis, argv, callbackName);
381 }
382 
RegisterCallback(napi_env env,napi_value jsThis,napi_value * argv,const std::string & cbName)383 napi_value AudioHapticPlayerNapi::RegisterCallback(napi_env env, napi_value jsThis, napi_value* argv,
384     const std::string& cbName)
385 {
386     napi_value result = nullptr;
387     napi_get_undefined(env, &result);
388 
389     AudioHapticPlayerNapi *audioHapticPlayerNapi = nullptr;
390     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&audioHapticPlayerNapi));
391     if (status != napi_ok || audioHapticPlayerNapi == nullptr || audioHapticPlayerNapi->audioHapticPlayer_ == nullptr) {
392         MEDIA_LOGE("RegisterCallback: Failed to get audioHapticPlayer_");
393         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_OPERATE_NOT_ALLOWED);
394         return result;
395     }
396 
397     if (!cbName.compare(AUDIO_INTERRUPT_CALLBACK_NAME) ||
398         !cbName.compare(END_OF_STREAM_CALLBACK_NAME)) {
399         result = RegisterAudioHapticPlayerCallback(env, argv, cbName, audioHapticPlayerNapi);
400     } else {
401         MEDIA_LOGE("RegisterCallback: the callback name: %{public}s is not supported", cbName.c_str());
402         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
403         return result;
404     }
405 
406     return result;
407 }
408 
RegisterAudioHapticPlayerCallback(napi_env env,napi_value * argv,const std::string & cbName,AudioHapticPlayerNapi * audioHapticPlayerNapi)409 napi_value AudioHapticPlayerNapi::RegisterAudioHapticPlayerCallback(napi_env env, napi_value* argv,
410     const std::string& cbName, AudioHapticPlayerNapi *audioHapticPlayerNapi)
411 {
412     napi_value result = nullptr;
413     napi_get_undefined(env, &result);
414 
415     if (audioHapticPlayerNapi->callbackNapi_ == nullptr) {
416         MEDIA_LOGE("RegisterAudioHapticPlayerCallback: callbackNapi_ is null");
417         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_OPERATE_NOT_ALLOWED);
418         return result;
419     }
420     audioHapticPlayerNapi->callbackNapi_->SaveCallbackReference(cbName, argv[PARAM1]);
421 
422     return result;
423 }
424 
Off(napi_env env,napi_callback_info info)425 napi_value AudioHapticPlayerNapi::Off(napi_env env, napi_callback_info info)
426 {
427     napi_value result = nullptr;
428     size_t argc = ARGS_TWO;
429     napi_value argv[ARGS_TWO] = {nullptr};
430     napi_value jsThis = nullptr;
431     napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
432     CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, result, "Off: napi_get_cb_info fail");
433     if (argc != ARGS_ONE && argc != ARGS_TWO) {
434         MEDIA_LOGE("Off: requires 1 or 2 parameters");
435         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
436         return result;
437     }
438 
439     napi_valuetype argvType = napi_undefined;
440     napi_typeof(env, argv[PARAM0], &argvType);
441     if (argvType != napi_string) {
442         MEDIA_LOGE("Off: the parameter must be napi_string");
443         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
444         return result;
445     }
446     std::string callbackName = AudioHapticCommonNapi::GetStringArgument(env, argv[0]);
447     MEDIA_LOGI("Off: callbackName: %{public}s", callbackName.c_str());
448 
449     return UnregisterCallback(env, jsThis, callbackName);
450 }
451 
UnregisterCallback(napi_env env,napi_value jsThis,const std::string & cbName)452 napi_value AudioHapticPlayerNapi::UnregisterCallback(napi_env env, napi_value jsThis, const std::string &cbName)
453 {
454     napi_value result = nullptr;
455     napi_get_undefined(env, &result);
456 
457     AudioHapticPlayerNapi *audioHapticPlayerNapi = nullptr;
458     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&audioHapticPlayerNapi));
459     if (status != napi_ok || audioHapticPlayerNapi == nullptr || audioHapticPlayerNapi->audioHapticPlayer_ == nullptr) {
460         MEDIA_LOGE("UnregisterCallback: Failed to get audioHapticPlayer_");
461         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_OPERATE_NOT_ALLOWED);
462         return result;
463     }
464 
465     if (!cbName.compare(AUDIO_INTERRUPT_CALLBACK_NAME) ||
466         !cbName.compare(END_OF_STREAM_CALLBACK_NAME)) {
467         result = UnregisterAudioHapticPlayerCallback(env, cbName, audioHapticPlayerNapi);
468     } else {
469         MEDIA_LOGE("UnregisterCallback: the callback name: %{public}s is not supported", cbName.c_str());
470         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_INPUT_INVALID);
471         return result;
472     }
473 
474     return result;
475 }
476 
UnregisterAudioHapticPlayerCallback(napi_env env,const std::string & cbName,AudioHapticPlayerNapi * audioHapticPlayerNapi)477 napi_value AudioHapticPlayerNapi::UnregisterAudioHapticPlayerCallback(napi_env env, const std::string& cbName,
478     AudioHapticPlayerNapi *audioHapticPlayerNapi)
479 {
480     napi_value result = nullptr;
481     napi_get_undefined(env, &result);
482 
483     if (audioHapticPlayerNapi->callbackNapi_ == nullptr) {
484         MEDIA_LOGE("RegisterAudioHapticPlayerCallback: callbackNapi_ is null");
485         AudioHapticCommonNapi::ThrowError(env, NAPI_ERR_OPERATE_NOT_ALLOWED);
486         return result;
487     }
488     audioHapticPlayerNapi->callbackNapi_->RemoveCallbackReference(cbName);
489 
490     return result;
491 }
492 } // namespace Media
493 } // namespace OHOS