1 /*
2  * Copyright (C) 2021 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_player_napi.h"
17 #include <climits>
18 #include "player_callback_napi.h"
19 #include "media_log.h"
20 #include "media_errors.h"
21 #include "media_permission.h"
22 #include "string_ex.h"
23 #ifdef SUPPORT_JSSTACK
24 #include "xpower_event_js.h"
25 #endif
26 
27 namespace {
28     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "AudioPlayerNapi"};
29 }
30 
31 namespace OHOS {
32 namespace Media {
33 thread_local napi_ref AudioPlayerNapi::constructor_ = nullptr;
34 const std::string CLASS_NAME = "AudioPlayer";
35 const std::string STATE_PLAYING = "playing";
36 const std::string STATE_PAUSED = "paused";
37 const std::string STATE_STOPPED = "stopped";
38 const std::string STATE_IDLE = "idle";
39 const std::string STATE_ERROR = "error";
40 
AudioPlayerNapi()41 AudioPlayerNapi::AudioPlayerNapi()
42 {
43     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
44 }
45 
~AudioPlayerNapi()46 AudioPlayerNapi::~AudioPlayerNapi()
47 {
48     CancelCallback();
49     nativePlayer_ = nullptr;
50     callbackNapi_ = nullptr;
51 
52     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
53 }
54 
Init(napi_env env,napi_value exports)55 napi_value AudioPlayerNapi::Init(napi_env env, napi_value exports)
56 {
57     napi_property_descriptor properties[] = {
58         DECLARE_NAPI_FUNCTION("play", Play),
59         DECLARE_NAPI_FUNCTION("pause", Pause),
60         DECLARE_NAPI_FUNCTION("stop", Stop),
61         DECLARE_NAPI_FUNCTION("reset", Reset),
62         DECLARE_NAPI_FUNCTION("release", Release),
63         DECLARE_NAPI_FUNCTION("seek", Seek),
64         DECLARE_NAPI_FUNCTION("on", On),
65         DECLARE_NAPI_FUNCTION("setVolume", SetVolume),
66         DECLARE_NAPI_FUNCTION("getTrackDescription", GetTrackDescription),
67 
68         DECLARE_NAPI_GETTER_SETTER("src", GetSrc, SetSrc),
69         DECLARE_NAPI_GETTER_SETTER("fdSrc", GetFdSrc, SetFdSrc),
70         DECLARE_NAPI_GETTER_SETTER("loop", GetLoop, SetLoop),
71         DECLARE_NAPI_GETTER_SETTER("audioInterruptMode", GetAudioInterruptMode, SetAudioInterruptMode),
72 
73         DECLARE_NAPI_GETTER("currentTime", GetCurrentTime),
74         DECLARE_NAPI_GETTER("duration", GetDuration),
75         DECLARE_NAPI_GETTER("state", GetState)
76     };
77 
78     napi_property_descriptor staticProperty[] = {
79         DECLARE_NAPI_STATIC_FUNCTION("createAudioPlayer", CreateAudioPlayer),
80     };
81 
82     napi_value constructor = nullptr;
83     napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
84         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
85     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define AudioPlayer class");
86 
87     status = napi_create_reference(env, constructor, 1, &constructor_);
88     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to create reference of constructor");
89 
90     status = napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor);
91     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to set constructor");
92 
93     status = napi_define_properties(env, exports, sizeof(staticProperty) / sizeof(staticProperty[0]), staticProperty);
94     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define static function");
95 
96     MEDIA_LOGD("Init success");
97     return exports;
98 }
99 
Constructor(napi_env env,napi_callback_info info)100 napi_value AudioPlayerNapi::Constructor(napi_env env, napi_callback_info info)
101 {
102     napi_value result = nullptr;
103     napi_value jsThis = nullptr;
104     size_t argCount = 0;
105     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
106     if (status != napi_ok) {
107         napi_get_undefined(env, &result);
108         MEDIA_LOGE("Failed to retrieve details about the callback");
109         return result;
110     }
111 
112     AudioPlayerNapi *playerNapi = new(std::nothrow) AudioPlayerNapi();
113     CHECK_AND_RETURN_RET_LOG(playerNapi != nullptr, nullptr, "No memory");
114 
115     playerNapi->env_ = env;
116     playerNapi->nativePlayer_ = PlayerFactory::CreatePlayer();
117     if (playerNapi->nativePlayer_ == nullptr) {
118         MEDIA_LOGE("failed to CreatePlayer");
119     }
120 
121     if (playerNapi->callbackNapi_ == nullptr && playerNapi->nativePlayer_ != nullptr) {
122         playerNapi->callbackNapi_ = std::make_shared<PlayerCallbackNapi>(env);
123         (void)playerNapi->nativePlayer_->SetPlayerCallback(playerNapi->callbackNapi_);
124     }
125 
126     status = napi_wrap(env, jsThis, reinterpret_cast<void *>(playerNapi),
127         AudioPlayerNapi::Destructor, nullptr, nullptr);
128     if (status != napi_ok) {
129         napi_get_undefined(env, &result);
130         delete playerNapi;
131         MEDIA_LOGE("Failed to wrap native instance");
132         return result;
133     }
134 
135     MEDIA_LOGD("Constructor success");
136     return jsThis;
137 }
138 
Destructor(napi_env env,void * nativeObject,void * finalize)139 void AudioPlayerNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
140 {
141     (void)env;
142     (void)finalize;
143     if (nativeObject != nullptr) {
144         delete reinterpret_cast<AudioPlayerNapi *>(nativeObject);
145     }
146     MEDIA_LOGD("Destructor success");
147 }
148 
CreateAudioPlayer(napi_env env,napi_callback_info info)149 napi_value AudioPlayerNapi::CreateAudioPlayer(napi_env env, napi_callback_info info)
150 {
151     napi_value result = nullptr;
152     napi_value constructor = nullptr;
153     napi_status status = napi_get_reference_value(env, constructor_, &constructor);
154     if (status != napi_ok) {
155         MEDIA_LOGE("Failed to get the representation of constructor object");
156         napi_get_undefined(env, &result);
157         return result;
158     }
159 
160     status = napi_new_instance(env, constructor, 0, nullptr, &result);
161     if (status != napi_ok) {
162         MEDIA_LOGE("Failed to instantiate JavaScript audio player instance");
163         napi_get_undefined(env, &result);
164         return result;
165     }
166 
167     MEDIA_LOGD("CreateAudioPlayer success");
168     return result;
169 }
170 
CreateAudioPlayerAsync(napi_env env,napi_callback_info info)171 napi_value AudioPlayerNapi::CreateAudioPlayerAsync(napi_env env, napi_callback_info info)
172 {
173     napi_value result = nullptr;
174     napi_get_undefined(env, &result);
175     MEDIA_LOGD("CreateAudioPlayerAsync In");
176 
177     std::unique_ptr<MediaAsyncContext> asyncContext = std::make_unique<MediaAsyncContext>(env);
178 
179     // get args
180     napi_value jsThis = nullptr;
181     napi_value args[1] = { nullptr };
182     size_t argCount = 1;
183     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
184     if (status != napi_ok) {
185         asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
186     }
187 
188     asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
189     asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
190     asyncContext->JsResult = std::make_unique<MediaJsResultInstance>(constructor_);
191     napi_value resource = nullptr;
192     napi_create_string_utf8(env, "CreateAudioPlayerAsync", NAPI_AUTO_LENGTH, &resource);
193     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {},
194         MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncContext.get()), &asyncContext->work));
195     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
196     asyncContext.release();
197 
198     MEDIA_LOGD("CreateAudioPlayerAsync Out");
199     return result;
200 }
201 
SetSrc(napi_env env,napi_callback_info info)202 napi_value AudioPlayerNapi::SetSrc(napi_env env, napi_callback_info info)
203 {
204     napi_value undefinedResult = nullptr;
205     napi_get_undefined(env, &undefinedResult);
206     napi_value jsThis = nullptr;
207     napi_value args[1] = { nullptr };
208 
209     size_t argCount = 1;
210     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
211     if (status != napi_ok || jsThis == nullptr || argCount < 1) {
212         return undefinedResult;
213     }
214 
215     AudioPlayerNapi *player = nullptr;
216     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
217     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
218 
219     if (player->nativePlayer_ == nullptr) {
220         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
221         return undefinedResult;
222     }
223 
224     auto asyncContext = std::make_unique<MediaAsyncContext>(env);
225     if (!(MediaPermission::CheckReadMediaPermission() || MediaPermission::CheckNetWorkPermission())) {
226         asyncContext->SignError(MSERR_EXT_API9_NO_PERMISSION, "CreateAudioRecorder no permission");
227     }
228 
229     napi_valuetype valueType = napi_undefined;
230     if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_string) {
231         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
232         return undefinedResult;
233     }
234 
235     player->uri_ = CommonNapi::GetStringArgument(env, args[0]);
236     const std::string fdHead = "fd://";
237     const std::string httpHead = "http";
238     int32_t ret = MSERR_EXT_INVALID_VAL;
239 
240     MEDIA_LOGD("input url is %{private}s!", player->uri_.c_str());
241     if (player->uri_.find(fdHead) != std::string::npos) {
242         int32_t fd = -1;
243         std::string inputFd = player->uri_.substr(fdHead.size());
244         if (!StrToInt(inputFd, fd) || fd < 0) {
245             player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
246             return undefinedResult;
247         }
248 
249         ret = player->nativePlayer_->SetSource(fd, 0, -1);
250     } else if (player->uri_.find(httpHead) != std::string::npos) {
251         ret = player->nativePlayer_->SetSource(player->uri_);
252     }
253 
254     if (ret != MSERR_OK) {
255         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetSource");
256         return undefinedResult;
257     }
258 
259     ret = player->nativePlayer_->PrepareAsync();
260     if (ret != MSERR_OK) {
261         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to PrepareAsync");
262         return undefinedResult;
263     }
264 
265     return undefinedResult;
266 }
267 
GetSrc(napi_env env,napi_callback_info info)268 napi_value AudioPlayerNapi::GetSrc(napi_env env, napi_callback_info info)
269 {
270     napi_value undefinedResult = nullptr;
271     napi_get_undefined(env, &undefinedResult);
272     napi_value jsThis = nullptr;
273     napi_value jsResult = nullptr;
274     AudioPlayerNapi *player = nullptr;
275     size_t argCount = 0;
276 
277     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
278     if (status != napi_ok || jsThis == nullptr) {
279         MEDIA_LOGE("Failed to retrieve details about the callback");
280         return undefinedResult;
281     }
282 
283     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
284     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
285 
286     status = napi_create_string_utf8(env, player->uri_.c_str(), NAPI_AUTO_LENGTH, &jsResult);
287     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_string_utf8 error");
288 
289     MEDIA_LOGD("GetSrc success");
290     return jsResult;
291 }
292 
SetFdSrc(napi_env env,napi_callback_info info)293 napi_value AudioPlayerNapi::SetFdSrc(napi_env env, napi_callback_info info)
294 {
295     napi_value undefinedResult = nullptr;
296     napi_get_undefined(env, &undefinedResult);
297     napi_value jsThis = nullptr;
298     napi_value args[1] = { nullptr };
299 
300     size_t argCount = 1;
301     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
302     CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr && argCount > 0,
303         undefinedResult, "Failed to retrieve details about the callback");
304 
305     AudioPlayerNapi *player = nullptr;
306     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
307     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
308     if (player->nativePlayer_ == nullptr) {
309         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
310         return undefinedResult;
311     }
312 
313     napi_valuetype valueType = napi_undefined;
314     if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_object) {
315         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
316         return undefinedResult;
317     }
318 
319     if (!CommonNapi::GetFdArgument(env, args[0], player->rawFd_)) {
320         MEDIA_LOGE("get rawfd argument failed!");
321         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
322         return undefinedResult;
323     }
324 
325     int32_t ret = player->nativePlayer_->SetSource(player->rawFd_.fd, player->rawFd_.offset, player->rawFd_.length);
326     if (ret != MSERR_OK) {
327         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetSource rawFd");
328         return undefinedResult;
329     }
330 
331     ret = player->nativePlayer_->PrepareAsync();
332     if (ret != MSERR_OK) {
333         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to PrepareAsync");
334         return undefinedResult;
335     }
336 
337     MEDIA_LOGD("SetFdSrc success");
338     return undefinedResult;
339 }
340 
GetFdSrc(napi_env env,napi_callback_info info)341 napi_value AudioPlayerNapi::GetFdSrc(napi_env env, napi_callback_info info)
342 {
343     napi_value undefinedResult = nullptr;
344     napi_get_undefined(env, &undefinedResult);
345     napi_value jsThis = nullptr;
346     napi_value jsResult = nullptr;
347     AudioPlayerNapi *player = nullptr;
348     size_t argCount = 0;
349 
350     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
351     if (status != napi_ok || jsThis == nullptr) {
352         MEDIA_LOGE("Failed to retrieve details about the callback");
353         return undefinedResult;
354     }
355 
356     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
357     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
358 
359     status = napi_create_object(env, &jsResult);
360     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "create jsResult object error");
361 
362     CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt32(env, jsResult, "fd", player->rawFd_.fd) == true, nullptr);
363     CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt64(env, jsResult, "offset", player->rawFd_.offset) == true,
364         nullptr);
365     CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt64(env, jsResult, "length", player->rawFd_.length) == true,
366         nullptr);
367 
368     MEDIA_LOGD("GetFdSrc success");
369     return jsResult;
370 }
371 
Play(napi_env env,napi_callback_info info)372 napi_value AudioPlayerNapi::Play(napi_env env, napi_callback_info info)
373 {
374     napi_value undefinedResult = nullptr;
375     napi_get_undefined(env, &undefinedResult);
376 
377     size_t argCount = 0;
378     napi_value jsThis = nullptr;
379     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
380     if (status != napi_ok || jsThis == nullptr) {
381         MEDIA_LOGE("Failed to retrieve details about the callback");
382         return undefinedResult;
383     }
384 
385     AudioPlayerNapi *player = nullptr;
386     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
387     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
388 
389     if (player->nativePlayer_ == nullptr) {
390         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
391         return undefinedResult;
392     }
393 #ifdef SUPPORT_JSSTACK
394     HiviewDFX::ReportXPowerJsStackSysEvent(env, "STREAM_CHANGE", "SRC=Media");
395 #endif
396     int32_t ret = player->nativePlayer_->Play();
397     if (ret != MSERR_OK) {
398         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Play");
399         return undefinedResult;
400     }
401     MEDIA_LOGD("AudioPlayerNapi Play success");
402     return undefinedResult;
403 }
404 
Pause(napi_env env,napi_callback_info info)405 napi_value AudioPlayerNapi::Pause(napi_env env, napi_callback_info info)
406 {
407     napi_value undefinedResult = nullptr;
408     napi_get_undefined(env, &undefinedResult);
409 
410     size_t argCount = 0;
411     napi_value jsThis = nullptr;
412     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
413     if (status != napi_ok || jsThis == nullptr) {
414         MEDIA_LOGE("Failed to retrieve details about the callback");
415         return undefinedResult;
416     }
417 
418     AudioPlayerNapi *player = nullptr;
419     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
420     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
421 
422     if (player->nativePlayer_ == nullptr) {
423         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
424         return undefinedResult;
425     }
426     int32_t ret = player->nativePlayer_->Pause();
427     if (ret != MSERR_OK) {
428         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Pause");
429         return undefinedResult;
430     }
431     MEDIA_LOGD("AudioPlayerNapi Pause success");
432     return undefinedResult;
433 }
434 
Stop(napi_env env,napi_callback_info info)435 napi_value AudioPlayerNapi::Stop(napi_env env, napi_callback_info info)
436 {
437     napi_value undefinedResult = nullptr;
438     napi_get_undefined(env, &undefinedResult);
439 
440     size_t argCount = 0;
441     napi_value jsThis = nullptr;
442     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
443     if (status != napi_ok || jsThis == nullptr) {
444         MEDIA_LOGE("Failed to retrieve details about the callback");
445         return undefinedResult;
446     }
447 
448     AudioPlayerNapi *player = nullptr;
449     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
450     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
451 
452     if (player->nativePlayer_ == nullptr) {
453         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
454         return undefinedResult;
455     }
456     int32_t ret = player->nativePlayer_->Stop();
457     if (ret != MSERR_OK) {
458         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Stop");
459         return undefinedResult;
460     }
461     MEDIA_LOGD("Stop success");
462     return undefinedResult;
463 }
464 
Reset(napi_env env,napi_callback_info info)465 napi_value AudioPlayerNapi::Reset(napi_env env, napi_callback_info info)
466 {
467     MEDIA_LOGD("AudioPlayerNapi Reset");
468     napi_value undefinedResult = nullptr;
469     napi_get_undefined(env, &undefinedResult);
470 
471     size_t argCount = 0;
472     napi_value jsThis = nullptr;
473     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
474     if (status != napi_ok || jsThis == nullptr) {
475         MEDIA_LOGE("Failed to retrieve details about the callback");
476         return undefinedResult;
477     }
478 
479     AudioPlayerNapi *player = nullptr;
480     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
481     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
482 
483     if (player->nativePlayer_ == nullptr) {
484         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
485         return undefinedResult;
486     }
487 
488     int32_t ret = player->nativePlayer_->Reset();
489     if (ret != MSERR_OK) {
490         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Reset");
491         return undefinedResult;
492     }
493     MEDIA_LOGD("Reset success");
494     return undefinedResult;
495 }
496 
Release(napi_env env,napi_callback_info info)497 napi_value AudioPlayerNapi::Release(napi_env env, napi_callback_info info)
498 {
499     napi_value undefinedResult = nullptr;
500     napi_get_undefined(env, &undefinedResult);
501 
502     size_t argCount = 0;
503     napi_value jsThis = nullptr;
504     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
505     if (status != napi_ok || jsThis == nullptr) {
506         MEDIA_LOGE("Failed to retrieve details about the callback");
507         return undefinedResult;
508     }
509 
510     AudioPlayerNapi *player = nullptr;
511     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
512     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
513 
514     if (player->nativePlayer_ == nullptr) {
515         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
516         return undefinedResult;
517     }
518 
519     (void)player->nativePlayer_->Release();
520     player->CancelCallback();
521     player->callbackNapi_ = nullptr;
522     player->nativePlayer_ = nullptr;
523     player->uri_.clear();
524     MEDIA_LOGD("Release success");
525     return undefinedResult;
526 }
527 
Seek(napi_env env,napi_callback_info info)528 napi_value AudioPlayerNapi::Seek(napi_env env, napi_callback_info info)
529 {
530     napi_value undefinedResult = nullptr;
531     napi_get_undefined(env, &undefinedResult);
532 
533     size_t argCount = 1;
534     napi_value args[1] = { nullptr };
535     napi_value jsThis = nullptr;
536 
537     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
538     if (status != napi_ok || jsThis == nullptr || argCount < 1) {
539         MEDIA_LOGE("Failed to retrieve details about the callback");
540         return undefinedResult;
541     }
542 
543     AudioPlayerNapi *player = nullptr;
544     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
545     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
546     if (player->nativePlayer_ == nullptr) {
547         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
548         return undefinedResult;
549     }
550 
551     napi_valuetype valueType = napi_undefined;
552     if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
553         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
554         return undefinedResult;
555     }
556 
557     int32_t position = -1;
558     status = napi_get_value_int32(env, args[0], &position);
559     if (status != napi_ok || position < 0) {
560         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
561         return undefinedResult;
562     }
563 
564     int32_t ret = player->nativePlayer_->Seek(position, SEEK_PREVIOUS_SYNC);
565     if (ret != MSERR_OK) {
566         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Seek");
567         return undefinedResult;
568     }
569 
570     MEDIA_LOGD("Seek success");
571     return undefinedResult;
572 }
573 
SetVolume(napi_env env,napi_callback_info info)574 napi_value AudioPlayerNapi::SetVolume(napi_env env, napi_callback_info info)
575 {
576     napi_value undefinedResult = nullptr;
577     napi_get_undefined(env, &undefinedResult);
578 
579     size_t argCount = 1;
580     napi_value args[1] = { nullptr };
581     napi_value jsThis = nullptr;
582 
583     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
584     if (status != napi_ok || jsThis == nullptr || argCount < 1) {
585         MEDIA_LOGE("Failed to retrieve details about the callback");
586         return undefinedResult;
587     }
588 
589     AudioPlayerNapi *player = nullptr;
590     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
591     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
592 
593     if (player->nativePlayer_ == nullptr) {
594         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
595         return undefinedResult;
596     }
597 
598     napi_valuetype valueType = napi_undefined;
599     if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
600         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
601         return undefinedResult;
602     }
603 
604     double volumeLevel;
605     status = napi_get_value_double(env, args[0], &volumeLevel);
606     if (status != napi_ok || volumeLevel < 0.0f || volumeLevel > 1.0f) {
607         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
608         return undefinedResult;
609     }
610 #ifdef SUPPORT_JSSTACK
611     HiviewDFX::ReportXPowerJsStackSysEvent(env, "VOLUME_CHANGE", "SRC=Media");
612 #endif
613     int32_t ret = player->nativePlayer_->SetVolume(static_cast<float>(volumeLevel), static_cast<float>(volumeLevel));
614     if (ret != MSERR_OK) {
615         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetVolume");
616         return undefinedResult;
617     }
618     MEDIA_LOGD("SetVolume success");
619     return undefinedResult;
620 }
621 
On(napi_env env,napi_callback_info info)622 napi_value AudioPlayerNapi::On(napi_env env, napi_callback_info info)
623 {
624     napi_value undefinedResult = nullptr;
625     napi_get_undefined(env, &undefinedResult);
626 
627     static constexpr size_t minArgCount = 2;
628     size_t argCount = minArgCount;
629     napi_value args[minArgCount] = { nullptr, nullptr };
630     napi_value jsThis = nullptr;
631     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
632     if (status != napi_ok || jsThis == nullptr || argCount < minArgCount) {
633         MEDIA_LOGE("Failed to retrieve details about the callback");
634         return undefinedResult;
635     }
636 
637     AudioPlayerNapi *player = nullptr;
638     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
639     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
640 
641     napi_valuetype valueType0 = napi_undefined;
642     napi_valuetype valueType1 = napi_undefined;
643     if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string ||
644         napi_typeof(env, args[1], &valueType1) != napi_ok || valueType1 != napi_function) {
645         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
646         return undefinedResult;
647     }
648 
649     std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
650     MEDIA_LOGD("callbackName: %{public}s", callbackName.c_str());
651 
652     napi_ref ref = nullptr;
653     status = napi_create_reference(env, args[1], 1, &ref);
654     CHECK_AND_RETURN_RET_LOG(status == napi_ok && ref != nullptr, undefinedResult, "failed to create reference!");
655 
656     std::shared_ptr<AutoRef> autoRef = std::make_shared<AutoRef>(env, ref);
657     player->SetCallbackReference(callbackName, autoRef);
658     return undefinedResult;
659 }
660 
SetLoop(napi_env env,napi_callback_info info)661 napi_value AudioPlayerNapi::SetLoop(napi_env env, napi_callback_info info)
662 {
663     size_t argCount = 1;
664     napi_value args[1] = { nullptr };
665     napi_value jsThis = nullptr;
666     napi_value undefinedResult = nullptr;
667     napi_get_undefined(env, &undefinedResult);
668 
669     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
670     if (status != napi_ok || jsThis == nullptr || argCount < 1) {
671         MEDIA_LOGE("Failed to retrieve details about the callback");
672         return undefinedResult;
673     }
674 
675     AudioPlayerNapi *player = nullptr;
676     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
677     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
678 
679     if (player->nativePlayer_ == nullptr) {
680         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
681         return undefinedResult;
682     }
683 
684     napi_valuetype valueType = napi_undefined;
685     if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_boolean) {
686         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
687         return undefinedResult;
688     }
689 
690     bool loopFlag = false;
691     status = napi_get_value_bool(env, args[0], &loopFlag);
692     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_value_bool error");
693 
694     int32_t ret = player->nativePlayer_->SetLooping(loopFlag);
695     if (ret != MSERR_OK) {
696         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetLooping");
697         return undefinedResult;
698     }
699 
700     MEDIA_LOGD("SetLoop success");
701     return undefinedResult;
702 }
703 
704 
GetLoop(napi_env env,napi_callback_info info)705 napi_value AudioPlayerNapi::GetLoop(napi_env env, napi_callback_info info)
706 {
707     napi_value jsThis = nullptr;
708     napi_value jsResult = nullptr;
709     napi_value undefinedResult = nullptr;
710     napi_get_undefined(env, &undefinedResult);
711 
712     size_t argCount = 0;
713     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
714     if (status != napi_ok || jsThis == nullptr) {
715         MEDIA_LOGE("Failed to retrieve details about the callback");
716         return undefinedResult;
717     }
718 
719     AudioPlayerNapi *player = nullptr;
720     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
721     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
722 
723     if (player->nativePlayer_ == nullptr) {
724         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
725         return undefinedResult;
726     }
727     bool loopFlag = player->nativePlayer_->IsLooping();
728 
729     status = napi_get_boolean(env, loopFlag, &jsResult);
730     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_boolean error");
731 
732     MEDIA_LOGD("GetSrc success loop Status: %{public}d", loopFlag);
733     return jsResult;
734 }
735 
GetCurrentTime(napi_env env,napi_callback_info info)736 napi_value AudioPlayerNapi::GetCurrentTime(napi_env env, napi_callback_info info)
737 {
738     napi_value jsThis = nullptr;
739     napi_value undefinedResult = nullptr;
740     napi_get_undefined(env, &undefinedResult);
741 
742     size_t argCount = 0;
743     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
744     if (status != napi_ok || jsThis == nullptr) {
745         MEDIA_LOGE("Failed to retrieve details about the callback");
746         return undefinedResult;
747     }
748 
749     AudioPlayerNapi *player = nullptr;
750     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
751     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
752 
753     if (player->nativePlayer_ == nullptr) {
754         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
755         return undefinedResult;
756     }
757     int32_t currentTime = -1;
758     (void)player->nativePlayer_->GetCurrentTime(currentTime);
759 
760     napi_value jsResult = nullptr;
761     status = napi_create_int32(env, currentTime, &jsResult);
762     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_int32 error");
763 
764     MEDIA_LOGD("GetCurrenTime success, Current time: %{public}d", currentTime);
765     return jsResult;
766 }
767 
GetDuration(napi_env env,napi_callback_info info)768 napi_value AudioPlayerNapi::GetDuration(napi_env env, napi_callback_info info)
769 {
770     napi_value jsThis = nullptr;
771     napi_value jsResult = nullptr;
772     napi_value undefinedResult = nullptr;
773     napi_get_undefined(env, &undefinedResult);
774 
775     size_t argCount = 0;
776     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
777     if (status != napi_ok || jsThis == nullptr) {
778         MEDIA_LOGE("Failed to retrieve details about the callback");
779         return undefinedResult;
780     }
781 
782     AudioPlayerNapi *player = nullptr;
783     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
784     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
785 
786     if (player->nativePlayer_ == nullptr) {
787         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
788         return undefinedResult;
789     }
790     int32_t duration = -1;
791     (void)player->nativePlayer_->GetDuration(duration);
792 
793     status = napi_create_int32(env, duration, &jsResult);
794     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_int64 error");
795 
796     MEDIA_LOGD("GetDuration success, Current time: %{public}d", duration);
797     return jsResult;
798 }
799 
GetJSState(PlayerStates currentState)800 static std::string GetJSState(PlayerStates currentState)
801 {
802     std::string result;
803 
804     MEDIA_LOGD("GetJSState()! is called!, %{public}d", currentState);
805     switch (currentState) {
806         case PLAYER_IDLE:
807         case PLAYER_INITIALIZED:
808         case PLAYER_PREPARING:
809         case PLAYER_PREPARED:
810             result = STATE_IDLE;
811             break;
812         case PLAYER_STARTED:
813             result = STATE_PLAYING;
814             break;
815         case PLAYER_PAUSED:
816             result = STATE_PAUSED;
817             break;
818         case PLAYER_STOPPED:
819         case PLAYER_PLAYBACK_COMPLETE:
820             result = STATE_STOPPED;
821             break;
822         default:
823             // Considering default state as stopped
824             MEDIA_LOGE("Error state! %{public}d", currentState);
825             result = STATE_ERROR;
826             break;
827     }
828     return result;
829 }
830 
GetState(napi_env env,napi_callback_info info)831 napi_value AudioPlayerNapi::GetState(napi_env env, napi_callback_info info)
832 {
833     napi_value jsThis = nullptr;
834     napi_value jsResult = nullptr;
835     napi_value undefinedResult = nullptr;
836     std::string curState;
837     napi_get_undefined(env, &undefinedResult);
838 
839     size_t argCount = 0;
840     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
841     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "Failed to retrieve details about the callback");
842 
843     AudioPlayerNapi *player = nullptr;
844     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
845     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "Failed to retrieve instance");
846 
847     if (player->callbackNapi_ == nullptr) {
848         return undefinedResult;
849     } else {
850         std::shared_ptr<PlayerCallbackNapi> cb = std::static_pointer_cast<PlayerCallbackNapi>(player->callbackNapi_);
851         curState = GetJSState(cb->GetCurrentState());
852         MEDIA_LOGD("GetState success, State: %{public}s", curState.c_str());
853     }
854     status = napi_create_string_utf8(env, curState.c_str(), NAPI_AUTO_LENGTH, &jsResult);
855     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_string_utf8 error");
856     return jsResult;
857 }
858 
ErrorCallback(MediaServiceExtErrCode errCode,std::string errMsg)859 void AudioPlayerNapi::ErrorCallback(MediaServiceExtErrCode errCode, std::string errMsg)
860 {
861     if (callbackNapi_ != nullptr) {
862         std::shared_ptr<PlayerCallbackNapi> napiCb = std::static_pointer_cast<PlayerCallbackNapi>(callbackNapi_);
863         napiCb->SendErrorCallback(errCode, errMsg);
864     }
865 }
866 
AsyncGetTrackDescription(napi_env env,void * data)867 void AudioPlayerNapi::AsyncGetTrackDescription(napi_env env, void *data)
868 {
869     auto asyncContext = reinterpret_cast<AudioPlayerAsyncContext *>(data);
870     CHECK_AND_RETURN_LOG(asyncContext != nullptr, "AudioPlayerAsyncContext is nullptr!");
871 
872     if (asyncContext->jsPlayer == nullptr) {
873         asyncContext->SignError(MSERR_EXT_NO_MEMORY, "jsPlayer is destroyed(null), please check js_runtime");
874         return;
875     }
876 
877     if (asyncContext->jsPlayer->nativePlayer_ == nullptr) {
878         asyncContext->SignError(MSERR_EXT_NO_MEMORY, "nativePlayer is released(null), please create player again");
879         return;
880     }
881 
882     auto player = asyncContext->jsPlayer->nativePlayer_;
883     std::vector<Format> &audioInfo = asyncContext->jsPlayer->audioTrackInfoVec_;
884     audioInfo.clear();
885     int32_t ret = player->GetAudioTrackInfo(audioInfo);
886     if (ret != MSERR_OK) {
887         asyncContext->SignError(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)),
888             "failed to GetAudioTrackInfo");
889         return;
890     }
891 
892     if (audioInfo.empty()) {
893         asyncContext->SignError(MSERR_EXT_OPERATE_NOT_PERMIT, "audio track info is empty");
894         return;
895     }
896 
897     asyncContext->JsResult = std::make_unique<MediaJsResultArray>(audioInfo);
898     MEDIA_LOGD("AsyncGetTrackDescription Out");
899 }
900 
GetTrackDescription(napi_env env,napi_callback_info info)901 napi_value AudioPlayerNapi::GetTrackDescription(napi_env env, napi_callback_info info)
902 {
903     napi_value result = nullptr;
904     napi_get_undefined(env, &result);
905 
906     MEDIA_LOGD("GetTrackDescription In");
907     std::unique_ptr<AudioPlayerAsyncContext> asyncContext = std::make_unique<AudioPlayerAsyncContext>(env);
908 
909     // get args
910     napi_value jsThis = nullptr;
911     napi_value args[1] = { nullptr };
912     size_t argCount = 1;
913     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
914     if (status != napi_ok || jsThis == nullptr) {
915         asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
916     }
917 
918     asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
919     asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
920     // get jsPlayer
921     (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
922     // async work
923     napi_value resource = nullptr;
924     napi_create_string_utf8(env, "GetTrackDescription", NAPI_AUTO_LENGTH, &resource);
925     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, AudioPlayerNapi::AsyncGetTrackDescription,
926         MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncContext.get()), &asyncContext->work));
927     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
928     asyncContext.release();
929     return result;
930 }
931 
SetAudioInterruptMode(napi_env env,napi_callback_info info)932 napi_value AudioPlayerNapi::SetAudioInterruptMode(napi_env env, napi_callback_info info)
933 {
934     size_t argCount = 1;
935     napi_value args[1] = { nullptr };
936     napi_value jsThis = nullptr;
937     napi_value undefinedResult = nullptr;
938     napi_get_undefined(env, &undefinedResult);
939 
940     MEDIA_LOGD("SetAudioInterruptMode In");
941     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
942     if (status != napi_ok || jsThis == nullptr || argCount < 1) {
943         MEDIA_LOGE("Failed to retrieve details about the callback");
944         return undefinedResult;
945     }
946 
947     AudioPlayerNapi *player = nullptr;
948     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
949     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
950 
951     if (player->nativePlayer_ == nullptr) {
952         player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
953         return undefinedResult;
954     }
955 
956     napi_valuetype valueType = napi_undefined;
957     if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
958         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
959         return undefinedResult;
960     }
961 
962     int32_t interruptMode = 0;
963     status = napi_get_value_int32(env, args[0], &interruptMode);
964     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_value_int32 error");
965 
966     if (interruptMode < AudioStandard::InterruptMode::SHARE_MODE ||
967         interruptMode > AudioStandard::InterruptMode::INDEPENDENT_MODE) {
968         player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
969         return undefinedResult;
970     }
971 
972     player->interruptMode_ = AudioStandard::InterruptMode(interruptMode);
973     Format format;
974     (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_MODE, interruptMode);
975     int32_t ret = player->nativePlayer_->SetParameter(format);
976     if (ret != MSERR_OK) {
977         player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetParameter");
978         return undefinedResult;
979     }
980 
981     MEDIA_LOGD("SetAudioInterruptMode success");
982     return undefinedResult;
983 }
984 
GetAudioInterruptMode(napi_env env,napi_callback_info info)985 napi_value AudioPlayerNapi::GetAudioInterruptMode(napi_env env, napi_callback_info info)
986 {
987     napi_value jsThis = nullptr;
988     napi_value jsResult = nullptr;
989     napi_value undefinedResult = nullptr;
990     napi_get_undefined(env, &undefinedResult);
991 
992     size_t argCount = 0;
993     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
994     if (status != napi_ok || jsThis == nullptr) {
995         MEDIA_LOGE("Failed to retrieve details about the callback");
996         return undefinedResult;
997     }
998 
999     AudioPlayerNapi *player = nullptr;
1000     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
1001     CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
1002 
1003     status = napi_create_object(env, &jsResult);
1004     CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "create jsresult object error");
1005 
1006     CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt32(env, jsResult, "InterruptMode",
1007         player->interruptMode_) == true, nullptr);
1008     MEDIA_LOGD("GetAudioInterruptMode success");
1009     return jsResult;
1010 }
1011 
SetCallbackReference(const std::string & callbackName,std::shared_ptr<AutoRef> ref)1012 void AudioPlayerNapi::SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref)
1013 {
1014     refMap_[callbackName] = ref;
1015     if (callbackNapi_ != nullptr) {
1016         std::shared_ptr<PlayerCallbackNapi> napiCb = std::static_pointer_cast<PlayerCallbackNapi>(callbackNapi_);
1017         napiCb->SaveCallbackReference(callbackName, ref);
1018     }
1019 }
1020 
CancelCallback()1021 void AudioPlayerNapi::CancelCallback()
1022 {
1023     if (callbackNapi_ != nullptr) {
1024         std::shared_ptr<PlayerCallbackNapi> napiCb = std::static_pointer_cast<PlayerCallbackNapi>(callbackNapi_);
1025         napiCb->ClearCallbackReference();
1026     }
1027 }
1028 } // namespace Media
1029 } // namespace OHOS
1030