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