• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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 "napi_media_description.h"
23 #include "napi_queue_item.h"
24 #include "want_params.h"
25 #include "want_agent.h"
26 #include "avsession_trace.h"
27 #include "napi_avsession_controller.h"
28 #include "napi_avsession_manager.h"
29 
30 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
31 #include "avcast_controller.h"
32 #include "napi_avcast_controller.h"
33 #endif
34 namespace OHOS::AVSession {
35 static __thread napi_ref AVSessionConstructorRef = nullptr;
36 std::map<std::string, NapiAVSession::OnEventHandlerType> NapiAVSession::onEventHandlers_ = {
37     { "play", OnPlay },
38     { "pause", OnPause },
39     { "stop", OnStop },
40     { "playNext", OnPlayNext },
41     { "playPrevious", OnPlayPrevious },
42     { "fastForward", OnFastForward },
43     { "rewind", OnRewind },
44     { "seek", OnSeek },
45     { "setSpeed", OnSetSpeed },
46     { "setLoopMode", OnSetLoopMode },
47     { "toggleFavorite", OnToggleFavorite },
48     { "handleKeyEvent", OnMediaKeyEvent },
49     { "outputDeviceChange", OnOutputDeviceChange },
50     { "commonCommand", OnCommonCommand },
51     { "skipToQueueItem", OnSkipToQueueItem },
52 };
53 std::map<std::string, NapiAVSession::OffEventHandlerType> NapiAVSession::offEventHandlers_ = {
54     { "play", OffPlay },
55     { "pause", OffPause },
56     { "stop", OffStop },
57     { "playNext", OffPlayNext },
58     { "playPrevious", OffPlayPrevious },
59     { "fastForward", OffFastForward },
60     { "rewind", OffRewind },
61     { "seek", OffSeek },
62     { "setSpeed", OffSetSpeed },
63     { "setLoopMode", OffSetLoopMode },
64     { "toggleFavorite", OffToggleFavorite },
65     { "handleKeyEvent", OffMediaKeyEvent },
66     { "outputDeviceChange", OffOutputDeviceChange },
67     { "commonCommand", OffCommonCommand },
68     { "skipToQueueItem", OffSkipToQueueItem },
69 };
70 
NapiAVSession()71 NapiAVSession::NapiAVSession()
72 {
73     SLOGI("construct");
74 }
75 
~NapiAVSession()76 NapiAVSession::~NapiAVSession()
77 {
78     SLOGI("destroy");
79 }
80 
Init(napi_env env,napi_value exports)81 napi_value NapiAVSession::Init(napi_env env, napi_value exports)
82 {
83     napi_property_descriptor descriptors[] = {
84         DECLARE_NAPI_FUNCTION("setAVMetadata", SetAVMetaData),
85         DECLARE_NAPI_FUNCTION("setAVPlaybackState", SetAVPlaybackState),
86         DECLARE_NAPI_FUNCTION("setLaunchAbility", SetLaunchAbility),
87         DECLARE_NAPI_FUNCTION("setExtras", SetExtras),
88         DECLARE_NAPI_FUNCTION("setAudioStreamId", SetAudioStreamId),
89         DECLARE_NAPI_FUNCTION("getController", GetController),
90         DECLARE_NAPI_FUNCTION("activate", Activate),
91         DECLARE_NAPI_FUNCTION("deactivate", Deactivate),
92         DECLARE_NAPI_FUNCTION("destroy", Destroy),
93         DECLARE_NAPI_FUNCTION("on", OnEvent),
94         DECLARE_NAPI_FUNCTION("off", OffEvent),
95         DECLARE_NAPI_FUNCTION("getOutputDevice", GetOutputDevice),
96         DECLARE_NAPI_FUNCTION("getOutputDeviceSync", GetOutputDeviceSync),
97         DECLARE_NAPI_FUNCTION("dispatchSessionEvent", SetSessionEvent),
98         DECLARE_NAPI_FUNCTION("setAVQueueItems", SetAVQueueItems),
99         DECLARE_NAPI_FUNCTION("setAVQueueTitle", SetAVQueueTitle),
100         DECLARE_NAPI_FUNCTION("getAVCastController", GetAVCastController),
101         DECLARE_NAPI_FUNCTION("stopCasting", ReleaseCast),
102     };
103     auto propertyCount = sizeof(descriptors) / sizeof(napi_property_descriptor);
104     napi_value constructor {};
105     auto status = napi_define_class(env, "AVSession", NAPI_AUTO_LENGTH, ConstructorCallback, nullptr,
106                                     propertyCount, descriptors, &constructor);
107     if (status != napi_ok) {
108         SLOGE("define class failed");
109         return NapiUtils::GetUndefinedValue(env);
110     }
111     napi_create_reference(env, constructor, 1, &AVSessionConstructorRef);
112     return exports;
113 }
114 
ConstructorCallback(napi_env env,napi_callback_info info)115 napi_value NapiAVSession::ConstructorCallback(napi_env env, napi_callback_info info)
116 {
117     napi_value self;
118     NAPI_CALL_BASE(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr), nullptr);
119     auto finalize = [](napi_env env, void* data, void* hint) {
120         auto* napiSession = reinterpret_cast<NapiAVSession*>(data);
121         napi_delete_reference(env, napiSession->wrapperRef_);
122         delete napiSession;
123         napiSession = nullptr;
124     };
125     auto* napiSession = new(std::nothrow) NapiAVSession();
126     if (napiSession == nullptr) {
127         SLOGE("no memory");
128         return nullptr;
129     }
130     if (napi_wrap(env, self, static_cast<void*>(napiSession), finalize, nullptr, nullptr) != napi_ok) {
131         SLOGE("wrap failed");
132         return nullptr;
133     }
134     return self;
135 }
136 
NewInstance(napi_env env,std::shared_ptr<AVSession> & nativeSession,napi_value & out)137 napi_status NapiAVSession::NewInstance(napi_env env, std::shared_ptr<AVSession>& nativeSession, napi_value& out)
138 {
139     napi_value constructor {};
140     NAPI_CALL_BASE(env, napi_get_reference_value(env, AVSessionConstructorRef, &constructor), napi_generic_failure);
141     napi_value instance{};
142     NAPI_CALL_BASE(env, napi_new_instance(env, constructor, 0, nullptr, &instance), napi_generic_failure);
143     NapiAVSession* napiAvSession{};
144     NAPI_CALL_BASE(env, napi_unwrap(env, instance, reinterpret_cast<void**>(&napiAvSession)), napi_generic_failure);
145     napiAvSession->session_ = std::move(nativeSession);
146     napiAvSession->sessionId_ = napiAvSession->session_->GetSessionId();
147     napiAvSession->sessionType_ = napiAvSession->session_->GetSessionType();
148     SLOGI("sessionId=%{public}s", napiAvSession->sessionId_.c_str());
149 
150     napi_value property {};
151     auto status = NapiUtils::SetValue(env, napiAvSession->sessionId_, property);
152     CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
153     NAPI_CALL_BASE(env, napi_set_named_property(env, instance, "sessionId", property), napi_generic_failure);
154 
155     status = NapiUtils::SetValue(env, napiAvSession->sessionType_, property);
156     CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
157     NAPI_CALL_BASE(env, napi_set_named_property(env, instance, "sessionType", property), napi_generic_failure);
158     out = instance;
159     return napi_ok;
160 }
161 
OnEvent(napi_env env,napi_callback_info info)162 napi_value NapiAVSession::OnEvent(napi_env env, napi_callback_info info)
163 {
164     auto context = std::make_shared<ContextBase>();
165     if (context == nullptr) {
166         SLOGE("OnEvent failed : no memory");
167         return ThrowErrorAndReturn(env, "OnEvent failed : no memory", ERR_NO_MEMORY);
168     }
169     std::string eventName;
170     napi_value callback {};
171     auto input = [&eventName, &callback, env, &context](size_t argc, napi_value* argv) {
172         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid argument number",
173             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
174         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
175         CHECK_STATUS_RETURN_VOID(context, "get event name failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
176         napi_valuetype type = napi_undefined;
177         context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
178         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
179                                "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
180         callback = argv[ARGV_SECOND];
181     };
182     context->GetCbInfo(env, info, input, true);
183     if (context->status != napi_ok) {
184         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
185         return NapiUtils::GetUndefinedValue(env);
186     }
187     auto it = onEventHandlers_.find(eventName);
188     if (it == onEventHandlers_.end()) {
189         SLOGE("event name invalid");
190         return ThrowErrorAndReturn(env, "event name invalid", ERR_INVALID_PARAM);
191     }
192     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
193     if (napiSession->session_ == nullptr) {
194         SLOGE("OnEvent failed : session is nullptr");
195         return ThrowErrorAndReturn(env, "OnEvent failed : session is nullptr", ERR_SESSION_NOT_EXIST);
196     }
197     if (napiSession->callback_ == nullptr) {
198         napiSession->callback_ = std::make_shared<NapiAVSessionCallback>();
199         if (napiSession->callback_ == nullptr) {
200             SLOGE("OnEvent failed : no memory");
201             return ThrowErrorAndReturn(env, "OnEvent failed : no memory", ERR_NO_MEMORY);
202         }
203         int32_t ret = napiSession->session_->RegisterCallback(napiSession->callback_);
204         if (ret != AVSESSION_SUCCESS) {
205             return ThrowErrorAndReturnByErrCode(env, "OnEvent", ret);
206         }
207     }
208     if (it->second(env, napiSession, callback) != napi_ok) {
209         NapiUtils::ThrowError(env, "add event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
210     }
211     return NapiUtils::GetUndefinedValue(env);
212 }
213 
ThrowErrorAndReturn(napi_env env,const std::string & message,int32_t errCode)214 napi_value NapiAVSession::ThrowErrorAndReturn(napi_env env, const std::string& message, int32_t errCode)
215 {
216     std::string tempMessage = message;
217     NapiUtils::ThrowError(env, tempMessage.c_str(), NapiAVSessionManager::errcode_[errCode]);
218     return NapiUtils::GetUndefinedValue(env);
219 }
220 
ThrowErrorAndReturnByErrCode(napi_env env,const std::string & message,int32_t errCode)221 napi_value NapiAVSession::ThrowErrorAndReturnByErrCode(napi_env env, const std::string& message, int32_t errCode)
222 {
223     std::string tempMessage = message;
224     if (errCode == ERR_SESSION_NOT_EXIST) {
225         tempMessage.append(" failed : native session not exist");
226     } else if (errCode == ERR_INVALID_PARAM) {
227         tempMessage.append(" failed : native invalid parameters");
228     } else if (errCode == ERR_NO_PERMISSION) {
229         tempMessage.append(" failed : native no permission");
230     } else {
231         tempMessage.append(" failed : native server exception");
232     }
233     SLOGI("throw error message: %{public}s", tempMessage.c_str());
234     NapiUtils::ThrowError(env, tempMessage.c_str(), NapiAVSessionManager::errcode_[errCode]);
235     return NapiUtils::GetUndefinedValue(env);
236 }
237 
OffEvent(napi_env env,napi_callback_info info)238 napi_value NapiAVSession::OffEvent(napi_env env, napi_callback_info info)
239 {
240     auto context = std::make_shared<ContextBase>();
241     if (context == nullptr) {
242         SLOGE("OffEvent failed : no memory");
243         NapiUtils::ThrowError(env, "OffEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
244         return NapiUtils::GetUndefinedValue(env);
245     }
246     std::string eventName;
247     napi_value callback = nullptr;
248     auto input = [&eventName, env, &context, &callback](size_t argc, napi_value* argv) {
249         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE || argc == ARGC_TWO,
250                                "invalid argument number", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
251         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
252         CHECK_STATUS_RETURN_VOID(context, "get event name failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
253         if (argc == ARGC_TWO) {
254             callback = argv[ARGV_SECOND];
255         }
256     };
257     context->GetCbInfo(env, info, input, true);
258     if (context->status != napi_ok) {
259         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
260         return NapiUtils::GetUndefinedValue(env);
261     }
262     auto it = offEventHandlers_.find(eventName);
263     if (it == offEventHandlers_.end()) {
264         SLOGE("event name invalid");
265         NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
266         return NapiUtils::GetUndefinedValue(env);
267     }
268     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
269     if (napiSession->session_ == nullptr) {
270         SLOGE("OffEvent failed : session is nullptr");
271         NapiUtils::ThrowError(env, "OffEvent failed : session is nullptr",
272             NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST]);
273         return NapiUtils::GetUndefinedValue(env);
274     }
275     if (napiSession != nullptr && it->second(env, napiSession, callback) != napi_ok) {
276         NapiUtils::ThrowError(env, "remove event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
277     }
278     return NapiUtils::GetUndefinedValue(env);
279 }
280 
SetAVMetaData(napi_env env,napi_callback_info info)281 napi_value NapiAVSession::SetAVMetaData(napi_env env, napi_callback_info info)
282 {
283     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVMetadata");
284     struct ConcreteContext : public ContextBase {
285         AVMetaData metaData_;
286     };
287     auto context = std::make_shared<ConcreteContext>();
288     if (context == nullptr) {
289         SLOGE("SetAVMetaData failed : no memory");
290         NapiUtils::ThrowError(env, "SetAVMetaData failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
291         return NapiUtils::GetUndefinedValue(env);
292     }
293 
294     auto inputParser = [env, context](size_t argc, napi_value* argv) {
295         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
296             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
297         context->status = NapiMetaData::GetValue(env, argv[ARGV_FIRST], context->metaData_);
298         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get metaData failed",
299             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
300     };
301     context->GetCbInfo(env, info, inputParser);
302     context->taskId = NAPI_SET_AV_META_DATA_TASK_ID;
303 
304     auto executor = [context]() {
305         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
306         if (napiSession->session_ == nullptr) {
307             context->status = napi_generic_failure;
308             context->errMessage = "SetAVMetaData failed : session is nullptr";
309             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
310             return;
311         }
312         int32_t ret = napiSession->session_->SetAVMetaData(context->metaData_);
313         if (ret != AVSESSION_SUCCESS) {
314             if (ret == ERR_SESSION_NOT_EXIST) {
315                 context->errMessage = "SetAVMetaData failed : native session not exist";
316             } else if (ret == ERR_INVALID_PARAM) {
317                 context->errMessage = "SetAVMetaData failed : native invalid parameters";
318             } else if (ret == ERR_NO_PERMISSION) {
319                 context->errMessage = "SetAVMetaData failed : native no permission";
320             } else {
321                 context->errMessage = "SetAVMetaData failed : native server exception";
322             }
323             context->status = napi_generic_failure;
324             context->errCode = NapiAVSessionManager::errcode_[ret];
325         }
326     };
327     auto complete = [env](napi_value& output) {
328         output = NapiUtils::GetUndefinedValue(env);
329     };
330     return NapiAsyncWork::Enqueue(env, context, "SetAVMetaData", executor, complete);
331 }
332 
SetAVPlaybackState(napi_env env,napi_callback_info info)333 napi_value NapiAVSession::SetAVPlaybackState(napi_env env, napi_callback_info info)
334 {
335     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVPlaybackState");
336     struct ConcreteContext : public ContextBase {
337         AVPlaybackState playBackState_;
338     };
339     auto context = std::make_shared<ConcreteContext>();
340     if (context == nullptr) {
341         SLOGE("SetAVPlaybackState failed : no memory");
342         NapiUtils::ThrowError(env, "SetAVPlaybackState failed : no memory",
343                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
344         return NapiUtils::GetUndefinedValue(env);
345     }
346 
347     auto inputParser = [env, context](size_t argc, napi_value* argv) {
348         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
349             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
350         context->status = NapiPlaybackState::GetValue(env, argv[ARGV_FIRST], context->playBackState_);
351         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get playBackState failed",
352             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
353     };
354     context->GetCbInfo(env, info, inputParser);
355     context->taskId = NAPI_SET_AV_PLAYBACK_STATE_TASK_ID;
356 
357     auto executor = [context]() {
358         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
359         if (napiSession->session_ == nullptr) {
360             context->status = napi_generic_failure;
361             context->errMessage = "SetAVPlaybackState failed : session is nullptr";
362             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
363             return;
364         }
365         int32_t ret = napiSession->session_->SetAVPlaybackState(context->playBackState_);
366         if (ret != AVSESSION_SUCCESS) {
367             if (ret == ERR_SESSION_NOT_EXIST) {
368                 context->errMessage = "SetAVPlaybackState failed : native session not exist";
369             } else if (ret == ERR_INVALID_PARAM) {
370                 context->errMessage = "SetAVPlaybackState failed : native invalid parameters";
371             } else if (ret == ERR_NO_PERMISSION) {
372                 context->errMessage = "SetAVPlaybackState failed : native no permission";
373             } else {
374                 context->errMessage = "SetAVPlaybackState failed : native server exception";
375             }
376             context->status = napi_generic_failure;
377             context->errCode = NapiAVSessionManager::errcode_[ret];
378         }
379     };
380     auto complete = [env](napi_value& output) {
381         output = NapiUtils::GetUndefinedValue(env);
382     };
383     return NapiAsyncWork::Enqueue(env, context, "SetAVPlaybackState", executor, complete);
384 }
385 
SetAVQueueItems(napi_env env,napi_callback_info info)386 napi_value NapiAVSession::SetAVQueueItems(napi_env env, napi_callback_info info)
387 {
388     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVQueueItems");
389     struct ConcreteContext : public ContextBase { std::vector<AVQueueItem> items_; };
390     auto context = std::make_shared<ConcreteContext>();
391     if (context == nullptr) {
392         NapiUtils::ThrowError(env, "SetAVQueueItems failed : no memory",
393             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
394         return NapiUtils::GetUndefinedValue(env);
395     }
396     auto inputParser = [env, context](size_t argc, napi_value* argv) {
397         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
398             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
399         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->items_);
400         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get queueItems failed",
401             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
402         for (auto &item : context->items_) {
403             CHECK_ARGS_RETURN_VOID(context, item.IsValid(), "invalid queue item content",
404                 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
405         }
406     };
407     context->GetCbInfo(env, info, inputParser);
408     context->taskId = NAPI_SET_AV_QUEUE_ITEMS_TASK_ID;
409     auto executor = [context]() {
410         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
411         if (napiSession->session_ == nullptr) {
412             context->status = napi_generic_failure;
413             context->errMessage = "SetAVQueueItems failed : session is nullptr";
414             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
415             return;
416         }
417         int32_t ret = napiSession->session_->SetAVQueueItems(context->items_);
418         if (ret != AVSESSION_SUCCESS) {
419             if (ret == ERR_SESSION_NOT_EXIST) {
420                 context->errMessage = "SetAVQueueItems failed : native session not exist";
421             } else if (ret == ERR_INVALID_PARAM) {
422                 context->errMessage = "SetAVQueueItems failed : native invalid parameters";
423             } else if (ret == ERR_NO_PERMISSION) {
424                 context->errMessage = "SetAVQueueItems failed : native no permission";
425             } else {
426                 context->errMessage = "SetAVQueueItems failed : native server exception";
427             }
428             context->status = napi_generic_failure;
429             context->errCode = NapiAVSessionManager::errcode_[ret];
430         }
431     };
432     auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
433     return NapiAsyncWork::Enqueue(env, context, "SetAVQueueItems", executor, complete);
434 }
435 
SetAVQueueTitle(napi_env env,napi_callback_info info)436 napi_value NapiAVSession::SetAVQueueTitle(napi_env env, napi_callback_info info)
437 {
438     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVQueueTitle");
439     struct ConcreteContext : public ContextBase {
440         std::string title;
441     };
442     auto context = std::make_shared<ConcreteContext>();
443     if (context == nullptr) {
444         SLOGE("SetAVQueueTitle failed : no memory");
445         NapiUtils::ThrowError(env, "SetAVQueueTitle failed : no memory",
446             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
447         return NapiUtils::GetUndefinedValue(env);
448     }
449 
450     auto inputParser = [env, context](size_t argc, napi_value* argv) {
451         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
452             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
453         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->title);
454         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get queueItems failed",
455             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
456     };
457     context->GetCbInfo(env, info, inputParser);
458     context->taskId = NAPI_SET_AV_QUEUE_TITLE_TASK_ID;
459 
460     auto executor = [context]() {
461         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
462         if (napiSession->session_ == nullptr) {
463             context->status = napi_generic_failure;
464             context->errMessage = "SetAVQueueTitle failed : session is nullptr";
465             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
466             return;
467         }
468         int32_t ret = napiSession->session_->SetAVQueueTitle(context->title);
469         if (ret != AVSESSION_SUCCESS) {
470             if (ret == ERR_SESSION_NOT_EXIST) {
471                 context->errMessage = "SetAVQueueTitle failed : native session not exist";
472             } else if (ret == ERR_INVALID_PARAM) {
473                 context->errMessage = "SetAVQueueTitle failed : native invalid parameters";
474             } else if (ret == ERR_NO_PERMISSION) {
475                 context->errMessage = "SetAVQueueTitle failed : native no permission";
476             } else {
477                 context->errMessage = "SetAVQueueTitle failed : native server exception";
478             }
479             context->status = napi_generic_failure;
480             context->errCode = NapiAVSessionManager::errcode_[ret];
481         }
482     };
483     auto complete = [env](napi_value& output) {
484         output = NapiUtils::GetUndefinedValue(env);
485     };
486     return NapiAsyncWork::Enqueue(env, context, "SetAVQueueTitle", executor, complete);
487 }
488 
SetLaunchAbility(napi_env env,napi_callback_info info)489 napi_value NapiAVSession::SetLaunchAbility(napi_env env, napi_callback_info info)
490 {
491     struct ConcreteContext : public ContextBase {
492         AbilityRuntime::WantAgent::WantAgent* wantAgent_;
493     };
494     auto context = std::make_shared<ConcreteContext>();
495     if (context == nullptr) {
496         SLOGE("SetLaunchAbility failed : no memory");
497         NapiUtils::ThrowError(env, "SetLaunchAbility failed : no memory",
498                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
499         return NapiUtils::GetUndefinedValue(env);
500     }
501 
502     auto inputParser = [env, context](size_t argc, napi_value* argv) {
503         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
504             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
505         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->wantAgent_);
506         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get  wantAgent failed",
507             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
508     };
509     context->GetCbInfo(env, info, inputParser);
510 
511     auto executor = [context]() {
512         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
513         if (napiSession->session_ == nullptr) {
514             context->status = napi_generic_failure;
515             context->errMessage = "SetLaunchAbility failed : session is nullptr";
516             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
517             return;
518         }
519         int32_t ret = napiSession->session_->SetLaunchAbility(*context->wantAgent_);
520         if (ret != AVSESSION_SUCCESS) {
521             if (ret == ERR_SESSION_NOT_EXIST) {
522                 context->errMessage = "SetLaunchAbility failed : native session not exist";
523             } else if (ret == ERR_NO_PERMISSION) {
524                 context->errMessage = "SetLaunchAbility failed : native no permission";
525             } else {
526                 context->errMessage = "SetLaunchAbility failed : native server exception";
527             }
528             context->status = napi_generic_failure;
529             context->errCode = NapiAVSessionManager::errcode_[ret];
530         }
531     };
532     auto complete = [env](napi_value& output) {
533         output = NapiUtils::GetUndefinedValue(env);
534     };
535     return NapiAsyncWork::Enqueue(env, context, "SetLaunchAbility", executor, complete);
536 }
537 
SetExtras(napi_env env,napi_callback_info info)538 napi_value NapiAVSession::SetExtras(napi_env env, napi_callback_info info)
539 {
540     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetExtras");
541     struct ConcreteContext : public ContextBase {
542         AAFwk::WantParams extras_;
543     };
544     auto context = std::make_shared<ConcreteContext>();
545     if (context == nullptr) {
546         SLOGE("SetExtras failed : no memory");
547         NapiUtils::ThrowError(env, "SetExtras failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
548         return NapiUtils::GetUndefinedValue(env);
549     }
550 
551     auto inputParser = [env, context](size_t argc, napi_value* argv) {
552         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
553             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
554         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->extras_);
555         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get extras failed",
556             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
557     };
558     context->GetCbInfo(env, info, inputParser);
559     context->taskId = NAPI_SET_EXTRAS_TASK_ID;
560 
561     auto executor = [context]() {
562         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
563         if (napiSession->session_ == nullptr) {
564             context->status = napi_generic_failure;
565             context->errMessage = "SetExtras failed : session is nullptr";
566             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
567             return;
568         }
569         int32_t ret = napiSession->session_->SetExtras(context->extras_);
570         if (ret != AVSESSION_SUCCESS) {
571             if (ret == ERR_SESSION_NOT_EXIST) {
572                 context->errMessage = "SetExtras failed : native session not exist";
573             } else if (ret == ERR_INVALID_PARAM) {
574                 context->errMessage = "SetExtras failed : native invalid parameters";
575             } else {
576                 context->errMessage = "SetExtras failed : native server exception";
577             }
578             context->status = napi_generic_failure;
579             context->errCode = NapiAVSessionManager::errcode_[ret];
580         }
581     };
582     auto complete = [env](napi_value& output) {
583         output = NapiUtils::GetUndefinedValue(env);
584     };
585     return NapiAsyncWork::Enqueue(env, context, "SetExtras", executor, complete);
586 }
587 
SetAudioStreamId(napi_env env,napi_callback_info info)588 napi_value NapiAVSession::SetAudioStreamId(napi_env env, napi_callback_info info)
589 {
590     struct ConcreteContext : public ContextBase {
591         std::vector<int32_t> streamIds_;
592     };
593     auto context = std::make_shared<ConcreteContext>();
594     if (context == nullptr) {
595         SLOGE("SetAudioStreamId failed : no memory");
596         NapiUtils::ThrowError(env, "SetAudioStreamId failed : no memory",
597                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
598         return NapiUtils::GetUndefinedValue(env);
599     }
600 
601     auto inputParser = [env, context](size_t argc, napi_value* argv) {
602         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
603             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
604         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->streamIds_);
605         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get streamIds_ failed",
606             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
607     };
608     context->GetCbInfo(env, info, inputParser);
609 
610     auto executor = [context]() {
611         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
612         if (napiSession->session_ == nullptr) {
613             context->status = napi_generic_failure;
614             context->errMessage = "SetAudioStreamId failed : session is nullptr";
615             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
616             return;
617         }
618     };
619     auto complete = [env](napi_value& output) {
620         output = NapiUtils::GetUndefinedValue(env);
621     };
622     return NapiAsyncWork::Enqueue(env, context, "SetAudioStreamId", executor, complete);
623 }
624 
GetController(napi_env env,napi_callback_info info)625 napi_value NapiAVSession::GetController(napi_env env, napi_callback_info info)
626 {
627     struct ConcreteContext : public ContextBase {
628         std::shared_ptr<AVSessionController> controller_;
629     };
630     auto context = std::make_shared<ConcreteContext>();
631     if (context == nullptr) {
632         SLOGE("GetController failed : no memory");
633         NapiUtils::ThrowError(env, "GetController failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
634         return NapiUtils::GetUndefinedValue(env);
635     }
636 
637     context->GetCbInfo(env, info);
638 
639     auto executor = [context]() {
640         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
641         if (napiSession->session_ == nullptr) {
642             context->status = napi_generic_failure;
643             context->errMessage = "GetController failed : session is nullptr";
644             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
645             return;
646         }
647         context->controller_ = napiSession->session_->GetController();
648         if (context->controller_ == nullptr) {
649             context->status = napi_generic_failure;
650             context->errMessage = "GetController failed : native get controller failed";
651             context->errCode = NapiAVSessionManager::errcode_[AVSESSION_ERROR];
652         }
653     };
654     auto complete = [env, context](napi_value& output) {
655         CHECK_STATUS_RETURN_VOID(context, "get controller failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
656         CHECK_ARGS_RETURN_VOID(context, context->controller_ != nullptr, "controller is nullptr",
657             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
658         context->status = NapiAVSessionController::NewInstance(env, context->controller_, output);
659         CHECK_STATUS_RETURN_VOID(context, "convert native object to js object failed",
660             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
661     };
662     return NapiAsyncWork::Enqueue(env, context, "GetController", executor, complete);
663 }
664 
GetAVCastController(napi_env env,napi_callback_info info)665 napi_value NapiAVSession::GetAVCastController(napi_env env, napi_callback_info info)
666 {
667 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
668     struct ConcreteContext : public ContextBase {
669         std::shared_ptr<AVCastController> castController_;
670     };
671     auto context = std::make_shared<ConcreteContext>();
672     if (context == nullptr) {
673         SLOGE("GetAVCastController failed : no memory");
674         NapiUtils::ThrowError(env, "GetAVCastController failed : no memory",
675             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
676         return NapiUtils::GetUndefinedValue(env);
677     }
678 
679     context->GetCbInfo(env, info);
680 
681     auto executor = [context]() {
682         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
683         if (napiSession->session_ == nullptr) {
684             context->status = napi_generic_failure;
685             context->errMessage = "GetAVCastController failed : session is nullptr";
686             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
687             return;
688         }
689         context->castController_ = napiSession->session_->GetAVCastController();
690         if (context->castController_ == nullptr) {
691             context->status = napi_generic_failure;
692             context->errMessage = "GetAVCastController failed : native get controller failed";
693             context->errCode = NapiAVSessionManager::errcode_[AVSESSION_ERROR];
694         }
695     };
696     auto complete = [env, context](napi_value& output) {
697         CHECK_STATUS_RETURN_VOID(context, "get controller failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
698         CHECK_ARGS_RETURN_VOID(context, context->castController_ != nullptr, "controller is nullptr",
699             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
700         context->status = NapiAVCastController::NewInstance(env, context->castController_, output);
701         CHECK_STATUS_RETURN_VOID(context, "convert native object to js object failed",
702             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
703     };
704     return NapiAsyncWork::Enqueue(env, context, "GetAVCastController", executor, complete);
705 #else
706     return nullptr;
707 #endif
708 }
709 
GetOutputDevice(napi_env env,napi_callback_info info)710 napi_value NapiAVSession::GetOutputDevice(napi_env env, napi_callback_info info)
711 {
712     struct ConcreteContext : public ContextBase {
713         OutputDeviceInfo outputDeviceInfo_;
714     };
715     auto context = std::make_shared<ConcreteContext>();
716     if (context == nullptr) {
717         SLOGE("GetOutputDevice failed : no memory");
718         NapiUtils::ThrowError(env, "GetOutputDevice failed : no memory",
719             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
720         return NapiUtils::GetUndefinedValue(env);
721     }
722 
723     context->GetCbInfo(env, info);
724 
725     auto executor = [context]() {
726         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
727         if (napiSession->session_ == nullptr) {
728             context->status = napi_generic_failure;
729             context->errMessage = "GetOutputDevice failed : session is nullptr";
730             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
731             return;
732         }
733         AVSessionDescriptor descriptor;
734         AVSessionManager::GetInstance().GetSessionDescriptorsBySessionId(napiSession->session_->GetSessionId(),
735                                                                          descriptor);
736         context->outputDeviceInfo_ = descriptor.outputDeviceInfo_;
737     };
738 
739     auto complete = [env, context](napi_value& output) {
740         context->status = NapiUtils::SetValue(env, context->outputDeviceInfo_, output);
741         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
742             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
743     };
744     return NapiAsyncWork::Enqueue(env, context, "GetOutputDevice", executor, complete);
745 }
746 
GetOutputDeviceSync(napi_env env,napi_callback_info info)747 napi_value NapiAVSession::GetOutputDeviceSync(napi_env env, napi_callback_info info)
748 {
749     SLOGD("Start GetOutputDeviceSync");
750     auto context = std::make_shared<ContextBase>();
751     if (context == nullptr) {
752         SLOGE("GetOutputDeviceSync failed : no memory");
753         NapiUtils::ThrowError(env, "GetOutputDeviceSync failed : no memory",
754           NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
755         return NapiUtils::GetUndefinedValue(env);
756     }
757 
758     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
759 
760     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
761     if (napiSession->session_ == nullptr) {
762         context->status = napi_generic_failure;
763         context->errMessage = "GetOutputDeviceSync failed : session is nullptr";
764         context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
765         return NapiUtils::GetUndefinedValue(env);
766     }
767 
768     AVSessionDescriptor descriptor;
769     AVSessionManager::GetInstance().GetSessionDescriptorsBySessionId(napiSession->session_->GetSessionId(),
770         descriptor);
771     napi_value output {};
772     auto status = NapiUtils::SetValue(env, descriptor.outputDeviceInfo_, output);
773     if (status != napi_ok) {
774         SLOGE("convert native object to javascript object failed");
775         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
776             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
777         return NapiUtils::GetUndefinedValue(env);
778     }
779     return output;
780 }
781 
Activate(napi_env env,napi_callback_info info)782 napi_value NapiAVSession::Activate(napi_env env, napi_callback_info info)
783 {
784     auto context = std::make_shared<ContextBase>();
785     if (context == nullptr) {
786         SLOGE("Activate failed : no memory");
787         NapiUtils::ThrowError(env, "Activate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
788         return NapiUtils::GetUndefinedValue(env);
789     }
790 
791     context->GetCbInfo(env, info);
792 
793     auto executor = [context]() {
794         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
795         if (napiSession->session_ == nullptr) {
796             context->status = napi_generic_failure;
797             context->errMessage = "Activate session failed : session is nullptr";
798             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
799             return;
800         }
801         int32_t ret = napiSession->session_->Activate();
802         if (ret != AVSESSION_SUCCESS) {
803             if (ret == ERR_SESSION_NOT_EXIST) {
804                 context->errMessage = "Activate session failed : native session not exist";
805             } else if (ret == ERR_NO_PERMISSION) {
806                 context->errMessage = "Activate failed : native no permission";
807             } else {
808                 context->errMessage = "Activate session failed : native server exception";
809             }
810             context->status = napi_generic_failure;
811             context->errCode = NapiAVSessionManager::errcode_[ret];
812         }
813     };
814     auto complete = [env](napi_value& output) {
815         output = NapiUtils::GetUndefinedValue(env);
816     };
817     return NapiAsyncWork::Enqueue(env, context, "Activate", executor, complete);
818 }
819 
Deactivate(napi_env env,napi_callback_info info)820 napi_value NapiAVSession::Deactivate(napi_env env, napi_callback_info info)
821 {
822     auto context = std::make_shared<ContextBase>();
823     if (context == nullptr) {
824         SLOGE("Deactivate failed : no memory");
825         NapiUtils::ThrowError(env, "Deactivate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
826         return NapiUtils::GetUndefinedValue(env);
827     }
828 
829     context->GetCbInfo(env, info);
830 
831     auto executor = [context]() {
832         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
833         if (napiSession->session_ == nullptr) {
834             context->status = napi_generic_failure;
835             context->errMessage = "Deactivate session failed : session is nullptr";
836             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
837             return;
838         }
839         int32_t ret = napiSession->session_->Deactivate();
840         if (ret != AVSESSION_SUCCESS) {
841             if (ret == ERR_SESSION_NOT_EXIST) {
842                 context->errMessage = "Deactivate session failed : native session not exist";
843             } else if (ret == ERR_NO_PERMISSION) {
844                 context->errMessage = "Deactivate failed : native no permission";
845             } else {
846                 context->errMessage = "Deactivate session failed : native server exception";
847             }
848             context->status = napi_generic_failure;
849             context->errCode = NapiAVSessionManager::errcode_[ret];
850         }
851     };
852     auto complete = [env](napi_value& output) {
853         output = NapiUtils::GetUndefinedValue(env);
854     };
855     return NapiAsyncWork::Enqueue(env, context, "Deactivate", executor, complete);
856 }
857 
Destroy(napi_env env,napi_callback_info info)858 napi_value NapiAVSession::Destroy(napi_env env, napi_callback_info info)
859 {
860     auto context = std::make_shared<ContextBase>();
861     if (context == nullptr) {
862         SLOGE("Destroy failed : no memory");
863         NapiUtils::ThrowError(env, "Destroy failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
864         return NapiUtils::GetUndefinedValue(env);
865     }
866 
867     context->GetCbInfo(env, info);
868 
869     auto executor = [context]() {
870         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
871         if (napiSession->session_ == nullptr) {
872             context->status = napi_generic_failure;
873             context->errMessage = "Destroy session failed : session is nullptr";
874             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
875             return;
876         }
877         int32_t ret = napiSession->session_->Destroy();
878         if (ret == AVSESSION_SUCCESS) {
879             napiSession->session_ = nullptr;
880             napiSession->callback_ = nullptr;
881         } else if (ret == ERR_SESSION_NOT_EXIST) {
882             context->status = napi_generic_failure;
883             context->errMessage = "Destroy session failed : native session not exist";
884             context->errCode = NapiAVSessionManager::errcode_[ret];
885         } else if (ret == ERR_NO_PERMISSION) {
886             context->status = napi_generic_failure;
887             context->errMessage = "Destroy failed : native no permission";
888             context->errCode = NapiAVSessionManager::errcode_[ret];
889         } else {
890             context->status = napi_generic_failure;
891             context->errMessage = "Destroy session failed : native server exception";
892             context->errCode = NapiAVSessionManager::errcode_[ret];
893         }
894     };
895     auto complete = [env](napi_value& output) {
896         output = NapiUtils::GetUndefinedValue(env);
897     };
898     return NapiAsyncWork::Enqueue(env, context, "Destroy", executor, complete);
899 }
900 
SetSessionEvent(napi_env env,napi_callback_info info)901 napi_value NapiAVSession::SetSessionEvent(napi_env env, napi_callback_info info)
902 {
903     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetSessionEvent");
904     struct ConcreteContext : public ContextBase {
905         std::string event_;
906         AAFwk::WantParams args_;
907     };
908     auto context = std::make_shared<ConcreteContext>();
909     if (context == nullptr) {
910         SLOGE("SetSessionEvent failed : no memory");
911         NapiUtils::ThrowError(env, "SetSessionEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
912         return NapiUtils::GetUndefinedValue(env);
913     }
914 
915     auto inputParser = [env, context](size_t argc, napi_value* argv) {
916         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid arguments",
917             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
918         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->event_);
919         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get event failed",
920             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
921         context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->args_);
922         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get args failed",
923             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
924     };
925     context->GetCbInfo(env, info, inputParser);
926     context->taskId = NAPI_SET_AV_META_DATA_TASK_ID;
927 
928     auto executor = [context]() {
929         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
930         if (napiSession->session_ == nullptr) {
931             context->status = napi_generic_failure;
932             context->errMessage = "SetSessionEvent failed : session is nullptr";
933             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
934             return;
935         }
936         int32_t ret = napiSession->session_->SetSessionEvent(context->event_, context->args_);
937         if (ret != AVSESSION_SUCCESS) {
938             ErrCodeToMessage(ret, context->errMessage);
939             context->status = napi_generic_failure;
940             context->errCode = NapiAVSessionManager::errcode_[ret];
941         }
942     };
943     auto complete = [env](napi_value& output) {
944         output = NapiUtils::GetUndefinedValue(env);
945     };
946     return NapiAsyncWork::Enqueue(env, context, "SetSessionEvent", executor, complete);
947 }
948 
ReleaseCast(napi_env env,napi_callback_info info)949 napi_value NapiAVSession::ReleaseCast(napi_env env, napi_callback_info info)
950 {
951 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
952     auto context = std::make_shared<ContextBase>();
953     if (context == nullptr) {
954         SLOGE("ReleaseCast failed : no memory");
955         NapiUtils::ThrowError(env, "ReleaseCast failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
956         return NapiUtils::GetUndefinedValue(env);
957     }
958 
959     context->GetCbInfo(env, info);
960 
961     auto executor = [context]() {
962         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
963         if (napiSession->session_ == nullptr) {
964             context->status = napi_generic_failure;
965             context->errMessage = "ReleaseCast failed : session is nullptr";
966             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
967             return;
968         }
969         int32_t ret = napiSession->session_->ReleaseCast();
970         if (ret != AVSESSION_SUCCESS) {
971             if (ret == ERR_SESSION_NOT_EXIST) {
972                 context->errMessage = "ReleaseCast failed : native session not exist";
973             } else if (ret == ERR_NO_PERMISSION) {
974                 context->errMessage = "ReleaseCast failed : native no permission";
975             } else {
976                 context->errMessage = "ReleaseCast failed : native server exception";
977             }
978             context->status = napi_generic_failure;
979             context->errCode = NapiAVSessionManager::errcode_[ret];
980         }
981     };
982     auto complete = [env](napi_value& output) {
983         output = NapiUtils::GetUndefinedValue(env);
984     };
985     return NapiAsyncWork::Enqueue(env, context, "ReleaseCast", executor, complete);
986 #else
987     return nullptr;
988 #endif
989 }
990 
ErrCodeToMessage(int32_t errCode,std::string & message)991 void NapiAVSession::ErrCodeToMessage(int32_t errCode, std::string& message)
992 {
993     switch (errCode) {
994         case ERR_SESSION_NOT_EXIST:
995             message = "SetSessionEvent failed : native session not exist";
996             break;
997         case ERR_INVALID_PARAM:
998             message = "SetSessionEvent failed : native invalid parameters";
999             break;
1000         case ERR_NO_PERMISSION:
1001             message = "SetSessionEvent failed : native no permission";
1002             break;
1003         default:
1004             message = "SetSessionEvent failed : native server exception";
1005             break;
1006     }
1007 }
1008 
OnPlay(napi_env env,NapiAVSession * napiSession,napi_value callback)1009 napi_status NapiAVSession::OnPlay(napi_env env, NapiAVSession* napiSession, napi_value callback)
1010 {
1011     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY);
1012     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1013     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1014         "NapiAVSessionCallback object is nullptr");
1015     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY, callback);
1016 }
1017 
OnPause(napi_env env,NapiAVSession * napiSession,napi_value callback)1018 napi_status NapiAVSession::OnPause(napi_env env, NapiAVSession* napiSession, napi_value callback)
1019 {
1020     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PAUSE);
1021     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1022     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1023         "NapiAVSessionCallback object is nullptr");
1024     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PAUSE, callback);
1025 }
1026 
OnStop(napi_env env,NapiAVSession * napiSession,napi_value callback)1027 napi_status NapiAVSession::OnStop(napi_env env, NapiAVSession* napiSession, napi_value callback)
1028 {
1029     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_STOP);
1030     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1031     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1032         "NapiAVSessionCallback object is nullptr");
1033     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_STOP, callback);
1034 }
1035 
OnPlayNext(napi_env env,NapiAVSession * napiSession,napi_value callback)1036 napi_status NapiAVSession::OnPlayNext(napi_env env, NapiAVSession* napiSession, napi_value callback)
1037 {
1038     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_NEXT);
1039     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1040     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1041         "NapiAVSessionCallback object is nullptr");
1042     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_NEXT, callback);
1043 }
1044 
OnPlayPrevious(napi_env env,NapiAVSession * napiSession,napi_value callback)1045 napi_status NapiAVSession::OnPlayPrevious(napi_env env, NapiAVSession* napiSession, napi_value callback)
1046 {
1047     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS);
1048     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1049     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1050         "NapiAVSessionCallback object is nullptr");
1051     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_PREVIOUS, callback);
1052 }
1053 
OnFastForward(napi_env env,NapiAVSession * napiSession,napi_value callback)1054 napi_status NapiAVSession::OnFastForward(napi_env env, NapiAVSession* napiSession, napi_value callback)
1055 {
1056     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_FAST_FORWARD);
1057     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1058     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1059         "NapiAVSessionCallback object is nullptr");
1060     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_FAST_FORWARD, callback);
1061 }
1062 
OnRewind(napi_env env,NapiAVSession * napiSession,napi_value callback)1063 napi_status NapiAVSession::OnRewind(napi_env env, NapiAVSession* napiSession, napi_value callback)
1064 {
1065     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_REWIND);
1066     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1067     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1068         "NapiAVSessionCallback object is nullptr");
1069     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_REWIND, callback);
1070 }
1071 
OnSeek(napi_env env,NapiAVSession * napiSession,napi_value callback)1072 napi_status NapiAVSession::OnSeek(napi_env env, NapiAVSession* napiSession, napi_value callback)
1073 {
1074     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SEEK);
1075     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1076     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1077         "NapiAVSessionCallback object is nullptr");
1078     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SEEK, callback);
1079 }
1080 
OnSetSpeed(napi_env env,NapiAVSession * napiSession,napi_value callback)1081 napi_status NapiAVSession::OnSetSpeed(napi_env env, NapiAVSession* napiSession, napi_value callback)
1082 {
1083     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SET_SPEED);
1084     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1085     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1086         "NapiAVSessionCallback object is nullptr");
1087     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SET_SPEED, callback);
1088 }
1089 
OnSetLoopMode(napi_env env,NapiAVSession * napiSession,napi_value callback)1090 napi_status NapiAVSession::OnSetLoopMode(napi_env env, NapiAVSession* napiSession, napi_value callback)
1091 {
1092     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
1093     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1094     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1095         "NapiAVSessionCallback object is nullptr");
1096     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SET_LOOP_MODE, callback);
1097 }
1098 
OnToggleFavorite(napi_env env,NapiAVSession * napiSession,napi_value callback)1099 napi_status NapiAVSession::OnToggleFavorite(napi_env env, NapiAVSession* napiSession, napi_value callback)
1100 {
1101     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE);
1102     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1103     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1104         "NapiAVSessionCallback object is nullptr");
1105     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE, callback);
1106 }
1107 
OnMediaKeyEvent(napi_env env,NapiAVSession * napiSession,napi_value callback)1108 napi_status NapiAVSession::OnMediaKeyEvent(napi_env env, NapiAVSession* napiSession, napi_value callback)
1109 {
1110     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1111         "NapiAVSessionCallback object is nullptr");
1112     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT, callback);
1113 }
1114 
OnOutputDeviceChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1115 napi_status NapiAVSession::OnOutputDeviceChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1116 {
1117     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1118         "NapiAVSessionCallback object is nullptr");
1119     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_OUTPUT_DEVICE_CHANGE, callback);
1120 }
1121 
OnCommonCommand(napi_env env,NapiAVSession * napiSession,napi_value callback)1122 napi_status NapiAVSession::OnCommonCommand(napi_env env, NapiAVSession* napiSession, napi_value callback)
1123 {
1124     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SEND_COMMON_COMMAND, callback);
1125 }
1126 
OnSkipToQueueItem(napi_env env,NapiAVSession * napiSession,napi_value callback)1127 napi_status NapiAVSession::OnSkipToQueueItem(napi_env env, NapiAVSession* napiSession, napi_value callback)
1128 {
1129     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SKIP_TO_QUEUE_ITEM, callback);
1130 }
1131 
OffPlay(napi_env env,NapiAVSession * napiSession,napi_value callback)1132 napi_status NapiAVSession::OffPlay(napi_env env, NapiAVSession* napiSession, napi_value callback)
1133 {
1134     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1135         "NapiAVSessionCallback object is nullptr");
1136     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY, callback);
1137     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1138     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY)) {
1139         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY);
1140         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1141     }
1142     return napi_ok;
1143 }
1144 
OffPause(napi_env env,NapiAVSession * napiSession,napi_value callback)1145 napi_status NapiAVSession::OffPause(napi_env env, NapiAVSession* napiSession, napi_value callback)
1146 {
1147     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1148         "NapiAVSessionCallback object is nullptr");
1149     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PAUSE, callback);
1150     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1151     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PAUSE)) {
1152         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PAUSE);
1153         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1154     }
1155     return napi_ok;
1156 }
1157 
OffStop(napi_env env,NapiAVSession * napiSession,napi_value callback)1158 napi_status NapiAVSession::OffStop(napi_env env, NapiAVSession* napiSession, napi_value callback)
1159 {
1160     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1161         "NapiAVSessionCallback object is nullptr");
1162     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_STOP, callback);
1163     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1164     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_STOP)) {
1165         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_STOP);
1166         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1167     }
1168     return napi_ok;
1169 }
1170 
OffPlayNext(napi_env env,NapiAVSession * napiSession,napi_value callback)1171 napi_status NapiAVSession::OffPlayNext(napi_env env, NapiAVSession* napiSession, napi_value callback)
1172 {
1173     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1174         "NapiAVSessionCallback object is nullptr");
1175     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_NEXT, callback);
1176     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1177     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_NEXT)) {
1178         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_NEXT);
1179         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1180     }
1181     return napi_ok;
1182 }
1183 
OffPlayPrevious(napi_env env,NapiAVSession * napiSession,napi_value callback)1184 napi_status NapiAVSession::OffPlayPrevious(napi_env env, NapiAVSession* napiSession, napi_value callback)
1185 {
1186     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1187         "NapiAVSessionCallback object is nullptr");
1188     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_PREVIOUS, callback);
1189     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1190 
1191     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_PREVIOUS)) {
1192         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS);
1193         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1194     }
1195     return napi_ok;
1196 }
1197 
OffFastForward(napi_env env,NapiAVSession * napiSession,napi_value callback)1198 napi_status NapiAVSession::OffFastForward(napi_env env, NapiAVSession* napiSession, napi_value callback)
1199 {
1200     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1201         "NapiAVSessionCallback object is nullptr");
1202     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_FAST_FORWARD, callback);
1203     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1204     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_FAST_FORWARD)) {
1205         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_FAST_FORWARD);
1206         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1207     }
1208     return napi_ok;
1209 }
1210 
OffRewind(napi_env env,NapiAVSession * napiSession,napi_value callback)1211 napi_status NapiAVSession::OffRewind(napi_env env, NapiAVSession* napiSession, napi_value callback)
1212 {
1213     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1214         "NapiAVSessionCallback object is nullptr");
1215     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_REWIND, callback);
1216     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1217     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_REWIND)) {
1218         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_REWIND);
1219         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1220     }
1221     return napi_ok;
1222 }
1223 
OffSeek(napi_env env,NapiAVSession * napiSession,napi_value callback)1224 napi_status NapiAVSession::OffSeek(napi_env env, NapiAVSession* napiSession, napi_value callback)
1225 {
1226     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1227         "NapiAVSessionCallback object is nullptr");
1228     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SEEK, callback);
1229     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1230     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SEEK)) {
1231         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SEEK);
1232         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1233     }
1234     return napi_ok;
1235 }
1236 
OffSetSpeed(napi_env env,NapiAVSession * napiSession,napi_value callback)1237 napi_status NapiAVSession::OffSetSpeed(napi_env env, NapiAVSession* napiSession, napi_value callback)
1238 {
1239     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1240         "NapiAVSessionCallback object is nullptr");
1241     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SET_SPEED, callback);
1242     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1243     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SET_SPEED)) {
1244         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SET_SPEED);
1245         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1246     }
1247     return napi_ok;
1248 }
1249 
OffSetLoopMode(napi_env env,NapiAVSession * napiSession,napi_value callback)1250 napi_status NapiAVSession::OffSetLoopMode(napi_env env, NapiAVSession* napiSession, napi_value callback)
1251 {
1252     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1253         "NapiAVSessionCallback object is nullptr");
1254     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SET_LOOP_MODE, callback);
1255     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1256     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SET_LOOP_MODE)) {
1257         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
1258         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1259     }
1260     return napi_ok;
1261 }
1262 
OffToggleFavorite(napi_env env,NapiAVSession * napiSession,napi_value callback)1263 napi_status NapiAVSession::OffToggleFavorite(napi_env env, NapiAVSession* napiSession, napi_value callback)
1264 {
1265     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1266         "NapiAVSessionCallback object is nullptr");
1267     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE, callback);
1268     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1269     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE)) {
1270         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE);
1271         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1272     }
1273     return napi_ok;
1274 }
1275 
OffMediaKeyEvent(napi_env env,NapiAVSession * napiSession,napi_value callback)1276 napi_status NapiAVSession::OffMediaKeyEvent(napi_env env, NapiAVSession* napiSession, napi_value callback)
1277 {
1278     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1279         "NapiAVSessionCallback object is nullptr");
1280     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT, callback);
1281 }
1282 
OffOutputDeviceChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1283 napi_status NapiAVSession::OffOutputDeviceChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1284 {
1285     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1286         "NapiAVSessionCallback object is nullptr");
1287     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_OUTPUT_DEVICE_CHANGE, callback);
1288 }
1289 
OffCommonCommand(napi_env env,NapiAVSession * napiSession,napi_value callback)1290 napi_status NapiAVSession::OffCommonCommand(napi_env env, NapiAVSession* napiSession, napi_value callback)
1291 {
1292     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SEND_COMMON_COMMAND, callback);
1293 }
1294 
OffSkipToQueueItem(napi_env env,NapiAVSession * napiSession,napi_value callback)1295 napi_status NapiAVSession::OffSkipToQueueItem(napi_env env, NapiAVSession* napiSession, napi_value callback)
1296 {
1297     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1298         "NapiAVSessionCallback object is nullptr");
1299     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SKIP_TO_QUEUE_ITEM, callback);
1300 }
1301 }
1302