• 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 <cstdio>
17 
18 #include "napi_avsession.h"
19 #include "avsession_controller.h"
20 #include "napi_utils.h"
21 #include "napi_avcall_meta_data.h"
22 #include "napi_avcall_state.h"
23 #include "napi_meta_data.h"
24 #include "napi_playback_state.h"
25 #include "napi_media_description.h"
26 #include "napi_queue_item.h"
27 #include "want_params.h"
28 #include "want_agent.h"
29 #include "avsession_trace.h"
30 #include "napi_avsession_controller.h"
31 #include "napi_avsession_manager.h"
32 #include "curl/curl.h"
33 #include "image_source.h"
34 #include "pixel_map.h"
35 #include "avsession_pixel_map_adapter.h"
36 
37 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
38 #include "avcast_controller.h"
39 #include "napi_avcast_controller.h"
40 #endif
41 namespace OHOS::AVSession {
42 
43 static __thread napi_ref AVSessionConstructorRef = nullptr;
44 std::map<std::string, NapiAVSession::OnEventHandlerType> NapiAVSession::onEventHandlers_ = {
45     { "play", OnPlay },
46     { "pause", OnPause },
47     { "stop", OnStop },
48     { "playNext", OnPlayNext },
49     { "playPrevious", OnPlayPrevious },
50     { "fastForward", OnFastForward },
51     { "rewind", OnRewind },
52     { "seek", OnSeek },
53     { "setSpeed", OnSetSpeed },
54     { "setLoopMode", OnSetLoopMode },
55     { "toggleFavorite", OnToggleFavorite },
56     { "handleKeyEvent", OnMediaKeyEvent },
57     { "outputDeviceChange", OnOutputDeviceChange },
58     { "commonCommand", OnCommonCommand },
59     { "skipToQueueItem", OnSkipToQueueItem },
60     { "answer", OnAVCallAnswer },
61     { "hangUp", OnAVCallHangUp },
62     { "toggleCallMute", OnAVCallToggleCallMute },
63     { "playFromAssetId", OnPlayFromAssetId },
64     { "castDisplayChange", OnCastDisplayChange },
65 };
66 std::map<std::string, NapiAVSession::OffEventHandlerType> NapiAVSession::offEventHandlers_ = {
67     { "play", OffPlay },
68     { "pause", OffPause },
69     { "stop", OffStop },
70     { "playNext", OffPlayNext },
71     { "playPrevious", OffPlayPrevious },
72     { "fastForward", OffFastForward },
73     { "rewind", OffRewind },
74     { "seek", OffSeek },
75     { "setSpeed", OffSetSpeed },
76     { "setLoopMode", OffSetLoopMode },
77     { "toggleFavorite", OffToggleFavorite },
78     { "handleKeyEvent", OffMediaKeyEvent },
79     { "outputDeviceChange", OffOutputDeviceChange },
80     { "commonCommand", OffCommonCommand },
81     { "skipToQueueItem", OffSkipToQueueItem },
82     { "answer", OffAVCallAnswer },
83     { "hangUp", OffAVCallHangUp },
84     { "toggleCallMute", OffAVCallToggleCallMute },
85     { "playFromAssetId", OffPlayFromAssetId },
86     { "castDisplayChange", OffCastDisplayChange },
87 };
88 std::mutex NapiAVSession::syncMutex_;
89 std::mutex NapiAVSession::syncAsyncMutex_;
90 std::condition_variable NapiAVSession::syncCond_;
91 std::condition_variable NapiAVSession::syncAsyncCond_;
92 int32_t NapiAVSession::playBackStateRet_ = AVSESSION_ERROR;
93 
NapiAVSession()94 NapiAVSession::NapiAVSession()
95 {
96     SLOGI("construct");
97 }
98 
~NapiAVSession()99 NapiAVSession::~NapiAVSession()
100 {
101     SLOGI("destroy");
102 }
103 
Init(napi_env env,napi_value exports)104 napi_value NapiAVSession::Init(napi_env env, napi_value exports)
105 {
106     napi_property_descriptor descriptors[] = {
107         DECLARE_NAPI_FUNCTION("setAVMetadata", SetAVMetaData),
108         DECLARE_NAPI_FUNCTION("setCallMetadata", SetAVCallMetaData),
109         DECLARE_NAPI_FUNCTION("setAVPlaybackState", SetAVPlaybackState),
110         DECLARE_NAPI_FUNCTION("setAVCallState", SetAVCallState),
111         DECLARE_NAPI_FUNCTION("setLaunchAbility", SetLaunchAbility),
112         DECLARE_NAPI_FUNCTION("setExtras", SetExtras),
113         DECLARE_NAPI_FUNCTION("setAudioStreamId", SetAudioStreamId),
114         DECLARE_NAPI_FUNCTION("getController", GetController),
115         DECLARE_NAPI_FUNCTION("activate", Activate),
116         DECLARE_NAPI_FUNCTION("deactivate", Deactivate),
117         DECLARE_NAPI_FUNCTION("destroy", Destroy),
118         DECLARE_NAPI_FUNCTION("on", OnEvent),
119         DECLARE_NAPI_FUNCTION("off", OffEvent),
120         DECLARE_NAPI_FUNCTION("getOutputDevice", GetOutputDevice),
121         DECLARE_NAPI_FUNCTION("getOutputDeviceSync", GetOutputDeviceSync),
122         DECLARE_NAPI_FUNCTION("dispatchSessionEvent", SetSessionEvent),
123         DECLARE_NAPI_FUNCTION("setAVQueueItems", SetAVQueueItems),
124         DECLARE_NAPI_FUNCTION("setAVQueueTitle", SetAVQueueTitle),
125         DECLARE_NAPI_FUNCTION("getAVCastController", GetAVCastController),
126         DECLARE_NAPI_FUNCTION("stopCasting", ReleaseCast),
127         DECLARE_NAPI_FUNCTION("getAllCastDisplays", GetAllCastDisplays),
128     };
129     auto propertyCount = sizeof(descriptors) / sizeof(napi_property_descriptor);
130     napi_value constructor {};
131     auto status = napi_define_class(env, "AVSession", NAPI_AUTO_LENGTH, ConstructorCallback, nullptr,
132                                     propertyCount, descriptors, &constructor);
133     if (status != napi_ok) {
134         SLOGE("define class failed");
135         return NapiUtils::GetUndefinedValue(env);
136     }
137     napi_create_reference(env, constructor, 1, &AVSessionConstructorRef);
138     return exports;
139 }
140 
ConstructorCallback(napi_env env,napi_callback_info info)141 napi_value NapiAVSession::ConstructorCallback(napi_env env, napi_callback_info info)
142 {
143     napi_value self;
144     NAPI_CALL_BASE(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr), nullptr);
145     auto finalize = [](napi_env env, void* data, void* hint) {
146         auto* napiSession = reinterpret_cast<NapiAVSession*>(data);
147         napi_delete_reference(env, napiSession->wrapperRef_);
148         delete napiSession;
149         napiSession = nullptr;
150     };
151     auto* napiSession = new(std::nothrow) NapiAVSession();
152     if (napiSession == nullptr) {
153         SLOGE("no memory");
154         return nullptr;
155     }
156     if (napi_wrap(env, self, static_cast<void*>(napiSession), finalize, nullptr, nullptr) != napi_ok) {
157         SLOGE("wrap failed");
158         return nullptr;
159     }
160     return self;
161 }
162 
NewInstance(napi_env env,std::shared_ptr<AVSession> & nativeSession,napi_value & out)163 napi_status NapiAVSession::NewInstance(napi_env env, std::shared_ptr<AVSession>& nativeSession, napi_value& out)
164 {
165     napi_value constructor {};
166     NAPI_CALL_BASE(env, napi_get_reference_value(env, AVSessionConstructorRef, &constructor), napi_generic_failure);
167     napi_value instance{};
168     NAPI_CALL_BASE(env, napi_new_instance(env, constructor, 0, nullptr, &instance), napi_generic_failure);
169     NapiAVSession* napiAvSession{};
170     NAPI_CALL_BASE(env, napi_unwrap(env, instance, reinterpret_cast<void**>(&napiAvSession)), napi_generic_failure);
171     napiAvSession->session_ = std::move(nativeSession);
172     napiAvSession->sessionId_ = napiAvSession->session_->GetSessionId();
173     napiAvSession->sessionType_ = napiAvSession->session_->GetSessionType();
174     SLOGI("sessionId=%{public}s, sessionType:%{public}s", napiAvSession->sessionId_.c_str(),
175         napiAvSession->sessionType_.c_str());
176 
177     napi_value property {};
178     auto status = NapiUtils::SetValue(env, napiAvSession->sessionId_, property);
179     CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
180     NAPI_CALL_BASE(env, napi_set_named_property(env, instance, "sessionId", property), napi_generic_failure);
181 
182     status = NapiUtils::SetValue(env, napiAvSession->sessionType_, property);
183     CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
184     NAPI_CALL_BASE(env, napi_set_named_property(env, instance, "sessionType", property), napi_generic_failure);
185     out = instance;
186     return napi_ok;
187 }
188 
OnEvent(napi_env env,napi_callback_info info)189 napi_value NapiAVSession::OnEvent(napi_env env, napi_callback_info info)
190 {
191     auto context = std::make_shared<ContextBase>();
192     if (context == nullptr) {
193         SLOGE("OnEvent failed : no memory");
194         return ThrowErrorAndReturn(env, "OnEvent failed : no memory", ERR_NO_MEMORY);
195     }
196     std::string eventName;
197     napi_value callback {};
198     auto input = [&eventName, &callback, env, &context](size_t argc, napi_value* argv) {
199         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid argument number",
200             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
201         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
202         CHECK_STATUS_RETURN_VOID(context, "get event name failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
203         napi_valuetype type = napi_undefined;
204         context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
205         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
206                                "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
207         callback = argv[ARGV_SECOND];
208     };
209     context->GetCbInfo(env, info, input, true);
210     if (context->status != napi_ok) {
211         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
212         return NapiUtils::GetUndefinedValue(env);
213     }
214     auto it = onEventHandlers_.find(eventName);
215     if (it == onEventHandlers_.end()) {
216         SLOGE("event name invalid");
217         return ThrowErrorAndReturn(env, "event name invalid", ERR_INVALID_PARAM);
218     }
219     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
220     if (napiSession->session_ == nullptr) {
221         SLOGE("OnEvent failed : session is nullptr");
222         return ThrowErrorAndReturn(env, "OnEvent failed : session is nullptr", ERR_SESSION_NOT_EXIST);
223     }
224     if (napiSession->callback_ == nullptr) {
225         napiSession->callback_ = std::make_shared<NapiAVSessionCallback>();
226         if (napiSession->callback_ == nullptr) {
227             SLOGE("OnEvent failed : no memory");
228             return ThrowErrorAndReturn(env, "OnEvent failed : no memory", ERR_NO_MEMORY);
229         }
230         int32_t ret = napiSession->session_->RegisterCallback(napiSession->callback_);
231         if (ret != AVSESSION_SUCCESS) {
232             return ThrowErrorAndReturnByErrCode(env, "OnEvent", ret);
233         }
234     }
235     if (it->second(env, napiSession, callback) != napi_ok) {
236         NapiUtils::ThrowError(env, "add event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
237     }
238     return NapiUtils::GetUndefinedValue(env);
239 }
240 
ThrowErrorAndReturn(napi_env env,const std::string & message,int32_t errCode)241 napi_value NapiAVSession::ThrowErrorAndReturn(napi_env env, const std::string& message, int32_t errCode)
242 {
243     std::string tempMessage = message;
244     NapiUtils::ThrowError(env, tempMessage.c_str(), NapiAVSessionManager::errcode_[errCode]);
245     return NapiUtils::GetUndefinedValue(env);
246 }
247 
ThrowErrorAndReturnByErrCode(napi_env env,const std::string & message,int32_t errCode)248 napi_value NapiAVSession::ThrowErrorAndReturnByErrCode(napi_env env, const std::string& message, int32_t errCode)
249 {
250     std::string tempMessage = message;
251     if (errCode == ERR_SESSION_NOT_EXIST) {
252         tempMessage.append(" failed : native session not exist");
253     } else if (errCode == ERR_INVALID_PARAM) {
254         tempMessage.append(" failed : native invalid parameters");
255     } else if (errCode == ERR_NO_PERMISSION) {
256         tempMessage.append(" failed : native no permission");
257     } else {
258         tempMessage.append(" failed : native server exception");
259     }
260     SLOGI("throw error message: %{public}s", tempMessage.c_str());
261     NapiUtils::ThrowError(env, tempMessage.c_str(), NapiAVSessionManager::errcode_[errCode]);
262     return NapiUtils::GetUndefinedValue(env);
263 }
264 
OffEvent(napi_env env,napi_callback_info info)265 napi_value NapiAVSession::OffEvent(napi_env env, napi_callback_info info)
266 {
267     auto context = std::make_shared<ContextBase>();
268     if (context == nullptr) {
269         SLOGE("OffEvent failed : no memory");
270         NapiUtils::ThrowError(env, "OffEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
271         return NapiUtils::GetUndefinedValue(env);
272     }
273     std::string eventName;
274     napi_value callback = nullptr;
275     auto input = [&eventName, env, &context, &callback](size_t argc, napi_value* argv) {
276         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE || argc == ARGC_TWO,
277                                "invalid argument number", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
278         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
279         CHECK_STATUS_RETURN_VOID(context, "get event name failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
280         if (argc == ARGC_TWO) {
281             callback = argv[ARGV_SECOND];
282         }
283     };
284     context->GetCbInfo(env, info, input, true);
285     if (context->status != napi_ok) {
286         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
287         return NapiUtils::GetUndefinedValue(env);
288     }
289     auto it = offEventHandlers_.find(eventName);
290     if (it == offEventHandlers_.end()) {
291         SLOGE("event name invalid");
292         NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
293         return NapiUtils::GetUndefinedValue(env);
294     }
295     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
296     if (napiSession == nullptr) {
297         SLOGE("OffEvent failed : napiSession is nullptr");
298         NapiUtils::ThrowError(env, "OffEvent failed : napiSession is nullptr",
299             NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST]);
300         return NapiUtils::GetUndefinedValue(env);
301     }
302     if (napiSession->session_ == nullptr) {
303         SLOGE("OffEvent failed : session is nullptr");
304         NapiUtils::ThrowError(env, "OffEvent failed : session is nullptr",
305             NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST]);
306         return NapiUtils::GetUndefinedValue(env);
307     }
308     if (napiSession != nullptr && it->second(env, napiSession, callback) != napi_ok) {
309         NapiUtils::ThrowError(env, "remove event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
310     }
311     return NapiUtils::GetUndefinedValue(env);
312 }
313 
SetAVCallMetaData(napi_env env,napi_callback_info info)314 napi_value NapiAVSession::SetAVCallMetaData(napi_env env, napi_callback_info info)
315 {
316     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVCallMetadata");
317     struct ConcreteContext : public ContextBase {
318         AVCallMetaData avCallMetaData;
319     };
320     auto context = std::make_shared<ConcreteContext>();
321     if (context == nullptr) {
322         SLOGE("SetAVCallMetaData failed : no memory");
323         NapiUtils::ThrowError(env, "SetAVCallMetaData failed : no memory",
324             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
325         return NapiUtils::GetUndefinedValue(env);
326     }
327 
328     auto inputParser = [env, context](size_t argc, napi_value* argv) {
329         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
330             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
331         context->status = NapiAVCallMetaData::GetValue(env, argv[ARGV_FIRST], context->avCallMetaData);
332         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get av call meta data failed",
333             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
334     };
335     context->GetCbInfo(env, info, inputParser);
336     context->taskId = NAPI_SET_AVCALL_META_DATA_TASK_ID;
337 
338     auto executor = [context]() {
339         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
340         if (napiSession->session_ == nullptr) {
341             context->status = napi_generic_failure;
342             context->errMessage = "SetAVCallMetaData failed : session is nullptr";
343             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
344             return;
345         }
346         int32_t ret = napiSession->session_->SetAVCallMetaData(context->avCallMetaData);
347         if (ret != AVSESSION_SUCCESS) {
348             if (ret == ERR_SESSION_NOT_EXIST) {
349                 context->errMessage = "SetAVCallMetaData failed : native session not exist";
350             } else if (ret == ERR_INVALID_PARAM) {
351                 context->errMessage = "SetAVCallMetaData failed : native invalid parameters";
352             } else if (ret == ERR_NO_PERMISSION) {
353                 context->errMessage = "SetAVCallMetaData failed : native no permission";
354             } else {
355                 context->errMessage = "SetAVCallMetaData failed : native server exception";
356             }
357             context->status = napi_generic_failure;
358             context->errCode = NapiAVSessionManager::errcode_[ret];
359         }
360     };
361     auto complete = [env](napi_value& output) {
362         output = NapiUtils::GetUndefinedValue(env);
363     };
364     return NapiAsyncWork::Enqueue(env, context, "SetAVCallMetaData", executor, complete);
365 }
366 
SetAVCallState(napi_env env,napi_callback_info info)367 napi_value NapiAVSession::SetAVCallState(napi_env env, napi_callback_info info)
368 {
369     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVCallState");
370     struct ConcreteContext : public ContextBase {
371         AVCallState avCallState;
372     };
373     auto context = std::make_shared<ConcreteContext>();
374     if (context == nullptr) {
375         SLOGE("SetAVCallState failed : no memory");
376         NapiUtils::ThrowError(env, "SetAVCallState failed : no memory",
377                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
378         return NapiUtils::GetUndefinedValue(env);
379     }
380 
381     auto inputParser = [env, context](size_t argc, napi_value* argv) {
382         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
383             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
384         context->status = NapiAVCallState::GetValue(env, argv[ARGV_FIRST], context->avCallState);
385         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get avCallState failed",
386             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
387     };
388     context->GetCbInfo(env, info, inputParser);
389     context->taskId = NAPI_SET_AV_CALL_STATE_TASK_ID;
390 
391     auto executor = [context]() {
392         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
393         if (napiSession->session_ == nullptr) {
394             context->status = napi_generic_failure;
395             context->errMessage = "SetAVCallState failed : session is nullptr";
396             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
397             return;
398         }
399         int32_t ret = napiSession->session_->SetAVCallState(context->avCallState);
400         if (ret != AVSESSION_SUCCESS) {
401             if (ret == ERR_SESSION_NOT_EXIST) {
402                 context->errMessage = "SetAVCallState failed : native session not exist";
403             } else if (ret == ERR_INVALID_PARAM) {
404                 context->errMessage = "SetAVCallState failed : native invalid parameters";
405             } else if (ret == ERR_NO_PERMISSION) {
406                 context->errMessage = "SetAVCallState failed : native no permission";
407             } else {
408                 context->errMessage = "SetAVCallState failed : native server exception";
409             }
410             context->status = napi_generic_failure;
411             context->errCode = NapiAVSessionManager::errcode_[ret];
412         }
413     };
414     auto complete = [env](napi_value& output) {
415         output = NapiUtils::GetUndefinedValue(env);
416     };
417     return NapiAsyncWork::Enqueue(env, context, "SetAVCallState", executor, complete);
418 }
419 
DoDownload(AVMetaData & meta,const std::string uri)420 int32_t DoDownload(AVMetaData& meta, const std::string uri)
421 {
422     SLOGI("DoDownload with title %{public}s", meta.GetTitle().c_str());
423 
424     std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
425     bool ret = NapiUtils::DoDownloadInCommon(pixelMap, uri);
426     SLOGI("DoDownload with ret %{public}d, %{public}d", static_cast<int>(ret), static_cast<int>(pixelMap == nullptr));
427     if (ret && pixelMap != nullptr) {
428         SLOGI("DoDownload success and reset meta except assetId but not, wait for mediacontrol fix");
429         meta.SetMediaImage(AVSessionPixelMapAdapter::ConvertToInner(pixelMap));
430         return AVSESSION_SUCCESS;
431     }
432     return AVSESSION_ERROR;
433 }
434 
processErrMsg(std::shared_ptr<ContextBase> context,int32_t ret)435 void processErrMsg(std::shared_ptr<ContextBase> context, int32_t ret)
436 {
437     if (ret == ERR_SESSION_NOT_EXIST) {
438         context->errMessage = "SetAVMetaData failed : native session not exist";
439     } else if (ret == ERR_INVALID_PARAM) {
440         context->errMessage = "SetAVMetaData failed : native invalid parameters";
441     } else if (ret == ERR_NO_PERMISSION) {
442         context->errMessage = "SetAVMetaData failed : native no permission";
443     } else {
444         context->errMessage = "SetAVMetaData failed : native server exception";
445     }
446     context->status = napi_generic_failure;
447     context->errCode = NapiAVSessionManager::errcode_[ret];
448 }
449 
doMetaDataSetNapi(std::shared_ptr<ContextBase> context,std::shared_ptr<AVSession> sessionPtr,AVMetaData & data,bool isRepeatDownload)450 bool doMetaDataSetNapi(std::shared_ptr<ContextBase> context, std::shared_ptr<AVSession> sessionPtr, AVMetaData& data,
451     bool isRepeatDownload)
452 {
453     SLOGI("do metadata set with check uri alive:%{public}d, pixel alive:%{public}d, session alive:%{public}d",
454         static_cast<int>(!data.GetMediaImageUri().empty()),
455         static_cast<int>(data.GetMediaImage() != nullptr),
456         static_cast<int>(sessionPtr != nullptr));
457     if (sessionPtr == nullptr) {
458         context->status = napi_generic_failure;
459         context->errMessage = "SetAVMetaData failed : session is nullptr";
460         context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
461         return false;
462     }
463     auto uri = data.GetMediaImageUri();
464     int32_t ret = sessionPtr->SetAVMetaData(data);
465     if (ret != AVSESSION_SUCCESS) {
466         SLOGE("do metadata set fail, ret:%{public}d", ret);
467         processErrMsg(context, ret);
468     } else if (data.GetMediaImageUri().empty()) {
469         SLOGE("do metadata set with img uri empty");
470     } else if (isRepeatDownload) {
471         SLOGE("do metadata set with repeat uriSize:%{public}d.", static_cast<int>(uri.size()));
472     } else if (data.GetMediaImage() == nullptr) {
473         ret = DoDownload(data, uri);
474         SLOGI("DoDownload uriSize%{public}d complete with ret %{public}d", static_cast<int>(uri.size()), ret);
475         CHECK_AND_RETURN_RET_LOG(sessionPtr != nullptr, false, "doMetaDataSet without session");
476         if (ret != AVSESSION_SUCCESS) {
477             SLOGE("DoDownload failed but not repeat setmetadata again");
478         } else {
479             return true;
480         }
481     }
482     return false;
483 }
484 
SetAVMetaData(napi_env env,napi_callback_info info)485 napi_value NapiAVSession::SetAVMetaData(napi_env env, napi_callback_info info)
486 {
487     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVMetadata");
488     struct ConcreteContext : public ContextBase {
489         AVMetaData metaData;
490         std::chrono::system_clock::time_point metadataTs;
491     };
492     auto context = std::make_shared<ConcreteContext>();
493     CHECK_AND_RETURN_RET_LOG(context != nullptr, NapiUtils::GetUndefinedValue(env), "SetAVMetaData failed: no memory");
494     auto inputParser = [env, context](size_t argc, napi_value* argv) {
495         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
496             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
497         context->status = NapiMetaData::GetValue(env, argv[ARGV_FIRST], context->metaData);
498         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get metaData failed",
499             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
500     };
501     context->GetCbInfo(env, info, inputParser);
502     auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
503     auto* napiAvSession = reinterpret_cast<NapiAVSession*>(context->native);
504     if (napiAvSession == nullptr || napiAvSession->metaData_.EqualWithUri((context->metaData))) {
505         SLOGI("Session nullptr or metadata all same");
506         auto executor = []() {};
507         return NapiAsyncWork::Enqueue(env, context, "SetAVMetaData", executor, complete);
508     }
509     napiAvSession->metaData_ = context->metaData;
510     context->taskId = NAPI_SET_AV_META_DATA_TASK_ID;
511     if (napiAvSession->latestMetadataUri_ != napiAvSession->metaData_.GetMediaImageUri() ||
512         !napiAvSession->metaData_.GetMediaImageUri().empty() || napiAvSession->metaData_.GetMediaImage() != nullptr) {
513         context->metadataTs = std::chrono::system_clock::now();
514         napiAvSession->latestMetadataUri_ = napiAvSession->metaData_.GetMediaImageUri();
515         reinterpret_cast<NapiAVSession*>(context->native)->latestMetadataTs_ = context->metadataTs;
516     }
517     auto executor = [context]() {
518         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
519         bool isRepeatDownload = napiSession->latestDownloadedUri_ == napiSession->latestMetadataUri_;
520         bool res = doMetaDataSetNapi(context, napiSession->session_, context->metaData, isRepeatDownload);
521         bool timeAvailable = context->metadataTs >= napiSession->latestMetadataTs_;
522         SLOGI("doMetaDataSet res:%{public}d, time:%{public}d", static_cast<int>(res), static_cast<int>(timeAvailable));
523         if (res && timeAvailable && napiSession->session_ != nullptr) {
524             napiSession->latestDownloadedUri_ = context->metaData.GetMediaImageUri();
525             napiSession->session_->SetAVMetaData(context->metaData);
526         }
527         context->metaData.Reset();
528     };
529     return NapiAsyncWork::Enqueue(env, context, "SetAVMetaData", executor, complete);
530 }
531 
PlaybackStateSyncExecutor(NapiAVSession * napiSession,AVPlaybackState playBackState)532 std::function<void()> NapiAVSession::PlaybackStateSyncExecutor(NapiAVSession* napiSession,
533     AVPlaybackState playBackState)
534 {
535     return [napiSession, playBackState]() {
536         if (napiSession->session_ == nullptr) {
537             playBackStateRet_ = ERR_SESSION_NOT_EXIST;
538             return;
539         }
540         playBackStateRet_ = napiSession->session_->SetAVPlaybackState(playBackState);
541         syncCond_.notify_one();
542         std::unique_lock<std::mutex> lock(syncAsyncMutex_);
543         auto waitStatus = syncAsyncCond_.wait_for(lock, std::chrono::milliseconds(100));
544         if (waitStatus == std::cv_status::timeout) {
545             SLOGE("SetAVPlaybackState in syncExecutor timeout");
546             return;
547         }
548     };
549 }
550 
PlaybackStateAsyncExecutor(std::shared_ptr<ContextBase> context)551 std::function<void()> NapiAVSession::PlaybackStateAsyncExecutor(std::shared_ptr<ContextBase> context)
552 {
553     return [context]() {
554         std::unique_lock<std::mutex> lock(syncMutex_);
555         auto waitStatus = syncCond_.wait_for(lock, std::chrono::milliseconds(100));
556         if (waitStatus == std::cv_status::timeout) {
557             SLOGE("SetAVPlaybackState in asyncExecutor timeout");
558             return;
559         }
560 
561         if (playBackStateRet_ != AVSESSION_SUCCESS) {
562             if (playBackStateRet_ == ERR_SESSION_NOT_EXIST) {
563                 context->errMessage = "SetAVPlaybackState failed : native session not exist";
564             } else if (playBackStateRet_ == ERR_INVALID_PARAM) {
565                 context->errMessage = "SetAVPlaybackState failed : native invalid parameters";
566             } else if (playBackStateRet_ == ERR_NO_PERMISSION) {
567                 context->errMessage = "SetAVPlaybackState failed : native no permission";
568             } else {
569                 context->errMessage = "SetAVPlaybackState failed : native server exception";
570             }
571             context->status = napi_generic_failure;
572             context->errCode = NapiAVSessionManager::errcode_[playBackStateRet_];
573         }
574         syncAsyncCond_.notify_one();
575     };
576 }
577 
SetAVPlaybackState(napi_env env,napi_callback_info info)578 napi_value NapiAVSession::SetAVPlaybackState(napi_env env, napi_callback_info info)
579 {
580     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVPlaybackState");
581     struct ConcreteContext : public ContextBase {
582         AVPlaybackState playBackState_;
583     };
584     auto context = std::make_shared<ConcreteContext>();
585     if (context == nullptr) {
586         SLOGE("SetAVPlaybackState failed : no memory");
587         NapiUtils::ThrowError(env, "SetAVPlaybackState failed : no memory",
588                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
589         return NapiUtils::GetUndefinedValue(env);
590     }
591 
592     auto inputParser = [env, context](size_t argc, napi_value* argv) {
593         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
594             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
595         context->status = NapiPlaybackState::GetValue(env, argv[ARGV_FIRST], context->playBackState_);
596         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get playBackState failed",
597             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
598     };
599     context->GetCbInfo(env, info, inputParser);
600     context->taskId = NAPI_SET_AV_PLAYBACK_STATE_TASK_ID;
601 
602     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
603     if (napiSession->session_ == nullptr) {
604         SLOGE("SetAVPlaybackState failed : session is nullptr");
605         context->status = napi_generic_failure;
606         context->errMessage = "SetAVPlaybackState failed : session is nullptr";
607         context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
608         auto executor = []() {};
609         auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
610         return NapiAsyncWork::Enqueue(env, context, "SetAVPlaybackState", executor, complete);
611     }
612 
613     auto syncExecutor = PlaybackStateSyncExecutor(napiSession, context->playBackState_);
614     CHECK_AND_PRINT_LOG(AVSessionEventHandler::GetInstance()
615         .AVSessionPostTask(syncExecutor, "SetAVPlaybackState"),
616         "NapiAVSession SetAVPlaybackState handler postTask failed");
617 
618     auto asyncExecutor = PlaybackStateAsyncExecutor(context);
619     auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
620     return NapiAsyncWork::Enqueue(env, context, "SetAVPlayback", asyncExecutor, complete);
621 }
622 
SetAVQueueItems(napi_env env,napi_callback_info info)623 napi_value NapiAVSession::SetAVQueueItems(napi_env env, napi_callback_info info)
624 {
625     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVQueueItems");
626     struct ConcreteContext : public ContextBase { std::vector<AVQueueItem> items_; };
627     auto context = std::make_shared<ConcreteContext>();
628     if (context == nullptr) {
629         NapiUtils::ThrowError(env, "SetAVQueueItems failed : no memory",
630             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
631         return NapiUtils::GetUndefinedValue(env);
632     }
633     auto inputParser = [env, context](size_t argc, napi_value* argv) {
634         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
635             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
636         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->items_);
637         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get queueItems failed",
638             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
639         for (auto &item : context->items_) {
640             CHECK_ARGS_RETURN_VOID(context, item.IsValid(), "invalid queue item content",
641                 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
642         }
643     };
644     context->GetCbInfo(env, info, inputParser);
645     context->taskId = NAPI_SET_AV_QUEUE_ITEMS_TASK_ID;
646     auto executor = [context]() {
647         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
648         if (napiSession->session_ == nullptr) {
649             context->status = napi_generic_failure;
650             context->errMessage = "SetAVQueueItems failed : session is nullptr";
651             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
652             return;
653         }
654         int32_t ret = napiSession->session_->SetAVQueueItems(context->items_);
655         if (ret != AVSESSION_SUCCESS) {
656             if (ret == ERR_SESSION_NOT_EXIST) {
657                 context->errMessage = "SetAVQueueItems failed : native session not exist";
658             } else if (ret == ERR_INVALID_PARAM) {
659                 context->errMessage = "SetAVQueueItems failed : native invalid parameters";
660             } else if (ret == ERR_NO_PERMISSION) {
661                 context->errMessage = "SetAVQueueItems failed : native no permission";
662             } else if (ret == ERR_MARSHALLING) {
663                 context->errMessage = "SetAVQueueItems failed : item number is out of range";
664             } else {
665                 context->errMessage = "SetAVQueueItems failed : native server exception";
666             }
667             context->status = napi_generic_failure;
668             context->errCode = NapiAVSessionManager::errcode_[ret];
669         }
670     };
671     auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
672     return NapiAsyncWork::Enqueue(env, context, "SetAVQueueItems", executor, complete);
673 }
674 
SetAVQueueTitle(napi_env env,napi_callback_info info)675 napi_value NapiAVSession::SetAVQueueTitle(napi_env env, napi_callback_info info)
676 {
677     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVQueueTitle");
678     struct ConcreteContext : public ContextBase {
679         std::string title;
680     };
681     auto context = std::make_shared<ConcreteContext>();
682     if (context == nullptr) {
683         SLOGE("SetAVQueueTitle failed : no memory");
684         NapiUtils::ThrowError(env, "SetAVQueueTitle failed : no memory",
685             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
686         return NapiUtils::GetUndefinedValue(env);
687     }
688 
689     auto inputParser = [env, context](size_t argc, napi_value* argv) {
690         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
691             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
692         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->title);
693         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get queueItems failed",
694             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
695     };
696     context->GetCbInfo(env, info, inputParser);
697     context->taskId = NAPI_SET_AV_QUEUE_TITLE_TASK_ID;
698 
699     auto executor = [context]() {
700         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
701         if (napiSession->session_ == nullptr) {
702             context->status = napi_generic_failure;
703             context->errMessage = "SetAVQueueTitle failed : session is nullptr";
704             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
705             return;
706         }
707         int32_t ret = napiSession->session_->SetAVQueueTitle(context->title);
708         if (ret != AVSESSION_SUCCESS) {
709             if (ret == ERR_SESSION_NOT_EXIST) {
710                 context->errMessage = "SetAVQueueTitle failed : native session not exist";
711             } else if (ret == ERR_INVALID_PARAM) {
712                 context->errMessage = "SetAVQueueTitle failed : native invalid parameters";
713             } else if (ret == ERR_NO_PERMISSION) {
714                 context->errMessage = "SetAVQueueTitle failed : native no permission";
715             } else {
716                 context->errMessage = "SetAVQueueTitle failed : native server exception";
717             }
718             context->status = napi_generic_failure;
719             context->errCode = NapiAVSessionManager::errcode_[ret];
720         }
721     };
722     auto complete = [env](napi_value& output) {
723         output = NapiUtils::GetUndefinedValue(env);
724     };
725     return NapiAsyncWork::Enqueue(env, context, "SetAVQueueTitle", executor, complete);
726 }
727 
SetLaunchAbility(napi_env env,napi_callback_info info)728 napi_value NapiAVSession::SetLaunchAbility(napi_env env, napi_callback_info info)
729 {
730     struct ConcreteContext : public ContextBase {
731         AbilityRuntime::WantAgent::WantAgent* wantAgent_;
732     };
733     auto context = std::make_shared<ConcreteContext>();
734     if (context == nullptr) {
735         SLOGE("SetLaunchAbility failed : no memory");
736         NapiUtils::ThrowError(env, "SetLaunchAbility failed : no memory",
737                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
738         return NapiUtils::GetUndefinedValue(env);
739     }
740 
741     auto inputParser = [env, context](size_t argc, napi_value* argv) {
742         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
743             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
744         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->wantAgent_);
745         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get  wantAgent failed",
746             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
747     };
748     context->GetCbInfo(env, info, inputParser);
749 
750     auto executor = [context]() {
751         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
752         if (napiSession->session_ == nullptr) {
753             context->status = napi_generic_failure;
754             context->errMessage = "SetLaunchAbility failed : session is nullptr";
755             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
756             return;
757         }
758         int32_t ret = napiSession->session_->SetLaunchAbility(*context->wantAgent_);
759         if (ret != AVSESSION_SUCCESS) {
760             if (ret == ERR_SESSION_NOT_EXIST) {
761                 context->errMessage = "SetLaunchAbility failed : native session not exist";
762             } else if (ret == ERR_NO_PERMISSION) {
763                 context->errMessage = "SetLaunchAbility failed : native no permission";
764             } else {
765                 context->errMessage = "SetLaunchAbility failed : native server exception";
766             }
767             context->status = napi_generic_failure;
768             context->errCode = NapiAVSessionManager::errcode_[ret];
769         }
770     };
771     auto complete = [env](napi_value& output) {
772         output = NapiUtils::GetUndefinedValue(env);
773     };
774     return NapiAsyncWork::Enqueue(env, context, "SetLaunchAbility", executor, complete);
775 }
776 
SetExtras(napi_env env,napi_callback_info info)777 napi_value NapiAVSession::SetExtras(napi_env env, napi_callback_info info)
778 {
779     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetExtras");
780     struct ConcreteContext : public ContextBase {
781         AAFwk::WantParams extras_;
782     };
783     auto context = std::make_shared<ConcreteContext>();
784     if (context == nullptr) {
785         SLOGE("SetExtras failed : no memory");
786         NapiUtils::ThrowError(env, "SetExtras failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
787         return NapiUtils::GetUndefinedValue(env);
788     }
789 
790     auto inputParser = [env, context](size_t argc, napi_value* argv) {
791         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
792             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
793         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->extras_);
794         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get extras failed",
795             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
796     };
797     context->GetCbInfo(env, info, inputParser);
798     context->taskId = NAPI_SET_EXTRAS_TASK_ID;
799 
800     auto executor = [context]() {
801         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
802         if (napiSession->session_ == nullptr) {
803             context->status = napi_generic_failure;
804             context->errMessage = "SetExtras failed : session is nullptr";
805             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
806             return;
807         }
808         int32_t ret = napiSession->session_->SetExtras(context->extras_);
809         if (ret != AVSESSION_SUCCESS) {
810             if (ret == ERR_SESSION_NOT_EXIST) {
811                 context->errMessage = "SetExtras failed : native session not exist";
812             } else if (ret == ERR_INVALID_PARAM) {
813                 context->errMessage = "SetExtras failed : native invalid parameters";
814             } else {
815                 context->errMessage = "SetExtras failed : native server exception";
816             }
817             context->status = napi_generic_failure;
818             context->errCode = NapiAVSessionManager::errcode_[ret];
819         }
820     };
821     auto complete = [env](napi_value& output) {
822         output = NapiUtils::GetUndefinedValue(env);
823     };
824     return NapiAsyncWork::Enqueue(env, context, "SetExtras", executor, complete);
825 }
826 
SetAudioStreamId(napi_env env,napi_callback_info info)827 napi_value NapiAVSession::SetAudioStreamId(napi_env env, napi_callback_info info)
828 {
829     struct ConcreteContext : public ContextBase {
830         std::vector<int32_t> streamIds_;
831     };
832     auto context = std::make_shared<ConcreteContext>();
833     if (context == nullptr) {
834         SLOGE("SetAudioStreamId failed : no memory");
835         NapiUtils::ThrowError(env, "SetAudioStreamId failed : no memory",
836                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
837         return NapiUtils::GetUndefinedValue(env);
838     }
839 
840     auto inputParser = [env, context](size_t argc, napi_value* argv) {
841         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
842             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
843         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->streamIds_);
844         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get streamIds_ failed",
845             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
846     };
847     context->GetCbInfo(env, info, inputParser);
848 
849     auto executor = [context]() {
850         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
851         if (napiSession->session_ == nullptr) {
852             context->status = napi_generic_failure;
853             context->errMessage = "SetAudioStreamId failed : session is nullptr";
854             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
855             return;
856         }
857     };
858     auto complete = [env](napi_value& output) {
859         output = NapiUtils::GetUndefinedValue(env);
860     };
861     return NapiAsyncWork::Enqueue(env, context, "SetAudioStreamId", executor, complete);
862 }
863 
GetController(napi_env env,napi_callback_info info)864 napi_value NapiAVSession::GetController(napi_env env, napi_callback_info info)
865 {
866     struct ConcreteContext : public ContextBase {
867         std::shared_ptr<AVSessionController> controller_;
868     };
869     auto context = std::make_shared<ConcreteContext>();
870     if (context == nullptr) {
871         SLOGE("GetController failed : no memory");
872         NapiUtils::ThrowError(env, "GetController failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
873         return NapiUtils::GetUndefinedValue(env);
874     }
875 
876     context->GetCbInfo(env, info);
877 
878     auto executor = [context]() {
879         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
880         if (napiSession->session_ == nullptr) {
881             context->status = napi_generic_failure;
882             context->errMessage = "GetController failed : session is nullptr";
883             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
884             return;
885         }
886         context->controller_ = napiSession->session_->GetController();
887         if (context->controller_ == nullptr) {
888             context->status = napi_generic_failure;
889             context->errMessage = "GetController failed : native get controller failed";
890             context->errCode = NapiAVSessionManager::errcode_[AVSESSION_ERROR];
891         }
892     };
893     auto complete = [env, context](napi_value& output) {
894         CHECK_STATUS_RETURN_VOID(context, "get controller failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
895         CHECK_ARGS_RETURN_VOID(context, context->controller_ != nullptr, "controller is nullptr",
896             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
897         context->status = NapiAVSessionController::NewInstance(env, context->controller_, output);
898         CHECK_STATUS_RETURN_VOID(context, "convert native object to js object failed",
899             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
900     };
901     return NapiAsyncWork::Enqueue(env, context, "GetController", executor, complete);
902 }
903 
GetAVCastController(napi_env env,napi_callback_info info)904 napi_value NapiAVSession::GetAVCastController(napi_env env, napi_callback_info info)
905 {
906 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
907     struct ConcreteContext : public ContextBase {
908         std::shared_ptr<AVCastController> castController_;
909     };
910     auto context = std::make_shared<ConcreteContext>();
911     if (context == nullptr) {
912         SLOGE("GetAVCastController failed : no memory");
913         NapiUtils::ThrowError(env, "GetAVCastController failed : no memory",
914             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
915         return NapiUtils::GetUndefinedValue(env);
916     }
917 
918     context->GetCbInfo(env, info);
919 
920     auto executor = [context]() {
921         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
922         if (napiSession->session_ == nullptr) {
923             context->status = napi_generic_failure;
924             context->errMessage = "GetAVCastController failed : session is nullptr";
925             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
926             return;
927         }
928         context->castController_ = napiSession->session_->GetAVCastController();
929         if (context->castController_ == nullptr) {
930             context->status = napi_generic_failure;
931             context->errMessage = "GetAVCastController failed : native get controller failed";
932             context->errCode = NapiAVSessionManager::errcode_[AVSESSION_ERROR];
933         }
934     };
935     auto complete = [env, context](napi_value& output) {
936         CHECK_STATUS_RETURN_VOID(context, "get controller failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
937         CHECK_ARGS_RETURN_VOID(context, context->castController_ != nullptr, "controller is nullptr",
938             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
939         context->status = NapiAVCastController::NewInstance(env, context->castController_, output);
940         CHECK_STATUS_RETURN_VOID(context, "convert native object to js object failed",
941             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
942     };
943     return NapiAsyncWork::Enqueue(env, context, "GetAVCastController", executor, complete);
944 #else
945     return nullptr;
946 #endif
947 }
948 
GetOutputDevice(napi_env env,napi_callback_info info)949 napi_value NapiAVSession::GetOutputDevice(napi_env env, napi_callback_info info)
950 {
951     struct ConcreteContext : public ContextBase {
952         OutputDeviceInfo outputDeviceInfo_;
953     };
954     auto context = std::make_shared<ConcreteContext>();
955     if (context == nullptr) {
956         SLOGE("GetOutputDevice failed : no memory");
957         NapiUtils::ThrowError(env, "GetOutputDevice failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
958         return NapiUtils::GetUndefinedValue(env);
959     }
960 
961     context->GetCbInfo(env, info);
962 
963     auto executor = [context]() {
964         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
965         if (napiSession->session_ == nullptr) {
966             context->status = napi_generic_failure;
967             context->errMessage = "GetOutputDevice failed : session is nullptr";
968             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
969             return;
970         }
971         AVSessionDescriptor descriptor;
972         AVSessionManager::GetInstance().GetSessionDescriptorsBySessionId(napiSession->session_->GetSessionId(),
973                                                                          descriptor);
974         context->outputDeviceInfo_ = descriptor.outputDeviceInfo_;
975     };
976 
977     auto complete = [env, context](napi_value& output) {
978         context->status = NapiUtils::SetValue(env, context->outputDeviceInfo_, output);
979         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
980             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
981     };
982     return NapiAsyncWork::Enqueue(env, context, "GetOutputDevice", executor, complete);
983 }
984 
GetOutputDeviceSync(napi_env env,napi_callback_info info)985 napi_value NapiAVSession::GetOutputDeviceSync(napi_env env, napi_callback_info info)
986 {
987     SLOGD("Start GetOutputDeviceSync");
988     auto context = std::make_shared<ContextBase>();
989     if (context == nullptr) {
990         SLOGE("GetOutputDeviceSync failed : no memory");
991         NapiUtils::ThrowError(env, "GetOutputDeviceSync failed : no memory",
992             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
993         return NapiUtils::GetUndefinedValue(env);
994     }
995 
996     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
997 
998     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
999     if (napiSession->session_ == nullptr) {
1000         context->status = napi_generic_failure;
1001         context->errMessage = "GetOutputDeviceSync failed : session is nullptr";
1002         context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1003         return NapiUtils::GetUndefinedValue(env);
1004     }
1005 
1006     AVSessionDescriptor descriptor;
1007     AVSessionManager::GetInstance().GetSessionDescriptorsBySessionId(napiSession->session_->GetSessionId(),
1008         descriptor);
1009     napi_value output {};
1010     auto status = NapiUtils::SetValue(env, descriptor.outputDeviceInfo_, output);
1011     if (status != napi_ok) {
1012         SLOGE("convert native object to javascript object failed");
1013         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
1014             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1015         return NapiUtils::GetUndefinedValue(env);
1016     }
1017     return output;
1018 }
1019 
Activate(napi_env env,napi_callback_info info)1020 napi_value NapiAVSession::Activate(napi_env env, napi_callback_info info)
1021 {
1022     auto context = std::make_shared<ContextBase>();
1023     if (context == nullptr) {
1024         SLOGE("Activate failed : no memory");
1025         NapiUtils::ThrowError(env, "Activate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1026         return NapiUtils::GetUndefinedValue(env);
1027     }
1028 
1029     context->GetCbInfo(env, info);
1030 
1031     auto executor = [context]() {
1032         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1033         if (napiSession->session_ == nullptr) {
1034             context->status = napi_generic_failure;
1035             context->errMessage = "Activate session failed : session is nullptr";
1036             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1037             return;
1038         }
1039         int32_t ret = napiSession->session_->Activate();
1040         if (ret != AVSESSION_SUCCESS) {
1041             if (ret == ERR_SESSION_NOT_EXIST) {
1042                 context->errMessage = "Activate session failed : native session not exist";
1043             } else if (ret == ERR_NO_PERMISSION) {
1044                 context->errMessage = "Activate failed : native no permission";
1045             } else {
1046                 context->errMessage = "Activate session failed : native server exception";
1047             }
1048             context->status = napi_generic_failure;
1049             context->errCode = NapiAVSessionManager::errcode_[ret];
1050         }
1051     };
1052     auto complete = [env](napi_value& output) {
1053         output = NapiUtils::GetUndefinedValue(env);
1054     };
1055     return NapiAsyncWork::Enqueue(env, context, "Activate", executor, complete);
1056 }
1057 
Deactivate(napi_env env,napi_callback_info info)1058 napi_value NapiAVSession::Deactivate(napi_env env, napi_callback_info info)
1059 {
1060     auto context = std::make_shared<ContextBase>();
1061     if (context == nullptr) {
1062         SLOGE("Deactivate failed : no memory");
1063         NapiUtils::ThrowError(env, "Deactivate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1064         return NapiUtils::GetUndefinedValue(env);
1065     }
1066 
1067     context->GetCbInfo(env, info);
1068 
1069     auto executor = [context]() {
1070         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1071         if (napiSession->session_ == nullptr) {
1072             context->status = napi_generic_failure;
1073             context->errMessage = "Deactivate session failed : session is nullptr";
1074             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1075             return;
1076         }
1077         int32_t ret = napiSession->session_->Deactivate();
1078         if (ret != AVSESSION_SUCCESS) {
1079             if (ret == ERR_SESSION_NOT_EXIST) {
1080                 context->errMessage = "Deactivate session failed : native session not exist";
1081             } else if (ret == ERR_NO_PERMISSION) {
1082                 context->errMessage = "Deactivate failed : native no permission";
1083             } else {
1084                 context->errMessage = "Deactivate session failed : native server exception";
1085             }
1086             context->status = napi_generic_failure;
1087             context->errCode = NapiAVSessionManager::errcode_[ret];
1088         }
1089     };
1090     auto complete = [env](napi_value& output) {
1091         output = NapiUtils::GetUndefinedValue(env);
1092     };
1093     return NapiAsyncWork::Enqueue(env, context, "Deactivate", executor, complete);
1094 }
1095 
Destroy(napi_env env,napi_callback_info info)1096 napi_value NapiAVSession::Destroy(napi_env env, napi_callback_info info)
1097 {
1098     auto context = std::make_shared<ContextBase>();
1099     if (context == nullptr) {
1100         SLOGE("Destroy failed : no memory");
1101         NapiUtils::ThrowError(env, "Destroy failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1102         return NapiUtils::GetUndefinedValue(env);
1103     }
1104 
1105     context->GetCbInfo(env, info);
1106 
1107     SLOGI("Destroy session begin");
1108     auto executor = [context]() {
1109         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1110         if (napiSession->session_ == nullptr) {
1111             context->status = napi_generic_failure;
1112             context->errMessage = "Destroy session failed : session is nullptr";
1113             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1114             return;
1115         }
1116         int32_t ret = napiSession->session_->Destroy();
1117         if (ret == AVSESSION_SUCCESS) {
1118             napiSession->session_ = nullptr;
1119             napiSession->callback_ = nullptr;
1120         } else if (ret == ERR_SESSION_NOT_EXIST) {
1121             context->status = napi_generic_failure;
1122             context->errMessage = "Destroy session failed : native session not exist";
1123             context->errCode = NapiAVSessionManager::errcode_[ret];
1124         } else if (ret == ERR_NO_PERMISSION) {
1125             context->status = napi_generic_failure;
1126             context->errMessage = "Destroy failed : native no permission";
1127             context->errCode = NapiAVSessionManager::errcode_[ret];
1128         } else {
1129             context->status = napi_generic_failure;
1130             context->errMessage = "Destroy session failed : native server exception";
1131             context->errCode = NapiAVSessionManager::errcode_[ret];
1132         }
1133     };
1134     auto complete = [env](napi_value& output) {
1135         output = NapiUtils::GetUndefinedValue(env);
1136     };
1137     return NapiAsyncWork::Enqueue(env, context, "Destroy", executor, complete);
1138 }
1139 
SetSessionEvent(napi_env env,napi_callback_info info)1140 napi_value NapiAVSession::SetSessionEvent(napi_env env, napi_callback_info info)
1141 {
1142     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetSessionEvent");
1143     struct ConcreteContext : public ContextBase {
1144         std::string event_;
1145         AAFwk::WantParams args_;
1146     };
1147     auto context = std::make_shared<ConcreteContext>();
1148     if (context == nullptr) {
1149         SLOGE("SetSessionEvent failed : no memory");
1150         NapiUtils::ThrowError(env, "SetSessionEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1151         return NapiUtils::GetUndefinedValue(env);
1152     }
1153 
1154     auto inputParser = [env, context](size_t argc, napi_value* argv) {
1155         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid arguments",
1156             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1157         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->event_);
1158         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get event failed",
1159             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1160         context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->args_);
1161         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get args failed",
1162             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1163     };
1164     context->GetCbInfo(env, info, inputParser);
1165     context->taskId = NAPI_SET_AV_META_DATA_TASK_ID;
1166 
1167     auto executor = [context]() {
1168         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1169         if (napiSession->session_ == nullptr) {
1170             context->status = napi_generic_failure;
1171             context->errMessage = "SetSessionEvent failed : session is nullptr";
1172             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1173             return;
1174         }
1175         int32_t ret = napiSession->session_->SetSessionEvent(context->event_, context->args_);
1176         if (ret != AVSESSION_SUCCESS) {
1177             ErrCodeToMessage(ret, context->errMessage);
1178             context->status = napi_generic_failure;
1179             context->errCode = NapiAVSessionManager::errcode_[ret];
1180         }
1181     };
1182     auto complete = [env](napi_value& output) {
1183         output = NapiUtils::GetUndefinedValue(env);
1184     };
1185     return NapiAsyncWork::Enqueue(env, context, "SetSessionEvent", executor, complete);
1186 }
1187 
ReleaseCast(napi_env env,napi_callback_info info)1188 napi_value NapiAVSession::ReleaseCast(napi_env env, napi_callback_info info)
1189 {
1190 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1191     auto context = std::make_shared<ContextBase>();
1192     if (context == nullptr) {
1193         SLOGE("ReleaseCast failed : no memory");
1194         NapiUtils::ThrowError(env, "ReleaseCast failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1195         return NapiUtils::GetUndefinedValue(env);
1196     }
1197 
1198     context->GetCbInfo(env, info);
1199 
1200     auto executor = [context]() {
1201         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1202         if (napiSession->session_ == nullptr) {
1203             context->status = napi_generic_failure;
1204             context->errMessage = "ReleaseCast failed : session is nullptr";
1205             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1206             return;
1207         }
1208         int32_t ret = napiSession->session_->ReleaseCast();
1209         if (ret != AVSESSION_SUCCESS) {
1210             if (ret == ERR_SESSION_NOT_EXIST) {
1211                 context->errMessage = "ReleaseCast failed : native session not exist";
1212             } else if (ret == ERR_NO_PERMISSION) {
1213                 context->errMessage = "ReleaseCast failed : native no permission";
1214             } else {
1215                 context->errMessage = "ReleaseCast failed : native server exception";
1216             }
1217             context->status = napi_generic_failure;
1218             context->errCode = NapiAVSessionManager::errcode_[ret];
1219         }
1220     };
1221     auto complete = [env](napi_value& output) {
1222         output = NapiUtils::GetUndefinedValue(env);
1223     };
1224     return NapiAsyncWork::Enqueue(env, context, "ReleaseCast", executor, complete);
1225 #else
1226     return nullptr;
1227 #endif
1228 }
1229 
GetAllCastDisplays(napi_env env,napi_callback_info info)1230 napi_value NapiAVSession::GetAllCastDisplays(napi_env env, napi_callback_info info)
1231 {
1232 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1233     struct ConcreteContext : public ContextBase {
1234         std::vector<CastDisplayInfo> castDisplays_;
1235     };
1236     auto context = std::make_shared<ConcreteContext>();
1237     if (context == nullptr) {
1238         SLOGE("GetAllCastDisplays failed : no memory");
1239         NapiUtils::ThrowError(env, "GetAllCastDisplays failed : no memory",
1240             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1241         return NapiUtils::GetUndefinedValue(env);
1242     }
1243 
1244     context->GetCbInfo(env, info);
1245 
1246     auto executor = [context]() {
1247         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1248         if (napiSession->session_ == nullptr) {
1249             context->status = napi_generic_failure;
1250             context->errMessage = "GetAllCastDisplays failed : session is nullptr";
1251             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1252             return;
1253         }
1254         int32_t ret = napiSession->session_->GetAllCastDisplays(context->castDisplays_);
1255         if (ret != AVSESSION_SUCCESS) {
1256             if (ret == ERR_SESSION_NOT_EXIST) {
1257                 context->errMessage = "GetAllCastDisplays failed : native session not exist";
1258             } else if (ret == ERR_NO_PERMISSION) {
1259                 context->errMessage = "GetAllCastDisplays failed : native no permission";
1260             } else {
1261                 context->errMessage = "GetAllCastDisplays failed : native server exception";
1262             }
1263             context->status = napi_generic_failure;
1264             context->errCode = NapiAVSessionManager::errcode_[ret];
1265         }
1266     };
1267 
1268     auto complete = [env, context](napi_value& output) {
1269         context->status = NapiUtils::SetValue(env, context->castDisplays_, output);
1270         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
1271             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1272     };
1273     return NapiAsyncWork::Enqueue(env, context, "GetAllCastDisplays", executor, complete);
1274 #else
1275     SLOGE("GetAllCastDisplays CASTPLUS_CAST_ENGINE_ENABLE is not support");
1276     return ThrowErrorAndReturn(env, "OnEvent failed : no memory", ERR_NO_MEMORY);
1277 #endif
1278 }
1279 
ErrCodeToMessage(int32_t errCode,std::string & message)1280 void NapiAVSession::ErrCodeToMessage(int32_t errCode, std::string& message)
1281 {
1282     switch (errCode) {
1283         case ERR_SESSION_NOT_EXIST:
1284             message = "SetSessionEvent failed : native session not exist";
1285             break;
1286         case ERR_INVALID_PARAM:
1287             message = "SetSessionEvent failed : native invalid parameters";
1288             break;
1289         case ERR_NO_PERMISSION:
1290             message = "SetSessionEvent failed : native no permission";
1291             break;
1292         default:
1293             message = "SetSessionEvent failed : native server exception";
1294             break;
1295     }
1296 }
1297 
OnPlay(napi_env env,NapiAVSession * napiSession,napi_value callback)1298 napi_status NapiAVSession::OnPlay(napi_env env, NapiAVSession* napiSession, napi_value callback)
1299 {
1300     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1301     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY);
1302     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1303     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1304         "NapiAVSessionCallback object is nullptr");
1305     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY, callback);
1306 }
1307 
OnPause(napi_env env,NapiAVSession * napiSession,napi_value callback)1308 napi_status NapiAVSession::OnPause(napi_env env, NapiAVSession* napiSession, napi_value callback)
1309 {
1310     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1311     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PAUSE);
1312     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1313     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1314         "NapiAVSessionCallback object is nullptr");
1315     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PAUSE, callback);
1316 }
1317 
OnStop(napi_env env,NapiAVSession * napiSession,napi_value callback)1318 napi_status NapiAVSession::OnStop(napi_env env, NapiAVSession* napiSession, napi_value callback)
1319 {
1320     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1321     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_STOP);
1322     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1323     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1324         "NapiAVSessionCallback object is nullptr");
1325     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_STOP, callback);
1326 }
1327 
OnPlayNext(napi_env env,NapiAVSession * napiSession,napi_value callback)1328 napi_status NapiAVSession::OnPlayNext(napi_env env, NapiAVSession* napiSession, napi_value callback)
1329 {
1330     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1331     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_NEXT);
1332     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1333     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1334         "NapiAVSessionCallback object is nullptr");
1335     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_NEXT, callback);
1336 }
1337 
OnPlayPrevious(napi_env env,NapiAVSession * napiSession,napi_value callback)1338 napi_status NapiAVSession::OnPlayPrevious(napi_env env, NapiAVSession* napiSession, napi_value callback)
1339 {
1340     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1341     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS);
1342     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1343     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1344         "NapiAVSessionCallback object is nullptr");
1345     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_PREVIOUS, callback);
1346 }
1347 
OnFastForward(napi_env env,NapiAVSession * napiSession,napi_value callback)1348 napi_status NapiAVSession::OnFastForward(napi_env env, NapiAVSession* napiSession, napi_value callback)
1349 {
1350     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1351     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_FAST_FORWARD);
1352     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1353     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1354         "NapiAVSessionCallback object is nullptr");
1355     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_FAST_FORWARD, callback);
1356 }
1357 
OnRewind(napi_env env,NapiAVSession * napiSession,napi_value callback)1358 napi_status NapiAVSession::OnRewind(napi_env env, NapiAVSession* napiSession, napi_value callback)
1359 {
1360     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1361     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_REWIND);
1362     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1363     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1364         "NapiAVSessionCallback object is nullptr");
1365     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_REWIND, callback);
1366 }
1367 
OnSeek(napi_env env,NapiAVSession * napiSession,napi_value callback)1368 napi_status NapiAVSession::OnSeek(napi_env env, NapiAVSession* napiSession, napi_value callback)
1369 {
1370     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1371     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SEEK);
1372     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1373     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1374         "NapiAVSessionCallback object is nullptr");
1375     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SEEK, callback);
1376 }
1377 
OnSetSpeed(napi_env env,NapiAVSession * napiSession,napi_value callback)1378 napi_status NapiAVSession::OnSetSpeed(napi_env env, NapiAVSession* napiSession, napi_value callback)
1379 {
1380     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1381     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SET_SPEED);
1382     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1383     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1384         "NapiAVSessionCallback object is nullptr");
1385     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SET_SPEED, callback);
1386 }
1387 
OnSetLoopMode(napi_env env,NapiAVSession * napiSession,napi_value callback)1388 napi_status NapiAVSession::OnSetLoopMode(napi_env env, NapiAVSession* napiSession, napi_value callback)
1389 {
1390     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1391     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
1392     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1393     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1394         "NapiAVSessionCallback object is nullptr");
1395     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SET_LOOP_MODE, callback);
1396 }
1397 
OnToggleFavorite(napi_env env,NapiAVSession * napiSession,napi_value callback)1398 napi_status NapiAVSession::OnToggleFavorite(napi_env env, NapiAVSession* napiSession, napi_value callback)
1399 {
1400     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1401     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE);
1402     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1403     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1404         "NapiAVSessionCallback object is nullptr");
1405     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE, callback);
1406 }
1407 
OnMediaKeyEvent(napi_env env,NapiAVSession * napiSession,napi_value callback)1408 napi_status NapiAVSession::OnMediaKeyEvent(napi_env env, NapiAVSession* napiSession, napi_value callback)
1409 {
1410     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1411     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_MEDIA_KEY_SUPPORT);
1412     SLOGI("add media key event listen ret %{public}d", static_cast<int>(ret));
1413     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1414         "NapiAVSessionCallback object is nullptr");
1415     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT, callback);
1416 }
1417 
OnOutputDeviceChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1418 napi_status NapiAVSession::OnOutputDeviceChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1419 {
1420     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1421         "NapiAVSessionCallback object is nullptr");
1422     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_OUTPUT_DEVICE_CHANGE, callback);
1423 }
1424 
OnCommonCommand(napi_env env,NapiAVSession * napiSession,napi_value callback)1425 napi_status NapiAVSession::OnCommonCommand(napi_env env, NapiAVSession* napiSession, napi_value callback)
1426 {
1427     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SEND_COMMON_COMMAND, callback);
1428 }
1429 
OnSkipToQueueItem(napi_env env,NapiAVSession * napiSession,napi_value callback)1430 napi_status NapiAVSession::OnSkipToQueueItem(napi_env env, NapiAVSession* napiSession, napi_value callback)
1431 {
1432     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SKIP_TO_QUEUE_ITEM, callback);
1433 }
1434 
OnAVCallAnswer(napi_env env,NapiAVSession * napiSession,napi_value callback)1435 napi_status NapiAVSession::OnAVCallAnswer(napi_env env, NapiAVSession* napiSession, napi_value callback)
1436 {
1437     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1438     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_AVCALL_ANSWER);
1439     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1440     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1441         "NapiAVSessionCallback object is nullptr");
1442     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_AVCALL_ANSWER, callback);
1443 }
1444 
OnAVCallHangUp(napi_env env,NapiAVSession * napiSession,napi_value callback)1445 napi_status NapiAVSession::OnAVCallHangUp(napi_env env, NapiAVSession* napiSession, napi_value callback)
1446 {
1447     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1448     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_AVCALL_HANG_UP);
1449     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1450     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1451         "NapiAVSessionCallback object is nullptr");
1452     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_AVCALL_HANG_UP, callback);
1453 }
1454 
OnAVCallToggleCallMute(napi_env env,NapiAVSession * napiSession,napi_value callback)1455 napi_status NapiAVSession::OnAVCallToggleCallMute(napi_env env, NapiAVSession* napiSession, napi_value callback)
1456 {
1457     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1458     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_AVCALL_TOGGLE_CALL_MUTE);
1459     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1460     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1461         "NapiAVSessionCallback object is nullptr");
1462     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_AVCALL_TOGGLE_CALL_MUTE, callback);
1463 }
1464 
OnPlayFromAssetId(napi_env env,NapiAVSession * napiSession,napi_value callback)1465 napi_status NapiAVSession::OnPlayFromAssetId(napi_env env, NapiAVSession* napiSession, napi_value callback)
1466 {
1467     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1468     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_FROM_ASSETID);
1469     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1470     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1471         "NapiAVSessionCallback object is nullptr");
1472     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_FROM_ASSETID, callback);
1473 }
1474 
OnCastDisplayChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1475 napi_status NapiAVSession::OnCastDisplayChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1476 {
1477 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1478     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1479                              "NapiAVSessionCallback object is nullptr");
1480     auto status = napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_DISPLAY_CHANGE, callback);
1481     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "AddCallback failed");
1482     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1483                              "NapiAVSession object is nullptr");
1484     napiSession->session_->StartCastDisplayListener();
1485 #else
1486     return napi_generic_failure;
1487 #endif
1488     return napi_ok;
1489 }
1490 
OffPlay(napi_env env,NapiAVSession * napiSession,napi_value callback)1491 napi_status NapiAVSession::OffPlay(napi_env env, NapiAVSession* napiSession, napi_value callback)
1492 {
1493     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1494     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1495         "NapiAVSessionCallback object is nullptr");
1496     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY, callback);
1497     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1498     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY)) {
1499         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1500                                  "NapiAVSession object is nullptr");
1501         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY);
1502         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1503     }
1504     return napi_ok;
1505 }
1506 
OffPause(napi_env env,NapiAVSession * napiSession,napi_value callback)1507 napi_status NapiAVSession::OffPause(napi_env env, NapiAVSession* napiSession, napi_value callback)
1508 {
1509     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1510     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1511         "NapiAVSessionCallback object is nullptr");
1512     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PAUSE, callback);
1513     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1514     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PAUSE)) {
1515         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1516                                  "NapiAVSession object is nullptr");
1517         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PAUSE);
1518         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1519     }
1520     return napi_ok;
1521 }
1522 
OffStop(napi_env env,NapiAVSession * napiSession,napi_value callback)1523 napi_status NapiAVSession::OffStop(napi_env env, NapiAVSession* napiSession, napi_value callback)
1524 {
1525     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1526     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1527         "NapiAVSessionCallback object is nullptr");
1528     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_STOP, callback);
1529     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1530     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_STOP)) {
1531         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1532                                  "NapiAVSession object is nullptr");
1533         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_STOP);
1534         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1535     }
1536     return napi_ok;
1537 }
1538 
OffPlayNext(napi_env env,NapiAVSession * napiSession,napi_value callback)1539 napi_status NapiAVSession::OffPlayNext(napi_env env, NapiAVSession* napiSession, napi_value callback)
1540 {
1541     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1542     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1543         "NapiAVSessionCallback object is nullptr");
1544     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_NEXT, callback);
1545     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1546     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_NEXT)) {
1547         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1548                                  "NapiAVSession object is nullptr");
1549         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_NEXT);
1550         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1551     }
1552     return napi_ok;
1553 }
1554 
OffPlayPrevious(napi_env env,NapiAVSession * napiSession,napi_value callback)1555 napi_status NapiAVSession::OffPlayPrevious(napi_env env, NapiAVSession* napiSession, napi_value callback)
1556 {
1557     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1558     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1559         "NapiAVSessionCallback object is nullptr");
1560     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_PREVIOUS, callback);
1561     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1562 
1563     if (napiSession->callback_ &&
1564         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_PREVIOUS)) {
1565         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1566                                  "NapiAVSession object is nullptr");
1567         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS);
1568         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1569     }
1570     return napi_ok;
1571 }
1572 
OffFastForward(napi_env env,NapiAVSession * napiSession,napi_value callback)1573 napi_status NapiAVSession::OffFastForward(napi_env env, NapiAVSession* napiSession, napi_value callback)
1574 {
1575     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1576     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1577         "NapiAVSessionCallback object is nullptr");
1578     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_FAST_FORWARD, callback);
1579     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1580     if (napiSession->callback_ &&
1581         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_FAST_FORWARD)) {
1582         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1583                                  "NapiAVSession object is nullptr");
1584         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_FAST_FORWARD);
1585         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1586     }
1587     return napi_ok;
1588 }
1589 
OffRewind(napi_env env,NapiAVSession * napiSession,napi_value callback)1590 napi_status NapiAVSession::OffRewind(napi_env env, NapiAVSession* napiSession, napi_value callback)
1591 {
1592     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1593     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1594         "NapiAVSessionCallback object is nullptr");
1595     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_REWIND, callback);
1596     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1597     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_REWIND)) {
1598         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1599                                  "NapiAVSession object is nullptr");
1600         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_REWIND);
1601         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1602     }
1603     return napi_ok;
1604 }
1605 
OffSeek(napi_env env,NapiAVSession * napiSession,napi_value callback)1606 napi_status NapiAVSession::OffSeek(napi_env env, NapiAVSession* napiSession, napi_value callback)
1607 {
1608     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1609     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1610         "NapiAVSessionCallback object is nullptr");
1611     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SEEK, callback);
1612     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1613     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SEEK)) {
1614         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1615                                  "NapiAVSession object is nullptr");
1616         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SEEK);
1617         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1618     }
1619     return napi_ok;
1620 }
1621 
OffSetSpeed(napi_env env,NapiAVSession * napiSession,napi_value callback)1622 napi_status NapiAVSession::OffSetSpeed(napi_env env, NapiAVSession* napiSession, napi_value callback)
1623 {
1624     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1625     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1626         "NapiAVSessionCallback object is nullptr");
1627     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SET_SPEED, callback);
1628     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1629     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SET_SPEED)) {
1630         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1631                                  "NapiAVSession_session is nullptr");
1632         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SET_SPEED);
1633         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1634     }
1635     return napi_ok;
1636 }
1637 
OffSetLoopMode(napi_env env,NapiAVSession * napiSession,napi_value callback)1638 napi_status NapiAVSession::OffSetLoopMode(napi_env env, NapiAVSession* napiSession, napi_value callback)
1639 {
1640     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1641     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1642         "NapiAVSessionCallback object is nullptr");
1643     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SET_LOOP_MODE, callback);
1644     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1645     if (napiSession->callback_ &&
1646         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SET_LOOP_MODE)) {
1647         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1648                                  "NapiAVSession object is nullptr");
1649         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
1650         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1651     }
1652     return napi_ok;
1653 }
1654 
OffToggleFavorite(napi_env env,NapiAVSession * napiSession,napi_value callback)1655 napi_status NapiAVSession::OffToggleFavorite(napi_env env, NapiAVSession* napiSession, napi_value callback)
1656 {
1657     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1658     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1659         "NapiAVSessionCallback object is nullptr");
1660     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE, callback);
1661     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1662     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE)) {
1663         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1664                                  "NapiAVSession object is nullptr");
1665         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE);
1666         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1667     }
1668     return napi_ok;
1669 }
1670 
OffMediaKeyEvent(napi_env env,NapiAVSession * napiSession,napi_value callback)1671 napi_status NapiAVSession::OffMediaKeyEvent(napi_env env, NapiAVSession* napiSession, napi_value callback)
1672 {
1673     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1674     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1675         "NapiAVSessionCallback object is nullptr");
1676     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT, callback);
1677     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1678     if (napiSession->callback_ &&
1679         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT)) {
1680         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1681                                  "NapiAVSession object is nullptr");
1682         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_MEDIA_KEY_SUPPORT);
1683         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1684     }
1685     return napi_ok;
1686 }
1687 
OffOutputDeviceChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1688 napi_status NapiAVSession::OffOutputDeviceChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1689 {
1690     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1691     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1692         "NapiAVSessionCallback object is nullptr");
1693     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_OUTPUT_DEVICE_CHANGE, callback);
1694 }
1695 
OffCommonCommand(napi_env env,NapiAVSession * napiSession,napi_value callback)1696 napi_status NapiAVSession::OffCommonCommand(napi_env env, NapiAVSession* napiSession, napi_value callback)
1697 {
1698     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SEND_COMMON_COMMAND, callback);
1699 }
1700 
OffSkipToQueueItem(napi_env env,NapiAVSession * napiSession,napi_value callback)1701 napi_status NapiAVSession::OffSkipToQueueItem(napi_env env, NapiAVSession* napiSession, napi_value callback)
1702 {
1703     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1704     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1705         "NapiAVSessionCallback object is nullptr");
1706     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SKIP_TO_QUEUE_ITEM, callback);
1707 }
1708 
OffAVCallAnswer(napi_env env,NapiAVSession * napiSession,napi_value callback)1709 napi_status NapiAVSession::OffAVCallAnswer(napi_env env, NapiAVSession* napiSession, napi_value callback)
1710 {
1711     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1712     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1713         "NapiAVSessionCallback object is nullptr");
1714     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_AVCALL_ANSWER, callback);
1715 }
1716 
OffAVCallHangUp(napi_env env,NapiAVSession * napiSession,napi_value callback)1717 napi_status NapiAVSession::OffAVCallHangUp(napi_env env, NapiAVSession* napiSession, napi_value callback)
1718 {
1719     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1720     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1721         "NapiAVSessionCallback object is nullptr");
1722     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_AVCALL_HANG_UP, callback);
1723 }
1724 
OffAVCallToggleCallMute(napi_env env,NapiAVSession * napiSession,napi_value callback)1725 napi_status NapiAVSession::OffAVCallToggleCallMute(napi_env env, NapiAVSession* napiSession, napi_value callback)
1726 {
1727     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1728     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1729         "NapiAVSessionCallback object is nullptr");
1730     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_AVCALL_TOGGLE_CALL_MUTE, callback);
1731 }
1732 
OffPlayFromAssetId(napi_env env,NapiAVSession * napiSession,napi_value callback)1733 napi_status NapiAVSession::OffPlayFromAssetId(napi_env env, NapiAVSession* napiSession, napi_value callback)
1734 {
1735     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1736     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1737         "NapiAVSessionCallback object is nullptr");
1738     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_FROM_ASSETID, callback);
1739     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1740 
1741     if (napiSession->callback_ &&
1742         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_FROM_ASSETID)) {
1743         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1744                                  "NapiAVSession object is nullptr");
1745         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_FROM_ASSETID);
1746         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1747     }
1748     return napi_ok;
1749 }
1750 
OffCastDisplayChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1751 napi_status NapiAVSession::OffCastDisplayChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1752 {
1753 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1754     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1755     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1756                              "NapiAVSessionCallback object is nullptr");
1757     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_DISPLAY_CHANGE, callback);
1758     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1759     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1760                              "NapiAVSession object is nullptr");
1761     napiSession->session_->StopCastDisplayListener();
1762 #else
1763     return napi_generic_failure;
1764 #endif
1765     return napi_ok;
1766 }
1767 }
1768