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)450 bool doMetaDataSetNapi(std::shared_ptr<ContextBase> context, std::shared_ptr<AVSession> sessionPtr, AVMetaData& data)
451 {
452     SLOGI("do metadata set with check uri alive:%{public}d, pixel alive:%{public}d",
453         static_cast<int>(!data.GetMediaImageUri().empty()), static_cast<int>(data.GetMediaImage() != nullptr));
454     auto uri = data.GetMediaImageUri();
455     int32_t ret = sessionPtr->SetAVMetaData(data);
456     if (ret != AVSESSION_SUCCESS) {
457         SLOGE("do metadata set fail, ret:%{public}d", ret);
458         processErrMsg(context, ret);
459     } else if (data.GetMediaImageUri().empty()) {
460         SLOGE("do metadata set with img uri empty");
461     } else if (data.GetMediaImage() == nullptr) {
462         ret = DoDownload(data, uri);
463         SLOGI("DoDownload complete with ret %{public}d", ret);
464         CHECK_AND_RETURN_RET_LOG(sessionPtr != nullptr, false, "doMetaDataSet without session");
465         if (ret != AVSESSION_SUCCESS) {
466             SLOGE("DoDownload failed but not repeat setmetadata again");
467         } else {
468             return true;
469         }
470     }
471     return false;
472 }
473 
SetAVMetaData(napi_env env,napi_callback_info info)474 napi_value NapiAVSession::SetAVMetaData(napi_env env, napi_callback_info info)
475 {
476     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVMetadata");
477     struct ConcreteContext : public ContextBase {
478         AVMetaData metaData;
479         std::chrono::system_clock::time_point metadataTs;
480     };
481     auto context = std::make_shared<ConcreteContext>();
482     CHECK_AND_RETURN_RET_LOG(context != nullptr, NapiUtils::GetUndefinedValue(env), "SetAVMetaData failed: no memory");
483     auto inputParser = [env, context](size_t argc, napi_value* argv) {
484         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
485             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
486         context->status = NapiMetaData::GetValue(env, argv[ARGV_FIRST], context->metaData);
487         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get metaData failed",
488             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
489     };
490     context->GetCbInfo(env, info, inputParser);
491     auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
492     auto* napiAvSession = reinterpret_cast<NapiAVSession*>(context->native);
493     if (napiAvSession == nullptr || napiAvSession->metaData_.EqualWithUri((context->metaData))) {
494         SLOGI("napiAvSession is nullptr or metadata with uri is the same as last time");
495         auto executor = []() {};
496         return NapiAsyncWork::Enqueue(env, context, "SetAVMetaData", executor, complete);
497     }
498     napiAvSession->metaData_ = context->metaData;
499     context->taskId = NAPI_SET_AV_META_DATA_TASK_ID;
500     if (napiAvSession->latestMetadataAssetId_ != napiAvSession->metaData_.GetAssetId() ||
501         !napiAvSession->metaData_.GetMediaImageUri().empty() || napiAvSession->metaData_.GetMediaImage() != nullptr) {
502         context->metadataTs = std::chrono::system_clock::now();
503         napiAvSession->latestMetadataAssetId_ = napiAvSession->metaData_.GetAssetId();
504         reinterpret_cast<NapiAVSession*>(context->native)->latestMetadataTs_ = context->metadataTs;
505     }
506     auto executor = [context]() {
507         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
508         if (napiSession->session_ == nullptr) {
509             context->status = napi_generic_failure;
510             context->errMessage = "SetAVMetaData failed : session is nullptr";
511             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
512             context->metaData.Reset();
513             return;
514         }
515         bool res = doMetaDataSetNapi(context, napiSession->session_, context->metaData);
516         bool timeAvailable = context->metadataTs >= napiSession->latestMetadataTs_;
517         SLOGI("doMetaDataSet res:%{public}d, time:%{public}d", static_cast<int>(res), static_cast<int>(timeAvailable));
518         if (res && timeAvailable && napiSession->session_ != nullptr) {
519             napiSession->session_->SetAVMetaData(context->metaData);
520         }
521         context->metaData.Reset();
522     };
523     return NapiAsyncWork::Enqueue(env, context, "SetAVMetaData", executor, complete);
524 }
525 
PlaybackStateSyncExecutor(NapiAVSession * napiSession,AVPlaybackState playBackState)526 std::function<void()> NapiAVSession::PlaybackStateSyncExecutor(NapiAVSession* napiSession,
527     AVPlaybackState playBackState)
528 {
529     return [napiSession, playBackState]() {
530         if (napiSession->session_ == nullptr) {
531             playBackStateRet_ = ERR_SESSION_NOT_EXIST;
532             return;
533         }
534         playBackStateRet_ = napiSession->session_->SetAVPlaybackState(playBackState);
535         syncCond_.notify_one();
536         std::unique_lock<std::mutex> lock(syncAsyncMutex_);
537         auto waitStatus = syncAsyncCond_.wait_for(lock, std::chrono::milliseconds(100));
538         if (waitStatus == std::cv_status::timeout) {
539             SLOGE("SetAVPlaybackState in syncExecutor timeout");
540             return;
541         }
542     };
543 }
544 
PlaybackStateAsyncExecutor(std::shared_ptr<ContextBase> context)545 std::function<void()> NapiAVSession::PlaybackStateAsyncExecutor(std::shared_ptr<ContextBase> context)
546 {
547     return [context]() {
548         std::unique_lock<std::mutex> lock(syncMutex_);
549         auto waitStatus = syncCond_.wait_for(lock, std::chrono::milliseconds(100));
550         if (waitStatus == std::cv_status::timeout) {
551             SLOGE("SetAVPlaybackState in asyncExecutor timeout");
552             return;
553         }
554 
555         if (playBackStateRet_ != AVSESSION_SUCCESS) {
556             if (playBackStateRet_ == ERR_SESSION_NOT_EXIST) {
557                 context->errMessage = "SetAVPlaybackState failed : native session not exist";
558             } else if (playBackStateRet_ == ERR_INVALID_PARAM) {
559                 context->errMessage = "SetAVPlaybackState failed : native invalid parameters";
560             } else if (playBackStateRet_ == ERR_NO_PERMISSION) {
561                 context->errMessage = "SetAVPlaybackState failed : native no permission";
562             } else {
563                 context->errMessage = "SetAVPlaybackState failed : native server exception";
564             }
565             context->status = napi_generic_failure;
566             context->errCode = NapiAVSessionManager::errcode_[playBackStateRet_];
567         }
568         syncAsyncCond_.notify_one();
569     };
570 }
571 
SetAVPlaybackState(napi_env env,napi_callback_info info)572 napi_value NapiAVSession::SetAVPlaybackState(napi_env env, napi_callback_info info)
573 {
574     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVPlaybackState");
575     struct ConcreteContext : public ContextBase {
576         AVPlaybackState playBackState_;
577     };
578     auto context = std::make_shared<ConcreteContext>();
579     if (context == nullptr) {
580         SLOGE("SetAVPlaybackState failed : no memory");
581         NapiUtils::ThrowError(env, "SetAVPlaybackState failed : no memory",
582                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
583         return NapiUtils::GetUndefinedValue(env);
584     }
585 
586     auto inputParser = [env, context](size_t argc, napi_value* argv) {
587         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
588             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
589         context->status = NapiPlaybackState::GetValue(env, argv[ARGV_FIRST], context->playBackState_);
590         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get playBackState failed",
591             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
592     };
593     context->GetCbInfo(env, info, inputParser);
594     context->taskId = NAPI_SET_AV_PLAYBACK_STATE_TASK_ID;
595 
596     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
597     if (napiSession->session_ == nullptr) {
598         SLOGE("SetAVPlaybackState failed : session is nullptr");
599         context->status = napi_generic_failure;
600         context->errMessage = "SetAVPlaybackState failed : session is nullptr";
601         context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
602         auto executor = []() {};
603         auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
604         return NapiAsyncWork::Enqueue(env, context, "SetAVPlaybackState", executor, complete);
605     }
606 
607     auto syncExecutor = PlaybackStateSyncExecutor(napiSession, context->playBackState_);
608     CHECK_AND_PRINT_LOG(AVSessionEventHandler::GetInstance()
609         .AVSessionPostTask(syncExecutor, "SetAVPlaybackState"),
610         "NapiAVSession SetAVPlaybackState handler postTask failed");
611 
612     auto asyncExecutor = PlaybackStateAsyncExecutor(context);
613     auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
614     return NapiAsyncWork::Enqueue(env, context, "SetAVPlaybackState", asyncExecutor, complete);
615 }
616 
SetAVQueueItems(napi_env env,napi_callback_info info)617 napi_value NapiAVSession::SetAVQueueItems(napi_env env, napi_callback_info info)
618 {
619     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVQueueItems");
620     struct ConcreteContext : public ContextBase { std::vector<AVQueueItem> items_; };
621     auto context = std::make_shared<ConcreteContext>();
622     if (context == nullptr) {
623         NapiUtils::ThrowError(env, "SetAVQueueItems failed : no memory",
624             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
625         return NapiUtils::GetUndefinedValue(env);
626     }
627     auto inputParser = [env, context](size_t argc, napi_value* argv) {
628         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
629             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
630         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->items_);
631         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get queueItems failed",
632             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
633         for (auto &item : context->items_) {
634             CHECK_ARGS_RETURN_VOID(context, item.IsValid(), "invalid queue item content",
635                 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
636         }
637     };
638     context->GetCbInfo(env, info, inputParser);
639     context->taskId = NAPI_SET_AV_QUEUE_ITEMS_TASK_ID;
640     auto executor = [context]() {
641         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
642         if (napiSession->session_ == nullptr) {
643             context->status = napi_generic_failure;
644             context->errMessage = "SetAVQueueItems failed : session is nullptr";
645             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
646             return;
647         }
648         int32_t ret = napiSession->session_->SetAVQueueItems(context->items_);
649         if (ret != AVSESSION_SUCCESS) {
650             if (ret == ERR_SESSION_NOT_EXIST) {
651                 context->errMessage = "SetAVQueueItems failed : native session not exist";
652             } else if (ret == ERR_INVALID_PARAM) {
653                 context->errMessage = "SetAVQueueItems failed : native invalid parameters";
654             } else if (ret == ERR_NO_PERMISSION) {
655                 context->errMessage = "SetAVQueueItems failed : native no permission";
656             } else if (ret == ERR_MARSHALLING) {
657                 context->errMessage = "SetAVQueueItems failed : item number is out of range";
658             } else {
659                 context->errMessage = "SetAVQueueItems failed : native server exception";
660             }
661             context->status = napi_generic_failure;
662             context->errCode = NapiAVSessionManager::errcode_[ret];
663         }
664     };
665     auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
666     return NapiAsyncWork::Enqueue(env, context, "SetAVQueueItems", executor, complete);
667 }
668 
SetAVQueueTitle(napi_env env,napi_callback_info info)669 napi_value NapiAVSession::SetAVQueueTitle(napi_env env, napi_callback_info info)
670 {
671     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetAVQueueTitle");
672     struct ConcreteContext : public ContextBase {
673         std::string title;
674     };
675     auto context = std::make_shared<ConcreteContext>();
676     if (context == nullptr) {
677         SLOGE("SetAVQueueTitle failed : no memory");
678         NapiUtils::ThrowError(env, "SetAVQueueTitle failed : no memory",
679             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
680         return NapiUtils::GetUndefinedValue(env);
681     }
682 
683     auto inputParser = [env, context](size_t argc, napi_value* argv) {
684         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
685             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
686         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->title);
687         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get queueItems failed",
688             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
689     };
690     context->GetCbInfo(env, info, inputParser);
691     context->taskId = NAPI_SET_AV_QUEUE_TITLE_TASK_ID;
692 
693     auto executor = [context]() {
694         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
695         if (napiSession->session_ == nullptr) {
696             context->status = napi_generic_failure;
697             context->errMessage = "SetAVQueueTitle failed : session is nullptr";
698             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
699             return;
700         }
701         int32_t ret = napiSession->session_->SetAVQueueTitle(context->title);
702         if (ret != AVSESSION_SUCCESS) {
703             if (ret == ERR_SESSION_NOT_EXIST) {
704                 context->errMessage = "SetAVQueueTitle failed : native session not exist";
705             } else if (ret == ERR_INVALID_PARAM) {
706                 context->errMessage = "SetAVQueueTitle failed : native invalid parameters";
707             } else if (ret == ERR_NO_PERMISSION) {
708                 context->errMessage = "SetAVQueueTitle failed : native no permission";
709             } else {
710                 context->errMessage = "SetAVQueueTitle failed : native server exception";
711             }
712             context->status = napi_generic_failure;
713             context->errCode = NapiAVSessionManager::errcode_[ret];
714         }
715     };
716     auto complete = [env](napi_value& output) {
717         output = NapiUtils::GetUndefinedValue(env);
718     };
719     return NapiAsyncWork::Enqueue(env, context, "SetAVQueueTitle", executor, complete);
720 }
721 
SetLaunchAbility(napi_env env,napi_callback_info info)722 napi_value NapiAVSession::SetLaunchAbility(napi_env env, napi_callback_info info)
723 {
724     struct ConcreteContext : public ContextBase {
725         AbilityRuntime::WantAgent::WantAgent* wantAgent_;
726     };
727     auto context = std::make_shared<ConcreteContext>();
728     if (context == nullptr) {
729         SLOGE("SetLaunchAbility failed : no memory");
730         NapiUtils::ThrowError(env, "SetLaunchAbility failed : no memory",
731                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
732         return NapiUtils::GetUndefinedValue(env);
733     }
734 
735     auto inputParser = [env, context](size_t argc, napi_value* argv) {
736         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
737             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
738         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->wantAgent_);
739         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get  wantAgent failed",
740             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
741     };
742     context->GetCbInfo(env, info, inputParser);
743 
744     auto executor = [context]() {
745         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
746         if (napiSession->session_ == nullptr) {
747             context->status = napi_generic_failure;
748             context->errMessage = "SetLaunchAbility failed : session is nullptr";
749             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
750             return;
751         }
752         int32_t ret = napiSession->session_->SetLaunchAbility(*context->wantAgent_);
753         if (ret != AVSESSION_SUCCESS) {
754             if (ret == ERR_SESSION_NOT_EXIST) {
755                 context->errMessage = "SetLaunchAbility failed : native session not exist";
756             } else if (ret == ERR_NO_PERMISSION) {
757                 context->errMessage = "SetLaunchAbility failed : native no permission";
758             } else {
759                 context->errMessage = "SetLaunchAbility failed : native server exception";
760             }
761             context->status = napi_generic_failure;
762             context->errCode = NapiAVSessionManager::errcode_[ret];
763         }
764     };
765     auto complete = [env](napi_value& output) {
766         output = NapiUtils::GetUndefinedValue(env);
767     };
768     return NapiAsyncWork::Enqueue(env, context, "SetLaunchAbility", executor, complete);
769 }
770 
SetExtras(napi_env env,napi_callback_info info)771 napi_value NapiAVSession::SetExtras(napi_env env, napi_callback_info info)
772 {
773     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetExtras");
774     struct ConcreteContext : public ContextBase {
775         AAFwk::WantParams extras_;
776     };
777     auto context = std::make_shared<ConcreteContext>();
778     if (context == nullptr) {
779         SLOGE("SetExtras failed : no memory");
780         NapiUtils::ThrowError(env, "SetExtras failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
781         return NapiUtils::GetUndefinedValue(env);
782     }
783 
784     auto inputParser = [env, context](size_t argc, napi_value* argv) {
785         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
786             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
787         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->extras_);
788         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get extras failed",
789             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
790     };
791     context->GetCbInfo(env, info, inputParser);
792     context->taskId = NAPI_SET_EXTRAS_TASK_ID;
793 
794     auto executor = [context]() {
795         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
796         if (napiSession->session_ == nullptr) {
797             context->status = napi_generic_failure;
798             context->errMessage = "SetExtras failed : session is nullptr";
799             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
800             return;
801         }
802         int32_t ret = napiSession->session_->SetExtras(context->extras_);
803         if (ret != AVSESSION_SUCCESS) {
804             if (ret == ERR_SESSION_NOT_EXIST) {
805                 context->errMessage = "SetExtras failed : native session not exist";
806             } else if (ret == ERR_INVALID_PARAM) {
807                 context->errMessage = "SetExtras failed : native invalid parameters";
808             } else {
809                 context->errMessage = "SetExtras failed : native server exception";
810             }
811             context->status = napi_generic_failure;
812             context->errCode = NapiAVSessionManager::errcode_[ret];
813         }
814     };
815     auto complete = [env](napi_value& output) {
816         output = NapiUtils::GetUndefinedValue(env);
817     };
818     return NapiAsyncWork::Enqueue(env, context, "SetExtras", executor, complete);
819 }
820 
SetAudioStreamId(napi_env env,napi_callback_info info)821 napi_value NapiAVSession::SetAudioStreamId(napi_env env, napi_callback_info info)
822 {
823     struct ConcreteContext : public ContextBase {
824         std::vector<int32_t> streamIds_;
825     };
826     auto context = std::make_shared<ConcreteContext>();
827     if (context == nullptr) {
828         SLOGE("SetAudioStreamId failed : no memory");
829         NapiUtils::ThrowError(env, "SetAudioStreamId failed : no memory",
830                               NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
831         return NapiUtils::GetUndefinedValue(env);
832     }
833 
834     auto inputParser = [env, context](size_t argc, napi_value* argv) {
835         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
836             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
837         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->streamIds_);
838         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get streamIds_ failed",
839             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
840     };
841     context->GetCbInfo(env, info, inputParser);
842 
843     auto executor = [context]() {
844         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
845         if (napiSession->session_ == nullptr) {
846             context->status = napi_generic_failure;
847             context->errMessage = "SetAudioStreamId failed : session is nullptr";
848             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
849             return;
850         }
851     };
852     auto complete = [env](napi_value& output) {
853         output = NapiUtils::GetUndefinedValue(env);
854     };
855     return NapiAsyncWork::Enqueue(env, context, "SetAudioStreamId", executor, complete);
856 }
857 
GetController(napi_env env,napi_callback_info info)858 napi_value NapiAVSession::GetController(napi_env env, napi_callback_info info)
859 {
860     struct ConcreteContext : public ContextBase {
861         std::shared_ptr<AVSessionController> controller_;
862     };
863     auto context = std::make_shared<ConcreteContext>();
864     if (context == nullptr) {
865         SLOGE("GetController failed : no memory");
866         NapiUtils::ThrowError(env, "GetController failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
867         return NapiUtils::GetUndefinedValue(env);
868     }
869 
870     context->GetCbInfo(env, info);
871 
872     auto executor = [context]() {
873         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
874         if (napiSession->session_ == nullptr) {
875             context->status = napi_generic_failure;
876             context->errMessage = "GetController failed : session is nullptr";
877             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
878             return;
879         }
880         context->controller_ = napiSession->session_->GetController();
881         if (context->controller_ == nullptr) {
882             context->status = napi_generic_failure;
883             context->errMessage = "GetController failed : native get controller failed";
884             context->errCode = NapiAVSessionManager::errcode_[AVSESSION_ERROR];
885         }
886     };
887     auto complete = [env, context](napi_value& output) {
888         CHECK_STATUS_RETURN_VOID(context, "get controller failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
889         CHECK_ARGS_RETURN_VOID(context, context->controller_ != nullptr, "controller is nullptr",
890             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
891         context->status = NapiAVSessionController::NewInstance(env, context->controller_, output);
892         CHECK_STATUS_RETURN_VOID(context, "convert native object to js object failed",
893             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
894     };
895     return NapiAsyncWork::Enqueue(env, context, "GetController", executor, complete);
896 }
897 
GetAVCastController(napi_env env,napi_callback_info info)898 napi_value NapiAVSession::GetAVCastController(napi_env env, napi_callback_info info)
899 {
900 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
901     struct ConcreteContext : public ContextBase {
902         std::shared_ptr<AVCastController> castController_;
903     };
904     auto context = std::make_shared<ConcreteContext>();
905     if (context == nullptr) {
906         SLOGE("GetAVCastController failed : no memory");
907         NapiUtils::ThrowError(env, "GetAVCastController failed : no memory",
908             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
909         return NapiUtils::GetUndefinedValue(env);
910     }
911 
912     context->GetCbInfo(env, info);
913 
914     auto executor = [context]() {
915         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
916         if (napiSession->session_ == nullptr) {
917             context->status = napi_generic_failure;
918             context->errMessage = "GetAVCastController failed : session is nullptr";
919             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
920             return;
921         }
922         context->castController_ = napiSession->session_->GetAVCastController();
923         if (context->castController_ == nullptr) {
924             context->status = napi_generic_failure;
925             context->errMessage = "GetAVCastController failed : native get controller failed";
926             context->errCode = NapiAVSessionManager::errcode_[AVSESSION_ERROR];
927         }
928     };
929     auto complete = [env, context](napi_value& output) {
930         CHECK_STATUS_RETURN_VOID(context, "get controller failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
931         CHECK_ARGS_RETURN_VOID(context, context->castController_ != nullptr, "controller is nullptr",
932             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
933         context->status = NapiAVCastController::NewInstance(env, context->castController_, output);
934         CHECK_STATUS_RETURN_VOID(context, "convert native object to js object failed",
935             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
936     };
937     return NapiAsyncWork::Enqueue(env, context, "GetAVCastController", executor, complete);
938 #else
939     return nullptr;
940 #endif
941 }
942 
GetOutputDevice(napi_env env,napi_callback_info info)943 napi_value NapiAVSession::GetOutputDevice(napi_env env, napi_callback_info info)
944 {
945     struct ConcreteContext : public ContextBase {
946         OutputDeviceInfo outputDeviceInfo_;
947     };
948     auto context = std::make_shared<ConcreteContext>();
949     if (context == nullptr) {
950         SLOGE("GetOutputDevice failed : no memory");
951         NapiUtils::ThrowError(env, "GetOutputDevice failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
952         return NapiUtils::GetUndefinedValue(env);
953     }
954 
955     context->GetCbInfo(env, info);
956 
957     auto executor = [context]() {
958         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
959         if (napiSession->session_ == nullptr) {
960             context->status = napi_generic_failure;
961             context->errMessage = "GetOutputDevice failed : session is nullptr";
962             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
963             return;
964         }
965         AVSessionDescriptor descriptor;
966         AVSessionManager::GetInstance().GetSessionDescriptorsBySessionId(napiSession->session_->GetSessionId(),
967                                                                          descriptor);
968         context->outputDeviceInfo_ = descriptor.outputDeviceInfo_;
969     };
970 
971     auto complete = [env, context](napi_value& output) {
972         context->status = NapiUtils::SetValue(env, context->outputDeviceInfo_, output);
973         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
974             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
975     };
976     return NapiAsyncWork::Enqueue(env, context, "GetOutputDevice", executor, complete);
977 }
978 
GetOutputDeviceSync(napi_env env,napi_callback_info info)979 napi_value NapiAVSession::GetOutputDeviceSync(napi_env env, napi_callback_info info)
980 {
981     SLOGD("Start GetOutputDeviceSync");
982     auto context = std::make_shared<ContextBase>();
983     if (context == nullptr) {
984         SLOGE("GetOutputDeviceSync failed : no memory");
985         NapiUtils::ThrowError(env, "GetOutputDeviceSync failed : no memory",
986             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
987         return NapiUtils::GetUndefinedValue(env);
988     }
989 
990     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
991 
992     auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
993     if (napiSession->session_ == nullptr) {
994         context->status = napi_generic_failure;
995         context->errMessage = "GetOutputDeviceSync failed : session is nullptr";
996         context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
997         return NapiUtils::GetUndefinedValue(env);
998     }
999 
1000     AVSessionDescriptor descriptor;
1001     AVSessionManager::GetInstance().GetSessionDescriptorsBySessionId(napiSession->session_->GetSessionId(),
1002         descriptor);
1003     napi_value output {};
1004     auto status = NapiUtils::SetValue(env, descriptor.outputDeviceInfo_, output);
1005     if (status != napi_ok) {
1006         SLOGE("convert native object to javascript object failed");
1007         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
1008             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1009         return NapiUtils::GetUndefinedValue(env);
1010     }
1011     return output;
1012 }
1013 
Activate(napi_env env,napi_callback_info info)1014 napi_value NapiAVSession::Activate(napi_env env, napi_callback_info info)
1015 {
1016     auto context = std::make_shared<ContextBase>();
1017     if (context == nullptr) {
1018         SLOGE("Activate failed : no memory");
1019         NapiUtils::ThrowError(env, "Activate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1020         return NapiUtils::GetUndefinedValue(env);
1021     }
1022 
1023     context->GetCbInfo(env, info);
1024 
1025     auto executor = [context]() {
1026         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1027         if (napiSession->session_ == nullptr) {
1028             context->status = napi_generic_failure;
1029             context->errMessage = "Activate session failed : session is nullptr";
1030             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1031             return;
1032         }
1033         int32_t ret = napiSession->session_->Activate();
1034         if (ret != AVSESSION_SUCCESS) {
1035             if (ret == ERR_SESSION_NOT_EXIST) {
1036                 context->errMessage = "Activate session failed : native session not exist";
1037             } else if (ret == ERR_NO_PERMISSION) {
1038                 context->errMessage = "Activate failed : native no permission";
1039             } else {
1040                 context->errMessage = "Activate session failed : native server exception";
1041             }
1042             context->status = napi_generic_failure;
1043             context->errCode = NapiAVSessionManager::errcode_[ret];
1044         }
1045     };
1046     auto complete = [env](napi_value& output) {
1047         output = NapiUtils::GetUndefinedValue(env);
1048     };
1049     return NapiAsyncWork::Enqueue(env, context, "Activate", executor, complete);
1050 }
1051 
Deactivate(napi_env env,napi_callback_info info)1052 napi_value NapiAVSession::Deactivate(napi_env env, napi_callback_info info)
1053 {
1054     auto context = std::make_shared<ContextBase>();
1055     if (context == nullptr) {
1056         SLOGE("Deactivate failed : no memory");
1057         NapiUtils::ThrowError(env, "Deactivate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1058         return NapiUtils::GetUndefinedValue(env);
1059     }
1060 
1061     context->GetCbInfo(env, info);
1062 
1063     auto executor = [context]() {
1064         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1065         if (napiSession->session_ == nullptr) {
1066             context->status = napi_generic_failure;
1067             context->errMessage = "Deactivate session failed : session is nullptr";
1068             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1069             return;
1070         }
1071         int32_t ret = napiSession->session_->Deactivate();
1072         if (ret != AVSESSION_SUCCESS) {
1073             if (ret == ERR_SESSION_NOT_EXIST) {
1074                 context->errMessage = "Deactivate session failed : native session not exist";
1075             } else if (ret == ERR_NO_PERMISSION) {
1076                 context->errMessage = "Deactivate failed : native no permission";
1077             } else {
1078                 context->errMessage = "Deactivate session failed : native server exception";
1079             }
1080             context->status = napi_generic_failure;
1081             context->errCode = NapiAVSessionManager::errcode_[ret];
1082         }
1083     };
1084     auto complete = [env](napi_value& output) {
1085         output = NapiUtils::GetUndefinedValue(env);
1086     };
1087     return NapiAsyncWork::Enqueue(env, context, "Deactivate", executor, complete);
1088 }
1089 
Destroy(napi_env env,napi_callback_info info)1090 napi_value NapiAVSession::Destroy(napi_env env, napi_callback_info info)
1091 {
1092     auto context = std::make_shared<ContextBase>();
1093     if (context == nullptr) {
1094         SLOGE("Destroy failed : no memory");
1095         NapiUtils::ThrowError(env, "Destroy failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1096         return NapiUtils::GetUndefinedValue(env);
1097     }
1098 
1099     context->GetCbInfo(env, info);
1100 
1101     SLOGI("Destroy session begin");
1102     auto executor = [context]() {
1103         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1104         if (napiSession->session_ == nullptr) {
1105             context->status = napi_generic_failure;
1106             context->errMessage = "Destroy session failed : session is nullptr";
1107             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1108             return;
1109         }
1110         int32_t ret = napiSession->session_->Destroy();
1111         if (ret == AVSESSION_SUCCESS) {
1112             napiSession->session_ = nullptr;
1113             napiSession->callback_ = nullptr;
1114         } else if (ret == ERR_SESSION_NOT_EXIST) {
1115             context->status = napi_generic_failure;
1116             context->errMessage = "Destroy session failed : native session not exist";
1117             context->errCode = NapiAVSessionManager::errcode_[ret];
1118         } else if (ret == ERR_NO_PERMISSION) {
1119             context->status = napi_generic_failure;
1120             context->errMessage = "Destroy failed : native no permission";
1121             context->errCode = NapiAVSessionManager::errcode_[ret];
1122         } else {
1123             context->status = napi_generic_failure;
1124             context->errMessage = "Destroy session failed : native server exception";
1125             context->errCode = NapiAVSessionManager::errcode_[ret];
1126         }
1127     };
1128     auto complete = [env](napi_value& output) {
1129         output = NapiUtils::GetUndefinedValue(env);
1130     };
1131     return NapiAsyncWork::Enqueue(env, context, "Destroy", executor, complete);
1132 }
1133 
SetSessionEvent(napi_env env,napi_callback_info info)1134 napi_value NapiAVSession::SetSessionEvent(napi_env env, napi_callback_info info)
1135 {
1136     AVSESSION_TRACE_SYNC_START("NapiAVSession::SetSessionEvent");
1137     struct ConcreteContext : public ContextBase {
1138         std::string event_;
1139         AAFwk::WantParams args_;
1140     };
1141     auto context = std::make_shared<ConcreteContext>();
1142     if (context == nullptr) {
1143         SLOGE("SetSessionEvent failed : no memory");
1144         NapiUtils::ThrowError(env, "SetSessionEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1145         return NapiUtils::GetUndefinedValue(env);
1146     }
1147 
1148     auto inputParser = [env, context](size_t argc, napi_value* argv) {
1149         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid arguments",
1150             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1151         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->event_);
1152         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get event failed",
1153             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1154         context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->args_);
1155         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get args failed",
1156             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1157     };
1158     context->GetCbInfo(env, info, inputParser);
1159     context->taskId = NAPI_SET_AV_META_DATA_TASK_ID;
1160 
1161     auto executor = [context]() {
1162         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1163         if (napiSession->session_ == nullptr) {
1164             context->status = napi_generic_failure;
1165             context->errMessage = "SetSessionEvent failed : session is nullptr";
1166             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1167             return;
1168         }
1169         int32_t ret = napiSession->session_->SetSessionEvent(context->event_, context->args_);
1170         if (ret != AVSESSION_SUCCESS) {
1171             ErrCodeToMessage(ret, context->errMessage);
1172             context->status = napi_generic_failure;
1173             context->errCode = NapiAVSessionManager::errcode_[ret];
1174         }
1175     };
1176     auto complete = [env](napi_value& output) {
1177         output = NapiUtils::GetUndefinedValue(env);
1178     };
1179     return NapiAsyncWork::Enqueue(env, context, "SetSessionEvent", executor, complete);
1180 }
1181 
ReleaseCast(napi_env env,napi_callback_info info)1182 napi_value NapiAVSession::ReleaseCast(napi_env env, napi_callback_info info)
1183 {
1184 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1185     auto context = std::make_shared<ContextBase>();
1186     if (context == nullptr) {
1187         SLOGE("ReleaseCast failed : no memory");
1188         NapiUtils::ThrowError(env, "ReleaseCast failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1189         return NapiUtils::GetUndefinedValue(env);
1190     }
1191 
1192     context->GetCbInfo(env, info);
1193 
1194     auto executor = [context]() {
1195         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1196         if (napiSession->session_ == nullptr) {
1197             context->status = napi_generic_failure;
1198             context->errMessage = "ReleaseCast failed : session is nullptr";
1199             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1200             return;
1201         }
1202         int32_t ret = napiSession->session_->ReleaseCast();
1203         if (ret != AVSESSION_SUCCESS) {
1204             if (ret == ERR_SESSION_NOT_EXIST) {
1205                 context->errMessage = "ReleaseCast failed : native session not exist";
1206             } else if (ret == ERR_NO_PERMISSION) {
1207                 context->errMessage = "ReleaseCast failed : native no permission";
1208             } else {
1209                 context->errMessage = "ReleaseCast failed : native server exception";
1210             }
1211             context->status = napi_generic_failure;
1212             context->errCode = NapiAVSessionManager::errcode_[ret];
1213         }
1214     };
1215     auto complete = [env](napi_value& output) {
1216         output = NapiUtils::GetUndefinedValue(env);
1217     };
1218     return NapiAsyncWork::Enqueue(env, context, "ReleaseCast", executor, complete);
1219 #else
1220     return nullptr;
1221 #endif
1222 }
1223 
GetAllCastDisplays(napi_env env,napi_callback_info info)1224 napi_value NapiAVSession::GetAllCastDisplays(napi_env env, napi_callback_info info)
1225 {
1226 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1227     struct ConcreteContext : public ContextBase {
1228         std::vector<CastDisplayInfo> castDisplays_;
1229     };
1230     auto context = std::make_shared<ConcreteContext>();
1231     if (context == nullptr) {
1232         SLOGE("GetAllCastDisplays failed : no memory");
1233         NapiUtils::ThrowError(env, "GetAllCastDisplays failed : no memory",
1234             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1235         return NapiUtils::GetUndefinedValue(env);
1236     }
1237 
1238     context->GetCbInfo(env, info);
1239 
1240     auto executor = [context]() {
1241         auto* napiSession = reinterpret_cast<NapiAVSession*>(context->native);
1242         if (napiSession->session_ == nullptr) {
1243             context->status = napi_generic_failure;
1244             context->errMessage = "GetAllCastDisplays failed : session is nullptr";
1245             context->errCode = NapiAVSessionManager::errcode_[ERR_SESSION_NOT_EXIST];
1246             return;
1247         }
1248         int32_t ret = napiSession->session_->GetAllCastDisplays(context->castDisplays_);
1249         if (ret != AVSESSION_SUCCESS) {
1250             if (ret == ERR_SESSION_NOT_EXIST) {
1251                 context->errMessage = "GetAllCastDisplays failed : native session not exist";
1252             } else if (ret == ERR_NO_PERMISSION) {
1253                 context->errMessage = "GetAllCastDisplays failed : native no permission";
1254             } else {
1255                 context->errMessage = "GetAllCastDisplays failed : native server exception";
1256             }
1257             context->status = napi_generic_failure;
1258             context->errCode = NapiAVSessionManager::errcode_[ret];
1259         }
1260     };
1261 
1262     auto complete = [env, context](napi_value& output) {
1263         context->status = NapiUtils::SetValue(env, context->castDisplays_, output);
1264         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
1265             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1266     };
1267     return NapiAsyncWork::Enqueue(env, context, "GetAllCastDisplays", executor, complete);
1268 #else
1269     SLOGE("GetAllCastDisplays CASTPLUS_CAST_ENGINE_ENABLE is not support");
1270     return ThrowErrorAndReturn(env, "OnEvent failed : no memory", ERR_NO_MEMORY);
1271 #endif
1272 }
1273 
ErrCodeToMessage(int32_t errCode,std::string & message)1274 void NapiAVSession::ErrCodeToMessage(int32_t errCode, std::string& message)
1275 {
1276     switch (errCode) {
1277         case ERR_SESSION_NOT_EXIST:
1278             message = "SetSessionEvent failed : native session not exist";
1279             break;
1280         case ERR_INVALID_PARAM:
1281             message = "SetSessionEvent failed : native invalid parameters";
1282             break;
1283         case ERR_NO_PERMISSION:
1284             message = "SetSessionEvent failed : native no permission";
1285             break;
1286         default:
1287             message = "SetSessionEvent failed : native server exception";
1288             break;
1289     }
1290 }
1291 
OnPlay(napi_env env,NapiAVSession * napiSession,napi_value callback)1292 napi_status NapiAVSession::OnPlay(napi_env env, NapiAVSession* napiSession, napi_value callback)
1293 {
1294     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1295     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY);
1296     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1297     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1298         "NapiAVSessionCallback object is nullptr");
1299     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY, callback);
1300 }
1301 
OnPause(napi_env env,NapiAVSession * napiSession,napi_value callback)1302 napi_status NapiAVSession::OnPause(napi_env env, NapiAVSession* napiSession, napi_value callback)
1303 {
1304     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1305     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PAUSE);
1306     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1307     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1308         "NapiAVSessionCallback object is nullptr");
1309     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PAUSE, callback);
1310 }
1311 
OnStop(napi_env env,NapiAVSession * napiSession,napi_value callback)1312 napi_status NapiAVSession::OnStop(napi_env env, NapiAVSession* napiSession, napi_value callback)
1313 {
1314     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1315     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_STOP);
1316     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1317     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1318         "NapiAVSessionCallback object is nullptr");
1319     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_STOP, callback);
1320 }
1321 
OnPlayNext(napi_env env,NapiAVSession * napiSession,napi_value callback)1322 napi_status NapiAVSession::OnPlayNext(napi_env env, NapiAVSession* napiSession, napi_value callback)
1323 {
1324     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1325     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_NEXT);
1326     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1327     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1328         "NapiAVSessionCallback object is nullptr");
1329     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_NEXT, callback);
1330 }
1331 
OnPlayPrevious(napi_env env,NapiAVSession * napiSession,napi_value callback)1332 napi_status NapiAVSession::OnPlayPrevious(napi_env env, NapiAVSession* napiSession, napi_value callback)
1333 {
1334     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1335     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS);
1336     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1337     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1338         "NapiAVSessionCallback object is nullptr");
1339     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_PREVIOUS, callback);
1340 }
1341 
OnFastForward(napi_env env,NapiAVSession * napiSession,napi_value callback)1342 napi_status NapiAVSession::OnFastForward(napi_env env, NapiAVSession* napiSession, napi_value callback)
1343 {
1344     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1345     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_FAST_FORWARD);
1346     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1347     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1348         "NapiAVSessionCallback object is nullptr");
1349     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_FAST_FORWARD, callback);
1350 }
1351 
OnRewind(napi_env env,NapiAVSession * napiSession,napi_value callback)1352 napi_status NapiAVSession::OnRewind(napi_env env, NapiAVSession* napiSession, napi_value callback)
1353 {
1354     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1355     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_REWIND);
1356     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1357     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1358         "NapiAVSessionCallback object is nullptr");
1359     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_REWIND, callback);
1360 }
1361 
OnSeek(napi_env env,NapiAVSession * napiSession,napi_value callback)1362 napi_status NapiAVSession::OnSeek(napi_env env, NapiAVSession* napiSession, napi_value callback)
1363 {
1364     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1365     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SEEK);
1366     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1367     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1368         "NapiAVSessionCallback object is nullptr");
1369     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SEEK, callback);
1370 }
1371 
OnSetSpeed(napi_env env,NapiAVSession * napiSession,napi_value callback)1372 napi_status NapiAVSession::OnSetSpeed(napi_env env, NapiAVSession* napiSession, napi_value callback)
1373 {
1374     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1375     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SET_SPEED);
1376     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1377     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1378         "NapiAVSessionCallback object is nullptr");
1379     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SET_SPEED, callback);
1380 }
1381 
OnSetLoopMode(napi_env env,NapiAVSession * napiSession,napi_value callback)1382 napi_status NapiAVSession::OnSetLoopMode(napi_env env, NapiAVSession* napiSession, napi_value callback)
1383 {
1384     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1385     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
1386     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1387     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1388         "NapiAVSessionCallback object is nullptr");
1389     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SET_LOOP_MODE, callback);
1390 }
1391 
OnToggleFavorite(napi_env env,NapiAVSession * napiSession,napi_value callback)1392 napi_status NapiAVSession::OnToggleFavorite(napi_env env, NapiAVSession* napiSession, napi_value callback)
1393 {
1394     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1395     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE);
1396     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1397     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1398         "NapiAVSessionCallback object is nullptr");
1399     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE, callback);
1400 }
1401 
OnMediaKeyEvent(napi_env env,NapiAVSession * napiSession,napi_value callback)1402 napi_status NapiAVSession::OnMediaKeyEvent(napi_env env, NapiAVSession* napiSession, napi_value callback)
1403 {
1404     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1405     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_MEDIA_KEY_SUPPORT);
1406     SLOGI("add media key event listen ret %{public}d", static_cast<int>(ret));
1407     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1408         "NapiAVSessionCallback object is nullptr");
1409     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT, callback);
1410 }
1411 
OnOutputDeviceChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1412 napi_status NapiAVSession::OnOutputDeviceChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1413 {
1414     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1415         "NapiAVSessionCallback object is nullptr");
1416     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_OUTPUT_DEVICE_CHANGE, callback);
1417 }
1418 
OnCommonCommand(napi_env env,NapiAVSession * napiSession,napi_value callback)1419 napi_status NapiAVSession::OnCommonCommand(napi_env env, NapiAVSession* napiSession, napi_value callback)
1420 {
1421     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SEND_COMMON_COMMAND, callback);
1422 }
1423 
OnSkipToQueueItem(napi_env env,NapiAVSession * napiSession,napi_value callback)1424 napi_status NapiAVSession::OnSkipToQueueItem(napi_env env, NapiAVSession* napiSession, napi_value callback)
1425 {
1426     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_SKIP_TO_QUEUE_ITEM, callback);
1427 }
1428 
OnAVCallAnswer(napi_env env,NapiAVSession * napiSession,napi_value callback)1429 napi_status NapiAVSession::OnAVCallAnswer(napi_env env, NapiAVSession* napiSession, napi_value callback)
1430 {
1431     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1432     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_AVCALL_ANSWER);
1433     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1434     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1435         "NapiAVSessionCallback object is nullptr");
1436     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_AVCALL_ANSWER, callback);
1437 }
1438 
OnAVCallHangUp(napi_env env,NapiAVSession * napiSession,napi_value callback)1439 napi_status NapiAVSession::OnAVCallHangUp(napi_env env, NapiAVSession* napiSession, napi_value callback)
1440 {
1441     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1442     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_AVCALL_HANG_UP);
1443     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1444     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1445         "NapiAVSessionCallback object is nullptr");
1446     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_AVCALL_HANG_UP, callback);
1447 }
1448 
OnAVCallToggleCallMute(napi_env env,NapiAVSession * napiSession,napi_value callback)1449 napi_status NapiAVSession::OnAVCallToggleCallMute(napi_env env, NapiAVSession* napiSession, napi_value callback)
1450 {
1451     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1452     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_AVCALL_TOGGLE_CALL_MUTE);
1453     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1454     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1455         "NapiAVSessionCallback object is nullptr");
1456     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_AVCALL_TOGGLE_CALL_MUTE, callback);
1457 }
1458 
OnPlayFromAssetId(napi_env env,NapiAVSession * napiSession,napi_value callback)1459 napi_status NapiAVSession::OnPlayFromAssetId(napi_env env, NapiAVSession* napiSession, napi_value callback)
1460 {
1461     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure, "session_ is nullptr");
1462     int32_t ret = napiSession->session_->AddSupportCommand(AVControlCommand::SESSION_CMD_PLAY_FROM_ASSETID);
1463     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add command failed");
1464     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1465         "NapiAVSessionCallback object is nullptr");
1466     return napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_PLAY_FROM_ASSETID, callback);
1467 }
1468 
OnCastDisplayChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1469 napi_status NapiAVSession::OnCastDisplayChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1470 {
1471 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1472     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1473                              "NapiAVSessionCallback object is nullptr");
1474     auto status = napiSession->callback_->AddCallback(env, NapiAVSessionCallback::EVENT_DISPLAY_CHANGE, callback);
1475     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "AddCallback failed");
1476     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1477                              "NapiAVSession object is nullptr");
1478     napiSession->session_->StartCastDisplayListener();
1479 #else
1480     return napi_generic_failure;
1481 #endif
1482     return napi_ok;
1483 }
1484 
OffPlay(napi_env env,NapiAVSession * napiSession,napi_value callback)1485 napi_status NapiAVSession::OffPlay(napi_env env, NapiAVSession* napiSession, napi_value callback)
1486 {
1487     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1488     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1489         "NapiAVSessionCallback object is nullptr");
1490     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY, callback);
1491     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1492     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY)) {
1493         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1494                                  "NapiAVSession object is nullptr");
1495         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY);
1496         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1497     }
1498     return napi_ok;
1499 }
1500 
OffPause(napi_env env,NapiAVSession * napiSession,napi_value callback)1501 napi_status NapiAVSession::OffPause(napi_env env, NapiAVSession* napiSession, napi_value callback)
1502 {
1503     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1504     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1505         "NapiAVSessionCallback object is nullptr");
1506     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PAUSE, callback);
1507     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1508     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PAUSE)) {
1509         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1510                                  "NapiAVSession object is nullptr");
1511         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PAUSE);
1512         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1513     }
1514     return napi_ok;
1515 }
1516 
OffStop(napi_env env,NapiAVSession * napiSession,napi_value callback)1517 napi_status NapiAVSession::OffStop(napi_env env, NapiAVSession* napiSession, napi_value callback)
1518 {
1519     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1520     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1521         "NapiAVSessionCallback object is nullptr");
1522     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_STOP, callback);
1523     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1524     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_STOP)) {
1525         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1526                                  "NapiAVSession object is nullptr");
1527         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_STOP);
1528         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1529     }
1530     return napi_ok;
1531 }
1532 
OffPlayNext(napi_env env,NapiAVSession * napiSession,napi_value callback)1533 napi_status NapiAVSession::OffPlayNext(napi_env env, NapiAVSession* napiSession, napi_value callback)
1534 {
1535     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1536     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1537         "NapiAVSessionCallback object is nullptr");
1538     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_NEXT, callback);
1539     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1540     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_NEXT)) {
1541         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1542                                  "NapiAVSession object is nullptr");
1543         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_NEXT);
1544         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1545     }
1546     return napi_ok;
1547 }
1548 
OffPlayPrevious(napi_env env,NapiAVSession * napiSession,napi_value callback)1549 napi_status NapiAVSession::OffPlayPrevious(napi_env env, NapiAVSession* napiSession, napi_value callback)
1550 {
1551     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1552     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1553         "NapiAVSessionCallback object is nullptr");
1554     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_PREVIOUS, callback);
1555     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1556 
1557     if (napiSession->callback_ &&
1558         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_PREVIOUS)) {
1559         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1560                                  "NapiAVSession object is nullptr");
1561         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS);
1562         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1563     }
1564     return napi_ok;
1565 }
1566 
OffFastForward(napi_env env,NapiAVSession * napiSession,napi_value callback)1567 napi_status NapiAVSession::OffFastForward(napi_env env, NapiAVSession* napiSession, napi_value callback)
1568 {
1569     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1570     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1571         "NapiAVSessionCallback object is nullptr");
1572     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_FAST_FORWARD, callback);
1573     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1574     if (napiSession->callback_ &&
1575         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_FAST_FORWARD)) {
1576         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1577                                  "NapiAVSession object is nullptr");
1578         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_FAST_FORWARD);
1579         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1580     }
1581     return napi_ok;
1582 }
1583 
OffRewind(napi_env env,NapiAVSession * napiSession,napi_value callback)1584 napi_status NapiAVSession::OffRewind(napi_env env, NapiAVSession* napiSession, napi_value callback)
1585 {
1586     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1587     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1588         "NapiAVSessionCallback object is nullptr");
1589     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_REWIND, callback);
1590     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1591     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_REWIND)) {
1592         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1593                                  "NapiAVSession object is nullptr");
1594         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_REWIND);
1595         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1596     }
1597     return napi_ok;
1598 }
1599 
OffSeek(napi_env env,NapiAVSession * napiSession,napi_value callback)1600 napi_status NapiAVSession::OffSeek(napi_env env, NapiAVSession* napiSession, napi_value callback)
1601 {
1602     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1603     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1604         "NapiAVSessionCallback object is nullptr");
1605     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SEEK, callback);
1606     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1607     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SEEK)) {
1608         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1609                                  "NapiAVSession object is nullptr");
1610         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SEEK);
1611         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1612     }
1613     return napi_ok;
1614 }
1615 
OffSetSpeed(napi_env env,NapiAVSession * napiSession,napi_value callback)1616 napi_status NapiAVSession::OffSetSpeed(napi_env env, NapiAVSession* napiSession, napi_value callback)
1617 {
1618     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1619     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1620         "NapiAVSessionCallback object is nullptr");
1621     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SET_SPEED, callback);
1622     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1623     if (napiSession->callback_ && napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SET_SPEED)) {
1624         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1625                                  "NapiAVSession_session is nullptr");
1626         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SET_SPEED);
1627         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1628     }
1629     return napi_ok;
1630 }
1631 
OffSetLoopMode(napi_env env,NapiAVSession * napiSession,napi_value callback)1632 napi_status NapiAVSession::OffSetLoopMode(napi_env env, NapiAVSession* napiSession, napi_value callback)
1633 {
1634     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1635     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1636         "NapiAVSessionCallback object is nullptr");
1637     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SET_LOOP_MODE, callback);
1638     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1639     if (napiSession->callback_ &&
1640         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_SET_LOOP_MODE)) {
1641         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1642                                  "NapiAVSession object is nullptr");
1643         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
1644         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1645     }
1646     return napi_ok;
1647 }
1648 
OffToggleFavorite(napi_env env,NapiAVSession * napiSession,napi_value callback)1649 napi_status NapiAVSession::OffToggleFavorite(napi_env env, NapiAVSession* napiSession, napi_value callback)
1650 {
1651     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1652     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1653         "NapiAVSessionCallback object is nullptr");
1654     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE, callback);
1655     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1656     if (napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_TOGGLE_FAVORITE)) {
1657         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1658                                  "NapiAVSession object is nullptr");
1659         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE);
1660         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1661     }
1662     return napi_ok;
1663 }
1664 
OffMediaKeyEvent(napi_env env,NapiAVSession * napiSession,napi_value callback)1665 napi_status NapiAVSession::OffMediaKeyEvent(napi_env env, NapiAVSession* napiSession, napi_value callback)
1666 {
1667     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1668     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1669         "NapiAVSessionCallback object is nullptr");
1670     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT, callback);
1671     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1672     if (napiSession->callback_ &&
1673         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_MEDIA_KEY_EVENT)) {
1674         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1675                                  "NapiAVSession object is nullptr");
1676         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_MEDIA_KEY_SUPPORT);
1677         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1678     }
1679     return napi_ok;
1680 }
1681 
OffOutputDeviceChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1682 napi_status NapiAVSession::OffOutputDeviceChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1683 {
1684     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1685     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1686         "NapiAVSessionCallback object is nullptr");
1687     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_OUTPUT_DEVICE_CHANGE, callback);
1688 }
1689 
OffCommonCommand(napi_env env,NapiAVSession * napiSession,napi_value callback)1690 napi_status NapiAVSession::OffCommonCommand(napi_env env, NapiAVSession* napiSession, napi_value callback)
1691 {
1692     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SEND_COMMON_COMMAND, callback);
1693 }
1694 
OffSkipToQueueItem(napi_env env,NapiAVSession * napiSession,napi_value callback)1695 napi_status NapiAVSession::OffSkipToQueueItem(napi_env env, NapiAVSession* napiSession, napi_value callback)
1696 {
1697     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1698     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1699         "NapiAVSessionCallback object is nullptr");
1700     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_SKIP_TO_QUEUE_ITEM, callback);
1701 }
1702 
OffAVCallAnswer(napi_env env,NapiAVSession * napiSession,napi_value callback)1703 napi_status NapiAVSession::OffAVCallAnswer(napi_env env, NapiAVSession* napiSession, napi_value callback)
1704 {
1705     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1706     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1707         "NapiAVSessionCallback object is nullptr");
1708     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_AVCALL_ANSWER, callback);
1709 }
1710 
OffAVCallHangUp(napi_env env,NapiAVSession * napiSession,napi_value callback)1711 napi_status NapiAVSession::OffAVCallHangUp(napi_env env, NapiAVSession* napiSession, napi_value callback)
1712 {
1713     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1714     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1715         "NapiAVSessionCallback object is nullptr");
1716     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_AVCALL_HANG_UP, callback);
1717 }
1718 
OffAVCallToggleCallMute(napi_env env,NapiAVSession * napiSession,napi_value callback)1719 napi_status NapiAVSession::OffAVCallToggleCallMute(napi_env env, NapiAVSession* napiSession, napi_value callback)
1720 {
1721     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1722     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1723         "NapiAVSessionCallback object is nullptr");
1724     return napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_AVCALL_TOGGLE_CALL_MUTE, callback);
1725 }
1726 
OffPlayFromAssetId(napi_env env,NapiAVSession * napiSession,napi_value callback)1727 napi_status NapiAVSession::OffPlayFromAssetId(napi_env env, NapiAVSession* napiSession, napi_value callback)
1728 {
1729     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1730     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1731         "NapiAVSessionCallback object is nullptr");
1732     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_PLAY_FROM_ASSETID, callback);
1733     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1734 
1735     if (napiSession->callback_ &&
1736         napiSession->callback_->IsCallbacksEmpty(NapiAVSessionCallback::EVENT_PLAY_FROM_ASSETID)) {
1737         CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1738                                  "NapiAVSession object is nullptr");
1739         int32_t ret = napiSession->session_->DeleteSupportCommand(AVControlCommand::SESSION_CMD_PLAY_FROM_ASSETID);
1740         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "delete cmd failed");
1741     }
1742     return napi_ok;
1743 }
1744 
OffCastDisplayChange(napi_env env,NapiAVSession * napiSession,napi_value callback)1745 napi_status NapiAVSession::OffCastDisplayChange(napi_env env, NapiAVSession* napiSession, napi_value callback)
1746 {
1747 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1748     CHECK_AND_RETURN_RET_LOG(napiSession != nullptr, napi_generic_failure, "input param is nullptr");
1749     CHECK_AND_RETURN_RET_LOG(napiSession->callback_ != nullptr, napi_generic_failure,
1750                              "NapiAVSessionCallback object is nullptr");
1751     auto status = napiSession->callback_->RemoveCallback(env, NapiAVSessionCallback::EVENT_DISPLAY_CHANGE, callback);
1752     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1753     CHECK_AND_RETURN_RET_LOG(napiSession->session_ != nullptr, napi_generic_failure,
1754                              "NapiAVSession object is nullptr");
1755     napiSession->session_->StopCastDisplayListener();
1756 #else
1757     return napi_generic_failure;
1758 #endif
1759     return napi_ok;
1760 }
1761 }
1762