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