• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_avsession.h"
17 #include "avsession_controller.h"
18 #include "napi_async_work.h"
19 #include "napi_utils.h"
20 #include "napi_meta_data.h"
21 #include "napi_playback_state.h"
22 #include "want_agent.h"
23 #include "avsession_trace.h"
24 #include "napi_avsession_controller.h"
25 #include "napi_avsession_manager.h"
26 
27 namespace OHOS::AVSession {
28 static __thread napi_ref AVSessionConstructorRef = nullptr;
29 std::map<std::string, NapiAVSession::OnEventHandlerType> NapiAVSession::onEventHandlers_ = {
30     { "play", OnPlay },
31     { "pause", OnPause },
32     { "stop", OnStop },
33     { "playNext", OnPlayNext },
34     { "playPrevious", OnPlayPrevious },
35     { "fastForward", OnFastForward },
36     { "rewind", OnRewind },
37     { "seek", OnSeek },
38     { "setSpeed", OnSetSpeed },
39     { "setLoopMode", OnSetLoopMode },
40     { "toggleFavorite", OnToggleFavorite },
41     { "handleKeyEvent", OnMediaKeyEvent },
42     { "outputDeviceChange", OnOutputDeviceChange },
43 };
44 std::map<std::string, NapiAVSession::OffEventHandlerType> NapiAVSession::offEventHandlers_ = {
45     { "play", OffPlay },
46     { "pause", OffPause },
47     { "stop", OffStop },
48     { "playNext", OffPlayNext },
49     { "playPrevious", OffPlayPrevious },
50     { "fastForward", OffFastForward },
51     { "rewind", OffRewind },
52     { "seek", OffSeek },
53     { "setSpeed", OffSetSpeed },
54     { "setLoopMode", OffSetLoopMode },
55     { "toggleFavorite", OffToggleFavorite },
56     { "handleKeyEvent", OffMediaKeyEvent },
57     { "outputDeviceChange", OffOutputDeviceChange }
58 };
59 
NapiAVSession()60 NapiAVSession::NapiAVSession()
61 {
62     SLOGI("construct");
63 }
64 
~NapiAVSession()65 NapiAVSession::~NapiAVSession()
66 {
67     SLOGI("destroy");
68 }
69 
Init(napi_env env,napi_value exports)70 napi_value NapiAVSession::Init(napi_env env, napi_value exports)
71 {
72     napi_property_descriptor descriptors[] = {
73         DECLARE_NAPI_FUNCTION("setAVMetadata", SetAVMetaData),
74         DECLARE_NAPI_FUNCTION("setAVPlaybackState", SetAVPlaybackState),
75         DECLARE_NAPI_FUNCTION("setLaunchAbility", SetLaunchAbility),
76         DECLARE_NAPI_FUNCTION("setAudioStreamId", SetAudioStreamId),
77         DECLARE_NAPI_FUNCTION("getController", GetController),
78         DECLARE_NAPI_FUNCTION("activate", Activate),
79         DECLARE_NAPI_FUNCTION("deactivate", Deactivate),
80         DECLARE_NAPI_FUNCTION("destroy", Destroy),
81         DECLARE_NAPI_FUNCTION("on", OnEvent),
82         DECLARE_NAPI_FUNCTION("off", OffEvent),
83         DECLARE_NAPI_FUNCTION("getOutputDevice", GetOutputDevice)
84     };
85     auto propertyCount = sizeof(descriptors) / sizeof(napi_property_descriptor);
86     napi_value constructor{};
87     auto status = napi_define_class(env, "AVSession", NAPI_AUTO_LENGTH, ConstructorCallback, nullptr,
88                                     propertyCount, descriptors, &constructor);
89     if (status != napi_ok) {
90         SLOGE("define class failed");
91         return NapiUtils::GetUndefinedValue(env);
92     }
93     napi_create_reference(env, constructor, 1, &AVSessionConstructorRef);
94     return exports;
95 }
96 
ConstructorCallback(napi_env env,napi_callback_info info)97 napi_value NapiAVSession::ConstructorCallback(napi_env env, napi_callback_info info)
98 {
99     napi_value self;
100     NAPI_CALL_BASE(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr), nullptr);
101     auto finalize = [](napi_env env, void* data, void* hint) {
102         auto* napiSession = reinterpret_cast<NapiAVSession*>(data);
103         napi_delete_reference(env, napiSession->wrapperRef_);
104         delete napiSession;
105     };
106     auto* napiSession = new(std::nothrow) NapiAVSession();
107     if (napiSession == nullptr) {
108         SLOGE("no memory");
109         return nullptr;
110     }
111     if (napi_wrap(env, self, static_cast<void*>(napiSession), finalize, nullptr,
112                   &(napiSession->wrapperRef_)) != napi_ok) {
113         SLOGE("wrap failed");
114         return nullptr;
115     }
116     return self;
117 }
118 
NewInstance(napi_env env,std::shared_ptr<AVSession> & nativeSession,napi_value & out)119 napi_status NapiAVSession::NewInstance(napi_env env, std::shared_ptr<AVSession>& nativeSession, napi_value& out)
120 {
121     napi_value constructor{};
122     NAPI_CALL_BASE(env, napi_get_reference_value(env, AVSessionConstructorRef, &constructor), napi_generic_failure);
123     napi_value instance{};
124     NAPI_CALL_BASE(env, napi_new_instance(env, constructor, 0, nullptr, &instance), napi_generic_failure);
125     NapiAVSession* napiAvSession{};
126     NAPI_CALL_BASE(env, napi_unwrap(env, instance, reinterpret_cast<void**>(&napiAvSession)), napi_generic_failure);
127     napiAvSession->session_ = std::move(nativeSession);
128     napiAvSession->sessionId_ = napiAvSession->session_->GetSessionId();
129     SLOGI("sessionId=%{public}s", napiAvSession->sessionId_.c_str());
130 
131     napi_value property {};
132     auto status = NapiUtils::SetValue(env, napiAvSession->sessionId_, property);
133     CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
134     NAPI_CALL_BASE(env, napi_set_named_property(env, instance, "sessionId", property), napi_generic_failure);
135     out = instance;
136     return napi_ok;
137 }
138 
OnEvent(napi_env env,napi_callback_info info)139 napi_value NapiAVSession::OnEvent(napi_env env, napi_callback_info info)
140 {
141     auto context = std::make_shared<ContextBase>();
142     if (context == nullptr) {
143         SLOGE("OnEvent failed : no memory");
144         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
145         return NapiUtils::GetUndefinedValue(env);
146     }
147     std::string eventName;
148     napi_value callback {};
149     auto input = [&eventName, &callback, env, &context](size_t argc, napi_value* argv) {
150         /* require 2 arguments <event, callback> */
151         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid argument number",
152             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
153         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
154         CHECK_STATUS_RETURN_VOID(context, "get event name failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
155         napi_valuetype type = napi_undefined;
156         context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
157         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
158                                "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
159         callback = argv[ARGV_SECOND];
160     };
161     context->GetCbInfo(env, info, input, true);
162     if (context->status != napi_ok) {
163         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
164         return NapiUtils::GetUndefinedValue(env);
165     }
166     auto it = onEventHandlers_.find(eventName);
167     if (it == onEventHandlers_.end()) {
168         SLOGE("event name invalid");
169         NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
170         return NapiUtils::GetUndefinedValue(env);
171     }
172     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
173     if (napiSession->session_ == nullptr) {
174         SLOGE("OnEvent failed : session is nullptr");
175         NapiUtils::ThrowError(env, "OnEvent failed : session is nullptr",
176             NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST]);
177         return NapiUtils::GetUndefinedValue(env);
178     }
179     if (napiSession->callback_ == nullptr) {
180         napiSession->callback_ = std::make_shared<NapiAVSessionCallback>();
181         if (napiSession->callback_ == nullptr) {
182             SLOGE("OnEvent failed : no memory");
183             NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
184             return NapiUtils::GetUndefinedValue(env);
185         }
186         int32_t ret = napiSession->session_->RegisterCallback(napiSession->callback_);
187         if (ret != AVSESSION_SUCCESS) {
188             if (ret == ERR_SESSION_NOT_EXIST) {
189                 NapiUtils::ThrowError(env, "OnEvent failed : native session not exist",
190                     NapiAVSessionManager::errcode_[ret]);
191             } else if (ret == ERR_INVALID_PARAM) {
192                 NapiUtils::ThrowError(env, "OnEvent failed : native invalid parameters",
193                     NapiAVSessionManager::errcode_[ret]);
194             } else {
195                 NapiUtils::ThrowError(env, "OnEvent failed : native server exception",
196                     NapiAVSessionManager::errcode_[ret]);
197             }
198             return NapiUtils::GetUndefinedValue(env);
199         }
200     }
201     if (it->second(env, napiSession, callback) != napi_ok) {
202         NapiUtils::ThrowError(env, "add event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
203     }
204     return NapiUtils::GetUndefinedValue(env);
205 }
206 
OffEvent(napi_env env,napi_callback_info info)207 napi_value NapiAVSession::OffEvent(napi_env env, napi_callback_info info)
208 {
209     auto context = std::make_shared<ContextBase>();
210     if (context == nullptr) {
211         SLOGE("OffEvent failed : no memory");
212         NapiUtils::ThrowError(env, "OffEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
213         return NapiUtils::GetUndefinedValue(env);
214     }
215     std::string eventName;
216     napi_value callback = nullptr;
217     auto input = [&eventName, env, &context, &callback](size_t argc, napi_value* argv) {
218         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE || argc == ARGC_TWO,
219                                "invalid argument number", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
220         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
221         CHECK_STATUS_RETURN_VOID(context, "get event name failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
222         if (argc == ARGC_TWO) {
223             callback = argv[ARGV_SECOND];
224         }
225     };
226     context->GetCbInfo(env, info, input, true);
227     if (context->status != napi_ok) {
228         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
229         return NapiUtils::GetUndefinedValue(env);
230     }
231     auto it = offEventHandlers_.find(eventName);
232     if (it == offEventHandlers_.end()) {
233         SLOGE("event name invalid");
234         NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
235         return NapiUtils::GetUndefinedValue(env);
236     }
237     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
238     if (napiSession->session_ == nullptr) {
239         SLOGE("OffEvent failed : session is nullptr");
240         NapiUtils::ThrowError(env, "OffEvent failed : session is nullptr",
241             NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST]);
242         return NapiUtils::GetUndefinedValue(env);
243     }
244     if (napiSession != nullptr && it->second(env, napiSession, callback) != napi_ok) {
245         NapiUtils::ThrowError(env, "remove event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
246     }
247     return NapiUtils::GetUndefinedValue(env);
248 }
249 
SetAVMetaData(napi_env env,napi_callback_info info)250 napi_value NapiAVSession::SetAVMetaData(napi_env env, napi_callback_info info)
251 {
252     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVMetadata");
253     struct ConcreteContext : public ContextBase {
254         AVMetaData metaData_;
255     };
256     auto context = std::make_shared<ConcreteContext>();
257     if (context == nullptr) {
258         SLOGE("SetAVMetaData failed : no memory");
259         NapiUtils::ThrowError(env, "SetAVMetaData failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
260         return NapiUtils::GetUndefinedValue(env);
261     }
262 
263     auto inputParser = [env, context](size_t argc, napi_value* argv) {
264         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
265             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
266         context->status = NapiMetaData::GetValue(env, argv[ARGV_FIRST], context->metaData_);
267         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get metaData failed",
268             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
269     };
270     context->GetCbInfo(env, info, inputParser);
271     context->taskId = NAPI_SET_AV_META_DATA_TASK_ID;
272 
273     auto executor = [context]() {
274         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
275         if (napiSession->session_ == nullptr) {
276             context->status = napi_generic_failure;
277             context->errMessage = "SetAVMetaData failed : session is nullptr";
278             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
279             return;
280         }
281         int32_t ret = napiSession->session_->SetAVMetaData(context->metaData_);
282         if (ret != AVSESSION_SUCCESS) {
283             if (ret == ERR_SESSION_NOT_EXIST) {
284                 context->errMessage = "SetAVMetaData failed : native session not exist";
285             } else if (ret == ERR_INVALID_PARAM) {
286                 context->errMessage = "SetAVMetaData failed : native invalid parameters";
287             } else {
288                 context->errMessage = "SetAVMetaData failed : native server exception";
289             }
290             context->status = napi_generic_failure;
291             context->errCode = NapiAVSessionManager::errcode_[ret];
292         }
293     };
294     auto complete = [env](napi_value& output) {
295         output = NapiUtils::GetUndefinedValue(env);
296     };
297     return NapiAsyncWork::Enqueue(env, context, "SetAVMetaData", executor, complete);
298 }
299 
SetAVPlaybackState(napi_env env,napi_callback_info info)300 napi_value NapiAVSession::SetAVPlaybackState(napi_env env, napi_callback_info info)
301 {
302     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVPlaybackState");
303     struct ConcreteContext : public ContextBase {
304         AVPlaybackState playBackState_;
305     };
306     auto context = std::make_shared<ConcreteContext>();
307     if (context == nullptr) {
308         SLOGE("SetAVPlaybackState failed : no memory");
309         NapiUtils::ThrowError(env, "SetAVPlaybackState failed : no memory",
310                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
311         return NapiUtils::GetUndefinedValue(env);
312     }
313 
314     auto inputParser = [env, context](size_t argc, napi_value* argv) {
315         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
316             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
317         context->status = NapiPlaybackState::GetValue(env, argv[ARGV_FIRST], context->playBackState_);
318         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get playBackState failed",
319             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
320     };
321     context->GetCbInfo(env, info, inputParser);
322     context->taskId = NAPI_SET_AV_PLAYBACK_STATE_TASK_ID;
323 
324     auto executor = [context]() {
325         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
326         if (napiSession->session_ == nullptr) {
327             context->status = napi_generic_failure;
328             context->errMessage = "SetAVPlaybackState failed : session is nullptr";
329             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
330             return;
331         }
332         int32_t ret = napiSession->session_->SetAVPlaybackState(context->playBackState_);
333         if (ret != AVSESSION_SUCCESS) {
334             if (ret == ERR_SESSION_NOT_EXIST) {
335                 context->errMessage = "SetAVPlaybackState failed : native session not exist";
336             } else if (ret == ERR_INVALID_PARAM) {
337                 context->errMessage = "SetAVPlaybackState failed : native invalid parameters";
338             } else {
339                 context->errMessage = "SetAVPlaybackState failed : native server exception";
340             }
341             context->status = napi_generic_failure;
342             context->errCode = NapiAVSessionManager::errcode_[ret];
343         }
344     };
345     auto complete = [env](napi_value& output) {
346         output = NapiUtils::GetUndefinedValue(env);
347     };
348     return NapiAsyncWork::Enqueue(env, context, "SetAVPlaybackState", executor, complete);
349 }
350 
SetLaunchAbility(napi_env env,napi_callback_info info)351 napi_value NapiAVSession::SetLaunchAbility(napi_env env, napi_callback_info info)
352 {
353     struct ConcreteContext : public ContextBase {
354         AbilityRuntime::WantAgent::WantAgent* wantAgent_;
355     };
356     auto context = std::make_shared<ConcreteContext>();
357     if (context == nullptr) {
358         SLOGE("SetLaunchAbility failed : no memory");
359         NapiUtils::ThrowError(env, "SetLaunchAbility failed : no memory",
360                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
361         return NapiUtils::GetUndefinedValue(env);
362     }
363 
364     auto inputParser = [env, context](size_t argc, napi_value* argv) {
365         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
366             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
367         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->wantAgent_);
368         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get  wantAgent failed",
369             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
370     };
371     context->GetCbInfo(env, info, inputParser);
372 
373     auto executor = [context]() {
374         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
375         if (napiSession->session_ == nullptr) {
376             context->status = napi_generic_failure;
377             context->errMessage = "SetLaunchAbility failed : session is nullptr";
378             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
379             return;
380         }
381         int32_t ret = napiSession->session_->SetLaunchAbility(*context->wantAgent_);
382         if (ret != AVSESSION_SUCCESS) {
383             if (ret == ERR_SESSION_NOT_EXIST) {
384                 context->errMessage = "SetLaunchAbility failed : native session not exist";
385             } else {
386                 context->errMessage = "SetLaunchAbility failed : native server exception";
387             }
388             context->status = napi_generic_failure;
389             context->errCode = NapiAVSessionManager::errcode_[ret];
390         }
391     };
392     auto complete = [env](napi_value& output) {
393         output = NapiUtils::GetUndefinedValue(env);
394     };
395     return NapiAsyncWork::Enqueue(env, context, "SetLaunchAbility", executor, complete);
396 }
397 
SetAudioStreamId(napi_env env,napi_callback_info info)398 napi_value NapiAVSession::SetAudioStreamId(napi_env env, napi_callback_info info)
399 {
400     struct ConcreteContext : public ContextBase {
401         std::vector<int32_t> streamIds_;
402     };
403     auto context = std::make_shared<ConcreteContext>();
404     if (context == nullptr) {
405         SLOGE("SetAudioStreamId failed : no memory");
406         NapiUtils::ThrowError(env, "SetAudioStreamId failed : no memory",
407                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
408         return NapiUtils::GetUndefinedValue(env);
409     }
410 
411     auto inputParser = [env, context](size_t argc, napi_value* argv) {
412         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
413             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
414         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->streamIds_);
415         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get streamIds_ failed",
416             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
417     };
418     context->GetCbInfo(env, info, inputParser);
419 
420     auto executor = [context]() {
421         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
422         if (napiSession->session_ == nullptr) {
423             context->status = napi_generic_failure;
424             context->errMessage = "SetAudioStreamId failed : session is nullptr";
425             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
426             return;
427         }
428     };
429     auto complete = [env](napi_value& output) {
430         output = NapiUtils::GetUndefinedValue(env);
431     };
432     return NapiAsyncWork::Enqueue(env, context, "SetAudioStreamId", executor, complete);
433 }
434 
GetController(napi_env env,napi_callback_info info)435 napi_value NapiAVSession::GetController(napi_env env, napi_callback_info info)
436 {
437     struct ConcreteContext : public ContextBase {
438         std::shared_ptr<AVSessionController> controller_;
439     };
440     auto context = std::make_shared<ConcreteContext>();
441     if (context == nullptr) {
442         SLOGE("GetController failed : no memory");
443         NapiUtils::ThrowError(env, "GetController failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
444         return NapiUtils::GetUndefinedValue(env);
445     }
446 
447     context->GetCbInfo(env, info);
448 
449     auto executor = [context]() {
450         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
451         if (napiSession->session_ == nullptr) {
452             context->status = napi_generic_failure;
453             context->errMessage = "GetController failed : session is nullptr";
454             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
455             return;
456         }
457         context->controller_ = napiSession->session_->GetController();
458         if (context->controller_ == nullptr) {
459             context->status = napi_generic_failure;
460             context->errMessage = "GetController failed : native get controller failed";
461             context->errCode = NapiAVSessionManager::errcode_[AVSESSION_ERROR];
462         }
463     };
464     auto complete = [env, context](napi_value& output) {
465         CHECK_STATUS_RETURN_VOID(context, "get controller failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
466         CHECK_ARGS_RETURN_VOID(context, context->controller_ != nullptr, "controller is nullptr",
467             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
468         context->status = NapiAVSessionController::NewInstance(env, context->controller_, output);
469         CHECK_STATUS_RETURN_VOID(context, "convert native object to js object failed",
470             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
471     };
472     return NapiAsyncWork::Enqueue(env, context, "GetController", executor, complete);
473 }
474 
GetOutputDevice(napi_env env,napi_callback_info info)475 napi_value NapiAVSession::GetOutputDevice(napi_env env, napi_callback_info info)
476 {
477     struct ConcreteContext : public ContextBase {
478         OutputDeviceInfo outputDeviceInfo_;
479     };
480     auto context = std::make_shared<ConcreteContext>();
481     if (context == nullptr) {
482         SLOGE("GetOutputDevice failed : no memory");
483         NapiUtils::ThrowError(env, "GetOutputDevice failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
484         return NapiUtils::GetUndefinedValue(env);
485     }
486 
487     context->GetCbInfo(env, info);
488 
489     auto executor = [context]() {
490         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
491         if (napiSession->session_ == nullptr) {
492             context->status = napi_generic_failure;
493             context->errMessage = "GetOutputDevice failed : session is nullptr";
494             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
495             return;
496         }
497         AVSessionDescriptor descriptor;
498         AVSessionManager::GetInstance().GetSessionDescriptorsBySessionId(napiSession->session_->GetSessionId(),
499                                                                          descriptor);
500         context->outputDeviceInfo_ = descriptor.outputDeviceInfo_;
501     };
502 
503     auto complete = [env, context](napi_value& output) {
504         context->status = NapiUtils::SetValue(env, context->outputDeviceInfo_, output);
505         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
506             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
507     };
508     return NapiAsyncWork::Enqueue(env, context, "GetOutputDevice", executor, complete);
509 }
510 
Activate(napi_env env,napi_callback_info info)511 napi_value NapiAVSession::Activate(napi_env env, napi_callback_info info)
512 {
513     auto context = std::make_shared<ContextBase>();
514     if (context == nullptr) {
515         SLOGE("Activate failed : no memory");
516         NapiUtils::ThrowError(env, "Activate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
517         return NapiUtils::GetUndefinedValue(env);
518     }
519 
520     context->GetCbInfo(env, info);
521 
522     auto executor = [context]() {
523         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
524         if (napiSession->session_ == nullptr) {
525             context->status = napi_generic_failure;
526             context->errMessage = "Activate session failed : session is nullptr";
527             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
528             return;
529         }
530         int32_t ret = napiSession->session_->Activate();
531         if (ret != AVSESSION_SUCCESS) {
532             if (ret == ERR_SESSION_NOT_EXIST) {
533                 context->errMessage = "Activate session failed : native session not exist";
534             } else {
535                 context->errMessage = "Activate session failed : native server exception";
536             }
537             context->status = napi_generic_failure;
538             context->errCode = NapiAVSessionManager::errcode_[ret];
539         }
540     };
541     auto complete = [env](napi_value& output) {
542         output = NapiUtils::GetUndefinedValue(env);
543     };
544     return NapiAsyncWork::Enqueue(env, context, "Activate", executor, complete);
545 }
546 
Deactivate(napi_env env,napi_callback_info info)547 napi_value NapiAVSession::Deactivate(napi_env env, napi_callback_info info)
548 {
549     auto context = std::make_shared<ContextBase>();
550     if (context == nullptr) {
551         SLOGE("Deactivate failed : no memory");
552         NapiUtils::ThrowError(env, "Deactivate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
553         return NapiUtils::GetUndefinedValue(env);
554     }
555 
556     context->GetCbInfo(env, info);
557 
558     auto executor = [context]() {
559         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
560         if (napiSession->session_ == nullptr) {
561             context->status = napi_generic_failure;
562             context->errMessage = "Deactivate session failed : session is nullptr";
563             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
564             return;
565         }
566         int32_t ret = napiSession->session_->Deactivate();
567         if (ret != AVSESSION_SUCCESS) {
568             if (ret == ERR_SESSION_NOT_EXIST) {
569                 context->errMessage = "Deactivate session failed : native session not exist";
570             } else {
571                 context->errMessage = "Deactivate session failed : native server exception";
572             }
573             context->status = napi_generic_failure;
574             context->errCode = NapiAVSessionManager::errcode_[ret];
575         }
576     };
577     auto complete = [env](napi_value& output) {
578         output = NapiUtils::GetUndefinedValue(env);
579     };
580     return NapiAsyncWork::Enqueue(env, context, "Deactivate", executor, complete);
581 }
582 
Destroy(napi_env env,napi_callback_info info)583 napi_value NapiAVSession::Destroy(napi_env env, napi_callback_info info)
584 {
585     auto context = std::make_shared<ContextBase>();
586     if (context == nullptr) {
587         SLOGE("Destroy failed : no memory");
588         NapiUtils::ThrowError(env, "Destroy failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
589         return NapiUtils::GetUndefinedValue(env);
590     }
591 
592     context->GetCbInfo(env, info);
593 
594     auto executor = [context]() {
595         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
596         if (napiSession->session_ == nullptr) {
597             context->status = napi_generic_failure;
598             context->errMessage = "Destroy session failed : session is nullptr";
599             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
600             return;
601         }
602         int32_t ret = napiSession->session_->Destroy();
603         if (ret == AVSESSION_SUCCESS) {
604             napiSession->session_ = nullptr;
605             napiSession->callback_ = nullptr;
606         } else if (ret == ERR_SESSION_NOT_EXIST) {
607             context->status = napi_generic_failure;
608             context->errMessage = "Destroy session failed : native session not exist";
609             context->errCode = NapiAVSessionManager::errcode_[ret];
610         } else {
611             context->status = napi_generic_failure;
612             context->errMessage = "Destroy session failed : native server exception";
613             context->errCode = NapiAVSessionManager::errcode_[ret];
614         }
615     };
616     auto complete = [env](napi_value& output) {
617         output = NapiUtils::GetUndefinedValue(env);
618     };
619     return NapiAsyncWork::Enqueue(env, context, "Destroy", executor, complete);
620 }
621 
OnPlay(napi_env env,NapiAVSession * napiSession,napi_value callback)622 napi_status NapiAVSession::OnPlay(napi_env env, NapiAVSession* napiSession, napi_value callback)
623 {
624     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY);
625     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
626     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
627         "NapiAVSessionCallback object is nullptr");
628     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY, callback);
629 }
630 
OnPause(napi_env env,NapiAVSession * napiSession,napi_value callback)631 napi_status NapiAVSession::OnPause(napi_env env, NapiAVSession* napiSession, napi_value callback)
632 {
633     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PAUSE);
634     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
635     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
636         "NapiAVSessionCallback object is nullptr");
637     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PAUSE, callback);
638 }
639 
OnStop(napi_env env,NapiAVSession * napiSession,napi_value callback)640 napi_status NapiAVSession::OnStop(napi_env env, NapiAVSession* napiSession, napi_value callback)
641 {
642     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_STOP);
643     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
644     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
645         "NapiAVSessionCallback object is nullptr");
646     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_STOP, callback);
647 }
648 
OnPlayNext(napi_env env,NapiAVSession * napiSession,napi_value callback)649 napi_status NapiAVSession::OnPlayNext(napi_env env, NapiAVSession* napiSession, napi_value callback)
650 {
651     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_NEXT);
652     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
653     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
654         "NapiAVSessionCallback object is nullptr");
655     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_NEXT, callback);
656 }
657 
OnPlayPrevious(napi_env env,NapiAVSession * napiSession,napi_value callback)658 napi_status NapiAVSession::OnPlayPrevious(napi_env env, NapiAVSession* napiSession, napi_value callback)
659 {
660     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS);
661     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
662     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
663         "NapiAVSessionCallback object is nullptr");
664     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_PREVIOUS, callback);
665 }
666 
OnFastForward(napi_env env,NapiAVSession * napiSession,napi_value callback)667 napi_status NapiAVSession::OnFastForward(napi_env env, NapiAVSession* napiSession, napi_value callback)
668 {
669     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_FAST_FORWARD);
670     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
671     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
672         "NapiAVSessionCallback object is nullptr");
673     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_FAST_FORWARD, callback);
674 }
675 
OnRewind(napi_env env,NapiAVSession * napiSession,napi_value callback)676 napi_status NapiAVSession::OnRewind(napi_env env, NapiAVSession* napiSession, napi_value callback)
677 {
678     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_REWIND);
679     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
680     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
681         "NapiAVSessionCallback object is nullptr");
682     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_REWIND, callback);
683 }
684 
OnSeek(napi_env env,NapiAVSession * napiSession,napi_value callback)685 napi_status NapiAVSession::OnSeek(napi_env env, NapiAVSession* napiSession, napi_value callback)
686 {
687     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SEEK);
688     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
689     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
690         "NapiAVSessionCallback object is nullptr");
691     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SEEK, callback);
692 }
693 
OnSetSpeed(napi_env env,NapiAVSession * napiSession,napi_value callback)694 napi_status NapiAVSession::OnSetSpeed(napi_env env, NapiAVSession* napiSession, napi_value callback)
695 {
696     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SET_SPEED);
697     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
698     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
699         "NapiAVSessionCallback object is nullptr");
700     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SET_SPEED, callback);
701 }
702 
OnSetLoopMode(napi_env env,NapiAVSession * napiSession,napi_value callback)703 napi_status NapiAVSession::OnSetLoopMode(napi_env env, NapiAVSession* napiSession, napi_value callback)
704 {
705     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
706     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
707     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
708         "NapiAVSessionCallback object is nullptr");
709     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SET_LOOP_MODE, callback);
710 }
711 
OnToggleFavorite(napi_env env,NapiAVSession * napiSession,napi_value callback)712 napi_status NapiAVSession::OnToggleFavorite(napi_env env, NapiAVSession* napiSession, napi_value callback)
713 {
714     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE);
715     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
716     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
717         "NapiAVSessionCallback object is nullptr");
718     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE, callback);
719 }
720 
OnMediaKeyEvent(napi_env env,NapiAVSession * napiSession,napi_value callback)721 napi_status NapiAVSession::OnMediaKeyEvent(napi_env env, NapiAVSession* napiSession, napi_value callback)
722 {
723     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
724         "NapiAVSessionCallback object is nullptr");
725     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT, callback);
726 }
727 
OnOutputDeviceChange(napi_env env,NapiAVSession * napiSession,napi_value callback)728 napi_status NapiAVSession::OnOutputDeviceChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
729 {
730     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
731         "NapiAVSessionCallback object is nullptr");
732     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_OUTPUT_DEVICE_CHANGE, callback);
733 }
734 
OffPlay(napi_env env,NapiAVSession * napiSession,napi_value callback)735 napi_status NapiAVSession::OffPlay(napi_env env, NapiAVSession* napiSession, napi_value callback)
736 {
737     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY, callback);
738     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
739     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
740         "NapiAVSessionCallback object is nullptr");
741     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY)) {
742         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY);
743         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
744     }
745     return napi_ok;
746 }
747 
OffPause(napi_env env,NapiAVSession * napiSession,napi_value callback)748 napi_status NapiAVSession::OffPause(napi_env env, NapiAVSession* napiSession, napi_value callback)
749 {
750     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PAUSE, callback);
751     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
752     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
753         "NapiAVSessionCallback object is nullptr");
754     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PAUSE)) {
755         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PAUSE);
756         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
757     }
758     return napi_ok;
759 }
760 
OffStop(napi_env env,NapiAVSession * napiSession,napi_value callback)761 napi_status NapiAVSession::OffStop(napi_env env, NapiAVSession* napiSession, napi_value callback)
762 {
763     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_STOP, callback);
764     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
765     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
766         "NapiAVSessionCallback object is nullptr");
767     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_STOP)) {
768         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_STOP);
769         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
770     }
771     return napi_ok;
772 }
773 
OffPlayNext(napi_env env,NapiAVSession * napiSession,napi_value callback)774 napi_status NapiAVSession::OffPlayNext(napi_env env, NapiAVSession* napiSession, napi_value callback)
775 {
776     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_NEXT, callback);
777     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
778     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
779         "NapiAVSessionCallback object is nullptr");
780     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_NEXT)) {
781         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_NEXT);
782         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
783     }
784     return napi_ok;
785 }
786 
OffPlayPrevious(napi_env env,NapiAVSession * napiSession,napi_value callback)787 napi_status NapiAVSession::OffPlayPrevious(napi_env env, NapiAVSession* napiSession, napi_value callback)
788 {
789     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_PREVIOUS, callback);
790     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
791     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
792         "NapiAVSessionCallback object is nullptr");
793     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_PREVIOUS)) {
794         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS);
795         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
796     }
797     return napi_ok;
798 }
799 
OffFastForward(napi_env env,NapiAVSession * napiSession,napi_value callback)800 napi_status NapiAVSession::OffFastForward(napi_env env, NapiAVSession* napiSession, napi_value callback)
801 {
802     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_FAST_FORWARD, callback);
803     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
804     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
805         "NapiAVSessionCallback object is nullptr");
806     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_FAST_FORWARD)) {
807         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_FAST_FORWARD);
808         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
809     }
810     return napi_ok;
811 }
812 
OffRewind(napi_env env,NapiAVSession * napiSession,napi_value callback)813 napi_status NapiAVSession::OffRewind(napi_env env, NapiAVSession* napiSession, napi_value callback)
814 {
815     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_REWIND, callback);
816     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
817     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
818         "NapiAVSessionCallback object is nullptr");
819     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_REWIND)) {
820         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_REWIND);
821         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
822     }
823     return napi_ok;
824 }
825 
OffSeek(napi_env env,NapiAVSession * napiSession,napi_value callback)826 napi_status NapiAVSession::OffSeek(napi_env env, NapiAVSession* napiSession, napi_value callback)
827 {
828     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SEEK, callback);
829     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
830     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
831         "NapiAVSessionCallback object is nullptr");
832     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SEEK)) {
833         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SEEK);
834         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
835     }
836     return napi_ok;
837 }
838 
OffSetSpeed(napi_env env,NapiAVSession * napiSession,napi_value callback)839 napi_status NapiAVSession::OffSetSpeed(napi_env env, NapiAVSession* napiSession, napi_value callback)
840 {
841     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SET_SPEED, callback);
842     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
843     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
844         "NapiAVSessionCallback object is nullptr");
845     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SET_SPEED)) {
846         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SET_SPEED);
847         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
848     }
849     return napi_ok;
850 }
851 
OffSetLoopMode(napi_env env,NapiAVSession * napiSession,napi_value callback)852 napi_status NapiAVSession::OffSetLoopMode(napi_env env, NapiAVSession* napiSession, napi_value callback)
853 {
854     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SET_LOOP_MODE, callback);
855     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
856     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
857         "NapiAVSessionCallback object is nullptr");
858     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SET_LOOP_MODE)) {
859         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
860         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
861     }
862     return napi_ok;
863 }
864 
OffToggleFavorite(napi_env env,NapiAVSession * napiSession,napi_value callback)865 napi_status NapiAVSession::OffToggleFavorite(napi_env env, NapiAVSession* napiSession, napi_value callback)
866 {
867     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE, callback);
868     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
869     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
870         "NapiAVSessionCallback object is nullptr");
871     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE)) {
872         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE);
873         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
874     }
875     return napi_ok;
876 }
877 
OffMediaKeyEvent(napi_env env,NapiAVSession * napiSession,napi_value callback)878 napi_status NapiAVSession::OffMediaKeyEvent(napi_env env, NapiAVSession* napiSession, napi_value callback)
879 {
880     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
881         "NapiAVSessionCallback object is nullptr");
882     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT, callback);
883 }
884 
OffOutputDeviceChange(napi_env env,NapiAVSession * napiSession,napi_value callback)885 napi_status NapiAVSession::OffOutputDeviceChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
886 {
887     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
888         "NapiAVSessionCallback object is nullptr");
889     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_OUTPUT_DEVICE_CHANGE, callback);
890 }
891 }
892