• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "key_event.h"
17 #include "napi_async_work.h"
18 #include "napi_avcast_controller_callback.h"
19 #include "napi_cast_control_command.h"
20 #include "napi_meta_data.h"
21 #include "napi_playback_state.h"
22 #include "napi_utils.h"
23 #include "napi_media_description.h"
24 #include "napi_queue_item.h"
25 #include "want_agent.h"
26 #include "avsession_errors.h"
27 #include "avsession_trace.h"
28 #include "napi_avsession_manager.h"
29 #include "ipc_skeleton.h"
30 #include "tokenid_kit.h"
31 #include "napi_avcast_controller.h"
32 #include "avsession_radar.h"
33 #include "curl/curl.h"
34 #include "image_source.h"
35 #include "pixel_map.h"
36 #include "avsession_pixel_map_adapter.h"
37 #include "avsession_event_handler.h"
38 
39 namespace OHOS::AVSession {
40 
41 static __thread napi_ref AVCastControllerConstructorRef = nullptr;
42 std::map<std::string, std::pair<NapiAVCastController::OnEventHandlerType,
43     NapiAVCastController::OffEventHandlerType>> NapiAVCastController::EventHandlers_ = {
44     { "playbackStateChange", { OnPlaybackStateChange, OffPlaybackStateChange } },
45     { "mediaItemChange", { OnMediaItemChange, OffMediaItemChange } },
46     { "playNext", { OnPlayNext, OffPlayNext } },
47     { "playPrevious", { OnPlayPrevious, OffPlayPrevious } },
48     { "requestPlay", { OnRequestPlay, OffRequestPlay } },
49     { "seekDone", { OnSeekDone, OffSeekDone } },
50     { "validCommandChange", { OnValidCommandChange, OffValidCommandChange } },
51     { "videoSizeChange", { OnVideoSizeChange, OffVideoSizeChange } }, // timeUpdate -> videoSizeChange
52     { "error", { OnPlayerError, OffPlayerError } },
53     { "castControlGenericError", { OnCastControlGenericError, OffCastControlGenericError } },
54     { "castControlIoError", { OnCastControlIoError, OffCastControlIoError } },
55     { "castControlParsingError", { OnCastControlParsingError, OffCastControlParsingError } },
56     { "castControlDecodingError", { OnCastControlDecodingError, OffCastControlDecodingError } },
57     { "castControlAudioRendererError", { OnCastControlAudioRendererError, OffCastControlAudioRendererError } },
58     { "castControlDrmError", { OnCastControlDrmError, OffCastControlDrmError } },
59     { "endOfStream", { OnEndOfStream, OffEndOfStream } },
60     { "requestPlay", { OnPlayRequest, OffPlayRequest } },
61     { "keyRequest", { OnKeyRequest, OffKeyRequest } },
62 };
63 
NapiAVCastController()64 NapiAVCastController::NapiAVCastController()
65 {
66     SLOGI("NapiAVCastController construct");
67 }
68 
~NapiAVCastController()69 NapiAVCastController::~NapiAVCastController()
70 {
71     SLOGI("NapiAVCastController destroy");
72 }
73 
Init(napi_env env,napi_value exports)74 napi_value NapiAVCastController::Init(napi_env env, napi_value exports)
75 {
76     napi_property_descriptor descriptors[] = {
77         DECLARE_NAPI_FUNCTION("on", OnEvent),
78         DECLARE_NAPI_FUNCTION("off", OffEvent),
79         DECLARE_NAPI_FUNCTION("start", Start),
80         DECLARE_NAPI_FUNCTION("prepare", Prepare),
81         DECLARE_NAPI_FUNCTION("sendControlCommand", SendControlCommand),
82         DECLARE_NAPI_FUNCTION("getDuration", GetDuration),
83         DECLARE_NAPI_FUNCTION("getAVPlaybackState", GetCastAVPlaybackState),
84         DECLARE_NAPI_FUNCTION("getSupportedDecoders", GetSupportedDecoders),
85         DECLARE_NAPI_FUNCTION("getRecommendedResolutionLevel", GetRecommendedResolutionLevel),
86         DECLARE_NAPI_FUNCTION("getSupportedHdrCapabilities", GetSupportedHdrCapabilities),
87         DECLARE_NAPI_FUNCTION("getSupportedPlaySpeeds", GetSupportedPlaySpeeds),
88         DECLARE_NAPI_FUNCTION("getCurrentItem", GetCurrentItem),
89         DECLARE_NAPI_FUNCTION("getValidCommands", GetValidCommands),
90         DECLARE_NAPI_FUNCTION("release", Release),
91         DECLARE_NAPI_FUNCTION("setDisplaySurface", SetDisplaySurface),
92         DECLARE_NAPI_FUNCTION("processMediaKeyResponse", ProcessMediaKeyResponse),
93     };
94 
95     auto property_count = sizeof(descriptors) / sizeof(napi_property_descriptor);
96     napi_value constructor {};
97     auto status = napi_define_class(env, "AVCastController", NAPI_AUTO_LENGTH, ConstructorCallback, nullptr,
98         property_count, descriptors, &constructor);
99     if (status != napi_ok) {
100         SLOGE("define class failed");
101         return NapiUtils::GetUndefinedValue(env);
102     }
103     napi_create_reference(env, constructor, 1, &AVCastControllerConstructorRef);
104     return exports;
105 }
106 
ConstructorCallback(napi_env env,napi_callback_info info)107 napi_value NapiAVCastController::ConstructorCallback(napi_env env, napi_callback_info info)
108 {
109     napi_value self;
110     NAPI_CALL_BASE(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr), nullptr);
111 
112     auto finalize = [](napi_env env, void* data, void* hint) {
113         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(data);
114         napi_delete_reference(env, napiCastController->wrapperRef_);
115         delete napiCastController;
116         napiCastController = nullptr;
117     };
118 
119     auto* napiCastController = new(std::nothrow) NapiAVCastController();
120     if (napiCastController == nullptr) {
121         SLOGE("no memory");
122         return nullptr;
123     }
124     //The last parameter of napi_wrap must be null
125     if (napi_wrap(env, self, static_cast<void*>(napiCastController), finalize,
126         &(napiCastController->wrapperRef_),  nullptr) != napi_ok) {
127         SLOGE("wrap failed");
128         return nullptr;
129     }
130     return self;
131 }
132 
NewInstance(napi_env env,std::shared_ptr<AVCastController> & nativeController,napi_value & out)133 napi_status NapiAVCastController::NewInstance(napi_env env, std::shared_ptr<AVCastController>& nativeController,
134     napi_value& out)
135 {
136     napi_value constructor {};
137     NAPI_CALL_BASE(env, napi_get_reference_value(env, AVCastControllerConstructorRef, &constructor),
138         napi_generic_failure);
139     napi_value instance {};
140     NAPI_CALL_BASE(env, napi_new_instance(env, constructor, 0, nullptr, &instance), napi_generic_failure);
141     NapiAVCastController* napiCastController {};
142     NAPI_CALL_BASE(env, napi_unwrap(env, instance, reinterpret_cast<void**>(&napiCastController)),
143         napi_generic_failure);
144     napiCastController->castController_ = std::move(nativeController);
145 
146     out = instance;
147     return napi_ok;
148 }
149 
SendControlCommand(napi_env env,napi_callback_info info)150 napi_value NapiAVCastController::SendControlCommand(napi_env env, napi_callback_info info)
151 {
152     AVSESSION_TRACE_SYNC_START("NapiAVCastController::SendControlCommand");
153     struct ConcrentContext : public ContextBase {
154         AVCastControlCommand castCommand_;
155     };
156     auto context = std::make_shared<ConcrentContext>();
157     auto input = [env, context](size_t argc, napi_value* argv) {
158         CheckSendCtrlCmdReportRadar((argc == ARGC_ONE), ERR_INVALID_PARAM);
159         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
160             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
161 
162         context->status = NapiCastControlCommand::GetValue(env, argv[ARGV_FIRST], context->castCommand_);
163         CheckSendCtrlCmdReportRadar((context->status == napi_ok), ERR_INVALID_PARAM);
164         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok), "invalid command",
165             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
166     };
167     context->GetCbInfo(env, info, input);
168     context->taskId = NAPI_CAST_CONTROLLER_SEND_CONTROL_COMMAND_TASK_ID;
169 
170     auto executor = [context]() {
171         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
172         if (napiCastController->castController_ == nullptr) {
173             SLOGE("SendControlCommand failed : controller is nullptr");
174             context->status = napi_generic_failure;
175             context->errMessage = "SendControlCommand failed : controller is nullptr";
176             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
177             ReportSendControlCommandFailInfo(ERR_CONTROLLER_NOT_EXIST);
178             return;
179         }
180 
181         int32_t ret = napiCastController->castController_->SendControlCommand(context->castCommand_);
182         if (ret != AVSESSION_SUCCESS) {
183             context->errMessage = GetSendControlCommandErrMsg(ret);
184             context->status = napi_generic_failure;
185             context->errCode = NapiAVSessionManager::errcode_[ret];
186             ReportSendControlCommandFailInfo(ret);
187         }
188     };
189 
190     return NapiAsyncWork::Enqueue(env, context, "SendControlCommand", executor);
191 }
192 
Start(napi_env env,napi_callback_info info)193 napi_value NapiAVCastController::Start(napi_env env, napi_callback_info info)
194 {
195     AVSESSION_TRACE_SYNC_START("NapiAVCastController::Start");
196     struct ConcreteContext : public ContextBase {
197         AVQueueItem avQueueItem_;
198     };
199     auto context = std::make_shared<ConcreteContext>();
200     if (context == nullptr) {
201         SLOGE("Start failed : no memory");
202         ReportStartFailInfo(ERR_NO_MEMORY);
203         NapiUtils::ThrowError(env, "Start failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
204         return NapiUtils::GetUndefinedValue(env);
205     }
206 
207     auto inputParser = [env, context](size_t argc, napi_value* argv) {
208         int napiErr = NapiAVSessionManager::errcode_[ERR_INVALID_PARAM];
209         CheckStartReportRadar((argc == ARGC_ONE), ERR_INVALID_PARAM);
210         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "Invalid arguments", napiErr);
211         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
212         if (napiCastController->callback_ != nullptr) {
213             napiCastController->callback_->saveDataSrc(env, argv[ARGV_FIRST]);
214         }
215 
216         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->avQueueItem_);
217         CheckStartReportRadar((context->status == napi_ok), ERR_INVALID_PARAM);
218         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "Get play queue item failed", napiErr);
219     };
220     context->GetCbInfo(env, info, inputParser);
221     context->taskId = NAPI_CAST_CONTROLLER_START_TASK_ID;
222 
223     auto executor = [context]() {
224         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
225         if (napiCastController->castController_ == nullptr) {
226             SLOGE("Start failed : controller is nullptr");
227             context->status = napi_generic_failure;
228             context->errMessage = "Start failed : castController_ is nullptr";
229             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
230             ReportStartFailInfo(ERR_CONTROLLER_NOT_EXIST);
231             return;
232         }
233         int32_t ret = napiCastController->castController_->Start(context->avQueueItem_);
234         if (ret != AVSESSION_SUCCESS) {
235             ErrCodeToMessage(ret, context->errMessage);
236             SLOGE("CastController Start failed:%{public}d", ret);
237             context->status = napi_generic_failure;
238             context->errCode = NapiAVSessionManager::errcode_[ret];
239             ReportStartFailInfo(ret);
240         }
241     };
242 
243     auto complete = [env](napi_value& output) {
244         output = NapiUtils::GetUndefinedValue(env);
245     };
246     return NapiAsyncWork::Enqueue(env, context, "Start", executor, complete);
247 }
248 
DownloadCastImg(std::shared_ptr<AVMediaDescription> description,const std::string & uri)249 int32_t NapiAVCastController::DownloadCastImg(std::shared_ptr<AVMediaDescription> description, const std::string& uri)
250 {
251     SLOGI("DownloadCastImg with title %{public}s", description->GetTitle().c_str());
252 
253     std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
254     bool ret = NapiUtils::DoDownloadInCommon(pixelMap, uri);
255     SLOGI("DownloadCastImg with ret %{public}d, %{public}d",
256         static_cast<int>(ret), static_cast<int>(pixelMap == nullptr));
257     if (ret && pixelMap != nullptr) {
258         SLOGI("DownloadCastImg success");
259         description->SetIcon(AVSessionPixelMapAdapter::ConvertToInnerWithLimitedSize(pixelMap));
260         return AVSESSION_SUCCESS;
261     }
262     return AVSESSION_ERROR;
263 }
264 
PrepareAsyncExecutor(NapiAVCastController * napiCastController,AVQueueItem & data)265 std::function<void()> NapiAVCastController::PrepareAsyncExecutor(NapiAVCastController* napiCastController,
266     AVQueueItem& data)
267 {
268     return [napiCastController, data]() {
269         if (napiCastController->castController_ == nullptr) {
270             return;
271         }
272         SLOGI("do prepare set with online download prepare with uri alive");
273         std::shared_ptr<AVMediaDescription> description = data.GetDescription();
274         if (description == nullptr) {
275             SLOGE("do prepare download image description is null");
276             return;
277         }
278         auto uri = description->GetIconUri() == "" ?
279             description->GetAlbumCoverUri() : description->GetIconUri();
280         AVQueueItem item;
281         if (description->GetIcon() == nullptr && !uri.empty()) {
282             auto ret = DownloadCastImg(description, uri);
283             SLOGI("DownloadCastImg complete with ret %{public}d", ret);
284             if (ret != AVSESSION_SUCCESS) {
285                 SLOGE("DownloadCastImg failed but not repeat setmetadata again");
286             } else {
287                 description->SetIconUri("URI_CACHE");
288                 item.SetDescription(description);
289                 auto ret = napiCastController->castController_->Prepare(item);
290                 SLOGI("do prepare set second with ret %{public}d", ret);
291             }
292         }
293     };
294 }
295 
Prepare(napi_env env,napi_callback_info info)296 napi_value NapiAVCastController::Prepare(napi_env env, napi_callback_info info)
297 {
298     AVSESSION_TRACE_SYNC_START("NapiAVCastController::Prepare");
299     struct ConcreteContext : public ContextBase {
300         AVQueueItem avQueueItem_;
301     };
302     auto context = std::make_shared<ConcreteContext>();
303     if (context == nullptr) {
304         SLOGE("Prepare failed : no memory");
305         NapiUtils::ThrowError(env, "Prepare failed : no memory",
306             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
307         return NapiUtils::GetUndefinedValue(env);
308     }
309 
310     auto inputParser = [env, context](size_t argc, napi_value* argv) {
311         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "Invalid arguments",
312             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
313         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
314         if (napiCastController->callback_ != nullptr) {
315             napiCastController->callback_->saveDataSrc(env, argv[ARGV_FIRST]);
316         }
317         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->avQueueItem_);
318         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "Get play queue item failed",
319             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
320     };
321     context->GetCbInfo(env, info, inputParser);
322     context->taskId = NAPI_CAST_CONTROLLER_PREPARE_TASK_ID;
323 
324     auto executor = [context]() {
325         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
326         if (napiCastController->castController_ == nullptr) {
327             SLOGE("Prepare failed : controller is nullptr");
328             context->status = napi_generic_failure;
329             context->errMessage = "Prepare failed : castController_ is nullptr";
330             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
331             return;
332         }
333         int32_t ret = napiCastController->castController_->Prepare(context->avQueueItem_);
334         if (ret != AVSESSION_SUCCESS) {
335             ErrCodeToMessage(ret, context->errMessage);
336             SLOGE("CastController UpdateMediaInfo failed:%{public}d", ret);
337             context->status = napi_generic_failure;
338             context->errCode = NapiAVSessionManager::errcode_[ret];
339         }
340     };
341 
342     auto complete = [env, context](napi_value& output) {
343         output = NapiUtils::GetUndefinedValue(env);
344         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
345         auto asyncExecutor = PrepareAsyncExecutor(napiCastController, context->avQueueItem_);
346         CHECK_AND_PRINT_LOG(AVSessionEventHandler::GetInstance()
347             .AVSessionPostTask(asyncExecutor, "PrepareAsync"),
348             "NapiAVCastController PrepareAsync handler postTask failed");
349     };
350     return NapiAsyncWork::Enqueue(env, context, "Prepare", executor, complete);
351 }
352 
GetDuration(napi_env env,napi_callback_info info)353 napi_value NapiAVCastController::GetDuration(napi_env env, napi_callback_info info)
354 {
355     struct ConcreteContext : public ContextBase {
356         int32_t duration;
357     };
358     auto context = std::make_shared<ConcreteContext>();
359     context->GetCbInfo(env, info);
360     context->taskId = NAPI_CAST_CONTROLLER_GET_DURATION_TASK_ID;
361 
362     auto executor = [context]() {
363         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
364         if (napiCastController->castController_ == nullptr) {
365             SLOGE("GetDuration failed : controller is nullptr");
366             context->status = napi_generic_failure;
367             context->errMessage = "GetDuration failed : controller is nullptr";
368             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
369             return;
370         }
371         int32_t ret = napiCastController->castController_->GetDuration(context->duration);
372         if (ret != AVSESSION_SUCCESS) {
373             if (ret == ERR_SESSION_NOT_EXIST) {
374                 context->errMessage = "GetDuration failed : native session not exist";
375             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
376                 context->errMessage = "GetDuration failed : native controller not exist";
377             } else if (ret == ERR_NO_PERMISSION) {
378                 context->errMessage = "GetDuration failed : native no permission";
379             } else {
380                 context->errMessage = "GetDuration failed : native server exception";
381             }
382             SLOGE("controller GetDuration failed:%{public}d", ret);
383             context->status = napi_generic_failure;
384             context->errCode = NapiAVSessionManager::errcode_[ret];
385         }
386     };
387 
388     auto complete = [env, context](napi_value& output) {
389         context->duration = NapiUtils::SetValue(env, context->duration, output);
390         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
391             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
392     };
393     return NapiAsyncWork::Enqueue(env, context, "GetDuration", executor, complete);
394 }
395 
GetCastAVPlaybackState(napi_env env,napi_callback_info info)396 napi_value NapiAVCastController::GetCastAVPlaybackState(napi_env env, napi_callback_info info)
397 {
398     struct ConcreteContext : public ContextBase {
399         AVPlaybackState castAVPlaybackState_;
400     };
401     auto context = std::make_shared<ConcreteContext>();
402     context->GetCbInfo(env, info);
403     context->taskId = NAPI_CAST_CONTROLLER_GET_PLAY_STATE_TASK_ID;
404 
405     auto executor = [context]() {
406         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
407         if (napiCastController->castController_ == nullptr) {
408             SLOGE("GetCastAVPlaybackState failed : controller is nullptr");
409             context->status = napi_generic_failure;
410             context->errMessage = "GetCastAVPlaybackState failed : controller is nullptr";
411             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
412             return;
413         }
414         int32_t ret = napiCastController->castController_->GetCastAVPlaybackState(context->castAVPlaybackState_);
415         if (ret != AVSESSION_SUCCESS) {
416             if (ret == ERR_SESSION_NOT_EXIST) {
417                 context->errMessage = "GetCastAVPlaybackState failed : native session not exist";
418             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
419                 context->errMessage = "GetCastAVPlaybackState failed : native controller not exist";
420             } else if (ret == ERR_NO_PERMISSION) {
421                 context->errMessage = "GetCastAVPlaybackState failed : native no permission";
422             } else {
423                 context->errMessage = "GetCastAVPlaybackState failed : native server exception";
424             }
425             SLOGE("controller GetCastAVPlaybackState failed:%{public}d", ret);
426             context->status = napi_generic_failure;
427             context->errCode = NapiAVSessionManager::errcode_[ret];
428         }
429     };
430 
431     auto complete = [env, context](napi_value& output) {
432         context->status = NapiUtils::SetValue(env, context->castAVPlaybackState_, output);
433         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
434             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
435     };
436     return NapiAsyncWork::Enqueue(env, context, "GetCastAVPlaybackState", executor, complete);
437 }
438 
GetSupportedDecoders(napi_env env,napi_callback_info info)439 napi_value NapiAVCastController::GetSupportedDecoders(napi_env env, napi_callback_info info)
440 {
441     struct ConcreteContext : public ContextBase {
442         std::vector<std::string> decoderTypes;
443     };
444     auto context = std::make_shared<ConcreteContext>();
445     context->GetCbInfo(env, info);
446     context->taskId = NAPI_CAST_CONTROL_GET_SUPPORT_DECODER_ID;
447 
448     auto executor = [context]() {
449         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
450         if (napiCastController->castController_ == nullptr) {
451             SLOGE("GetSupportedDecoders failed : controller is nullptr");
452             context->status = napi_generic_failure;
453             context->errMessage = "GetSupportedDecoders failed : controller is nullptr";
454             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
455             return;
456         }
457         int32_t ret = napiCastController->castController_->GetSupportedDecoders(context->decoderTypes);
458         if (ret != AVSESSION_SUCCESS) {
459             if (ret == ERR_SESSION_NOT_EXIST) {
460                 context->errMessage = "GetSupportedDecoders failed : native session not exist";
461             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
462                 context->errMessage = "GetSupportedDecoders failed : native controller not exist";
463             } else if (ret == ERR_NO_PERMISSION) {
464                 context->errMessage = "GetSupportedDecoders failed : native no permission";
465             } else {
466                 context->errMessage = "GetSupportedDecoders failed : native server exception";
467             }
468             SLOGE("controller GetSupportedDecoders failed:%{public}d", ret);
469             context->status = napi_generic_failure;
470             context->errCode = NapiAVSessionManager::errcode_[ret];
471         }
472     };
473 
474     auto complete = [env, context](napi_value& output) {
475         context->status = NapiUtils::SetValue(env, context->decoderTypes, output);
476         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
477             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
478     };
479     return NapiAsyncWork::Enqueue(env, context, "GetSupportedDecoders", executor, complete);
480 }
481 
GetRecommendedResolutionLevel(napi_env env,napi_callback_info info)482 napi_value NapiAVCastController::GetRecommendedResolutionLevel(napi_env env, napi_callback_info info)
483 {
484     struct ConcreteContext : public ContextBase {
485         std::string decoderType;
486         ResolutionLevel resolutionLevel;
487     };
488     auto context = std::make_shared<ConcreteContext>();
489     auto input = [env, context](size_t argc, napi_value* argv) {
490         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
491             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
492 
493         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->decoderType);
494         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok), "invalid command",
495             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
496     };
497     context->GetCbInfo(env, info, input);
498     context->taskId = NAPI_CAST_CONTROL_GET_RECOMMEND_RESOLUTION_LEVEL_ID;
499 
500     auto executor = [context]() {
501         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
502         if (napiCastController->castController_ == nullptr) {
503             SLOGE("GetRecommendedResolutionLevel failed : controller is nullptr");
504             context->status = napi_generic_failure;
505             context->errMessage = "GetRecommendedResolutionLevel failed : controller is nullptr";
506             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
507             return;
508         }
509         int32_t ret = napiCastController->castController_->GetRecommendedResolutionLevel(
510             context->decoderType, context->resolutionLevel);
511         if (ret != AVSESSION_SUCCESS) {
512             if (ret == ERR_SESSION_NOT_EXIST) {
513                 context->errMessage = "GetRecommendedResolutionLevel failed : native session not exist";
514             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
515                 context->errMessage = "GetRecommendedResolutionLevel failed : native controller not exist";
516             } else if (ret == ERR_NO_PERMISSION) {
517                 context->errMessage = "GetRecommendedResolutionLevel failed : native no permission";
518             } else {
519                 context->errMessage = "GetRecommendedResolutionLevel failed : native server exception";
520             }
521             SLOGE("controller GetRecommendedResolutionLevel failed:%{public}d", ret);
522             context->status = napi_generic_failure;
523             context->errCode = NapiAVSessionManager::errcode_[ret];
524         }
525     };
526 
527     auto complete = [env, context](napi_value& output) {
528         context->status = NapiUtils::SetValue(env, context->resolutionLevel, output);
529         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
530             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
531     };
532     return NapiAsyncWork::Enqueue(env, context, "GetRecommendedResolutionLevel", executor, complete);
533 }
534 
GetSupportedHdrCapabilities(napi_env env,napi_callback_info info)535 napi_value NapiAVCastController::GetSupportedHdrCapabilities(napi_env env, napi_callback_info info)
536 {
537     struct ConcreteContext : public ContextBase {
538         std::vector<HDRFormat> hdrFormats;
539     };
540     auto context = std::make_shared<ConcreteContext>();
541     context->GetCbInfo(env, info);
542     context->taskId = NAPI_CAST_CONTROL_GET_SUPPORT_HDR_CAPABILITIES_ID;
543 
544     auto executor = [context]() {
545         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
546         if (napiCastController->castController_ == nullptr) {
547             SLOGE("GetSupportedHdrCapabilities failed : controller is nullptr");
548             context->status = napi_generic_failure;
549             context->errMessage = "GetSupportedHdrCapabilities failed : controller is nullptr";
550             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
551             return;
552         }
553         int32_t ret = napiCastController->castController_->GetSupportedHdrCapabilities(context->hdrFormats);
554         if (ret != AVSESSION_SUCCESS) {
555             if (ret == ERR_SESSION_NOT_EXIST) {
556                 context->errMessage = "GetSupportedHdrCapabilities failed : native session not exist";
557             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
558                 context->errMessage = "GetSupportedHdrCapabilities failed : native controller not exist";
559             } else if (ret == ERR_NO_PERMISSION) {
560                 context->errMessage = "GetSupportedHdrCapabilities failed : native no permission";
561             } else {
562                 context->errMessage = "GetSupportedHdrCapabilities failed : native server exception";
563             }
564             SLOGE("controller GetSupportedHdrCapabilities failed:%{public}d", ret);
565             context->status = napi_generic_failure;
566             context->errCode = NapiAVSessionManager::errcode_[ret];
567         }
568     };
569 
570     auto complete = [env, context](napi_value& output) {
571         context->status = NapiUtils::SetValue(env, context->hdrFormats, output);
572         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
573             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
574     };
575     return NapiAsyncWork::Enqueue(env, context, "GetSupportedHdrCapabilities", executor, complete);
576 }
577 
GetSupportedPlaySpeeds(napi_env env,napi_callback_info info)578 napi_value NapiAVCastController::GetSupportedPlaySpeeds(napi_env env, napi_callback_info info)
579 {
580     struct ConcreteContext : public ContextBase {
581         std::vector<float> playSpeeds;
582     };
583     auto context = std::make_shared<ConcreteContext>();
584     context->GetCbInfo(env, info);
585     context->taskId = NAPI_CAST_CONTROL_GET_SUPPORT_PLAY_SPEED_ID;
586 
587     auto executor = [context]() {
588         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
589         if (napiCastController->castController_ == nullptr) {
590             SLOGE("GetSupportedPlaySpeeds failed : controller is nullptr");
591             context->status = napi_generic_failure;
592             context->errMessage = "GetSupportedPlaySpeeds failed : controller is nullptr";
593             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
594             return;
595         }
596         int32_t ret = napiCastController->castController_->GetSupportedPlaySpeeds(context->playSpeeds);
597         if (ret != AVSESSION_SUCCESS) {
598             if (ret == ERR_SESSION_NOT_EXIST) {
599                 context->errMessage = "GetSupportedPlaySpeeds failed : native session not exist";
600             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
601                 context->errMessage = "GetSupportedPlaySpeeds failed : native controller not exist";
602             } else if (ret == ERR_NO_PERMISSION) {
603                 context->errMessage = "GetSupportedPlaySpeeds failed : native no permission";
604             } else {
605                 context->errMessage = "GetSupportedPlaySpeeds failed : native server exception";
606             }
607             SLOGE("controller GetSupportedPlaySpeeds failed:%{public}d", ret);
608             context->status = napi_generic_failure;
609             context->errCode = NapiAVSessionManager::errcode_[ret];
610         }
611     };
612 
613     auto complete = [env, context](napi_value& output) {
614         context->status = NapiUtils::SetValue(env, context->playSpeeds, output);
615         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
616             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
617     };
618     return NapiAsyncWork::Enqueue(env, context, "GetSupportedPlaySpeeds", executor, complete);
619 }
620 
GetCurrentItem(napi_env env,napi_callback_info info)621 napi_value NapiAVCastController::GetCurrentItem(napi_env env, napi_callback_info info)
622 {
623     struct ConcreteContext : public ContextBase {
624         AVQueueItem currentItem_;
625     };
626     auto context = std::make_shared<ConcreteContext>();
627     context->GetCbInfo(env, info);
628     context->taskId = NAPI_CAST_CONTROLLER_GET_CURRENT_ITEM_TASK_ID;
629 
630     auto executor = [context]() {
631         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
632         if (napiCastController->castController_ == nullptr) {
633             SLOGE("GetCurrentItem failed : controller is nullptr");
634             context->status = napi_generic_failure;
635             context->errMessage = "GetCurrentItem failed : controller is nullptr";
636             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
637             return;
638         }
639         int32_t ret = napiCastController->castController_->GetCurrentItem(context->currentItem_);
640         if (ret != AVSESSION_SUCCESS) {
641             if (ret == ERR_SESSION_NOT_EXIST) {
642                 context->errMessage = "GetCurrentItem failed : native session not exist";
643             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
644                 context->errMessage = "GetCurrentItem failed : native controller not exist";
645             } else if (ret == ERR_NO_PERMISSION) {
646                 context->errMessage = "GetCurrentItem failed : native no permission";
647             } else {
648                 context->errMessage = "GetCurrentItem failed : native server exception";
649             }
650             SLOGE("controller GetCurrentItem failed:%{public}d", ret);
651             context->status = napi_generic_failure;
652             context->errCode = NapiAVSessionManager::errcode_[ret];
653         }
654     };
655 
656     auto complete = [env, context](napi_value& output) {
657         context->status = NapiUtils::SetValue(env, context->currentItem_, output);
658         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
659             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
660     };
661     return NapiAsyncWork::Enqueue(env, context, "GetCurrentItem", executor, complete);
662 }
663 
GetValidCommands(napi_env env,napi_callback_info info)664 napi_value NapiAVCastController::GetValidCommands(napi_env env, napi_callback_info info)
665 {
666     struct ConcreteContext : public ContextBase {
667         std::vector<std::string> stringCmds;
668     };
669     auto context = std::make_shared<ConcreteContext>();
670     context->GetCbInfo(env, info);
671     context->taskId = NAPI_CAST_CONTROLLER_GET_CURRENT_ITEM_TASK_ID;
672 
673     auto executor = [context]() {
674         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
675         if (napiCastController->castController_ == nullptr) {
676             SLOGE("GetValidCommands failed : controller is nullptr");
677             context->status = napi_generic_failure;
678             context->errMessage = "GetValidCommands failed : controller is nullptr";
679             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
680             return;
681         }
682         std::vector<int32_t> cmds;
683         int32_t ret = napiCastController->castController_->GetValidCommands(cmds);
684         if (ret != AVSESSION_SUCCESS) {
685             if (ret == ERR_SESSION_NOT_EXIST) {
686                 context->errMessage = "GetValidCommands failed : native session not exist";
687             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
688                 context->errMessage = "GetValidCommands failed : native controller not exist";
689             } else if (ret == ERR_NO_PERMISSION) {
690                 context->errMessage = "GetValidCommands failed : native no permission";
691             } else {
692                 context->errMessage = "GetValidCommands failed : native server exception";
693             }
694             SLOGE("controller GetValidCommands failed:%{public}d", ret);
695             context->status = napi_generic_failure;
696             context->errCode = NapiAVSessionManager::errcode_[ret];
697         }
698         context->stringCmds = NapiCastControlCommand::ConvertCommands(cmds);
699     };
700 
701     auto complete = [env, context](napi_value& output) {
702         context->status = NapiUtils::SetValue(env, context->stringCmds, output);
703         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
704             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
705     };
706     return NapiAsyncWork::Enqueue(env, context, "GetValidCommands", executor, complete);
707 }
708 
Release(napi_env env,napi_callback_info info)709 napi_value NapiAVCastController::Release(napi_env env, napi_callback_info info)
710 {
711     auto context = std::make_shared<ContextBase>();
712     if (context == nullptr) {
713         SLOGE("Release failed : no memory");
714         NapiUtils::ThrowError(env, "Release failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
715         return NapiUtils::GetUndefinedValue(env);
716     }
717     context->GetCbInfo(env, info);
718     context->taskId = NAPI_CAST_CONTROLLER_GET_CURRENT_ITEM_TASK_ID;
719 
720     auto executor = [context]() {
721         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
722         if (napiCastController->castController_ == nullptr) {
723             SLOGE("release failed : controller is nullptr");
724             context->status = napi_generic_failure;
725             context->errMessage = "release failed : controller is nullptr";
726             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
727             return;
728         }
729         std::vector<int32_t> cmds;
730         int32_t ret = napiCastController->castController_->Destroy();
731         if (ret != AVSESSION_SUCCESS) {
732             if (ret == ERR_SESSION_NOT_EXIST) {
733                 context->errMessage = "release failed : native session not exist";
734             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
735                 context->errMessage = "release failed : native controller not exist";
736             } else if (ret == ERR_NO_PERMISSION) {
737                 context->errMessage = "release failed : native no permission";
738             } else {
739                 context->errMessage = "release failed : native server exception";
740             }
741             SLOGE("controller release failed:%{public}d", ret);
742             context->status = napi_generic_failure;
743             context->errCode = NapiAVSessionManager::errcode_[ret];
744         }
745     };
746 
747     return NapiAsyncWork::Enqueue(env, context, "release", executor);
748 }
749 
SetDisplaySurface(napi_env env,napi_callback_info info)750 napi_value NapiAVCastController::SetDisplaySurface(napi_env env, napi_callback_info info)
751 {
752     AVSESSION_TRACE_SYNC_START("NapiAVCastController::SetDisplaySurface");
753     struct ConcrentContext : public ContextBase {
754         std::string surfaceId;
755     };
756     auto context = std::make_shared<ConcrentContext>();
757     auto input = [env, context](size_t argc, napi_value* argv) {
758         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
759             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
760         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->surfaceId);
761         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok), "invalid command",
762             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
763     };
764     context->GetCbInfo(env, info, input);
765     context->taskId = NAPI_CAST_CONTROLLER_SET_DISPLAY_SURFACE_TASK_ID;
766 
767     auto executor = [context]() {
768         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
769         if (napiCastController->castController_ == nullptr) {
770             SLOGE("SetDisplaySurface failed : controller is nullptr");
771             context->status = napi_generic_failure;
772             context->errMessage = "SetDisplaySurface failed : controller is nullptr";
773             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
774             return;
775         }
776         int32_t ret = napiCastController->castController_->SetDisplaySurface(context->surfaceId);
777         if (ret != AVSESSION_SUCCESS) {
778             if (ret == ERR_SESSION_NOT_EXIST) {
779                 context->errMessage = "SetDisplaySurface failed : native session not exist";
780             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
781                 context->errMessage = "SetDisplaySurface failed : native controller not exist";
782             } else if (ret == ERR_SESSION_DEACTIVE) {
783                 context->errMessage = "SetDisplaySurface failed : native session is not active";
784             } else if (ret == ERR_COMMAND_NOT_SUPPORT) {
785                 context->errMessage = "SetDisplaySurface failed : native command not support";
786             } else if (ret == ERR_COMMAND_SEND_EXCEED_MAX) {
787                 context->errMessage = "SetDisplaySurface failed : native command send nums overload";
788             } else if (ret == ERR_NO_PERMISSION) {
789                 context->errMessage = "SetDisplaySurface failed : native no permission";
790             } else {
791                 context->errMessage = "SetDisplaySurface failed : native server exception";
792             }
793             SLOGE("controller SetDisplaySurface failed:%{public}d", ret);
794             context->status = napi_generic_failure;
795             context->errCode = NapiAVSessionManager::errcode_[ret];
796         }
797     };
798 
799     return NapiAsyncWork::Enqueue(env, context, "SetDisplaySurface", executor);
800 }
801 
ProcessMediaKeyResponse(napi_env env,napi_callback_info info)802 napi_value NapiAVCastController::ProcessMediaKeyResponse(napi_env env, napi_callback_info info)
803 {
804     AVSESSION_TRACE_SYNC_START("NapiAVCastController::ProcessMediaKeyResponse");
805     struct ConcrentContext : public ContextBase {
806         std::string assetId;
807         std::vector<uint8_t> response;
808     };
809     auto context = std::make_shared<ConcrentContext>();
810     auto input = [env, context](size_t argc, napi_value* argv) {
811         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid arguments",
812                                NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
813         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->assetId);
814         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok), "invalid command",
815                                NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
816         context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->response);
817         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok), "invalid command",
818                                NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
819     };
820     context->GetCbInfo(env, info, input);
821     context->taskId = NAPI_PROVIDE_KEY_RESPONSE_TASK_ID;
822 
823     auto executor = [context]() {
824         auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
825         if (napiCastController->castController_ == nullptr) {
826             SLOGE("ProcessMediaKeyResponse failed : controller is nullptr");
827             context->status = napi_generic_failure;
828             context->errMessage = "ProcessMediaKeyResponse failed : controller is nullptr";
829             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
830             return;
831         }
832         int32_t ret = napiCastController->castController_->ProcessMediaKeyResponse(context->assetId, context->response);
833         if (ret != AVSESSION_SUCCESS) {
834             if (ret == ERR_SESSION_NOT_EXIST) {
835                 context->errMessage = "ProcessMediaKeyResponse failed : native session not exist";
836             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
837                 context->errMessage = "ProcessMediaKeyResponse failed : native controller not exist";
838             } else if (ret == ERR_NO_PERMISSION) {
839                 context->errMessage = "ProcessMediaKeyResponse failed : native no permission";
840             } else {
841                 context->errMessage = "ProcessMediaKeyResponse failed : native server exception";
842             }
843             SLOGE("controller ProcessMediaKeyResponse failed:%{public}d", ret);
844             context->status = napi_generic_failure;
845             context->errCode = NapiAVSessionManager::errcode_[ret];
846         }
847     };
848 
849     return NapiAsyncWork::Enqueue(env, context, "ProcessMediaKeyResponse", executor);
850 }
851 
RegisterCallback(napi_env env,const std::shared_ptr<ContextBase> & context,const std::string & event,napi_value filter,napi_value callback)852 napi_status NapiAVCastController::RegisterCallback(napi_env env, const std::shared_ptr<ContextBase>& context,
853     const std::string& event, napi_value filter, napi_value callback)
854 {
855     auto it = EventHandlers_.find(event);
856     if (it == EventHandlers_.end()) {
857         SLOGE("event name invalid");
858         NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
859         return napi_generic_failure;
860     }
861     auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
862     if (napiCastController->castController_ == nullptr) {
863         SLOGE("OnEvent failed : controller is nullptr");
864         NapiUtils::ThrowError(env, "OnEvent failed : controller is nullptr",
865             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
866         return napi_generic_failure;
867     }
868     if (napiCastController->callback_ == nullptr) {
869         napiCastController->callback_ = std::make_shared<NapiAVCastControllerCallback>();
870         if (napiCastController->callback_ == nullptr) {
871             SLOGE("OnEvent failed : no memory");
872             NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
873             return napi_generic_failure;
874         }
875         auto ret = napiCastController->castController_->RegisterCallback(napiCastController->callback_);
876         if (ret != AVSESSION_SUCCESS) {
877             SLOGE("controller RegisterCallback failed:%{public}d", ret);
878             if (ret == ERR_CONTROLLER_NOT_EXIST) {
879                 NapiUtils::ThrowError(env, "OnEvent failed : native controller not exist",
880                     NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
881             } else if (ret == ERR_NO_MEMORY) {
882                 NapiUtils::ThrowError(env, "OnEvent failed : native no memory",
883                     NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
884             } else if (ret == ERR_NO_PERMISSION) {
885                 NapiUtils::ThrowError(env, "OnEvent failed : native no permission",
886                     NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
887             } else {
888                 NapiUtils::ThrowError(env, "OnEvent failed : native server exception",
889                     NapiAVSessionManager::errcode_[ret]);
890             }
891             napiCastController->callback_ = nullptr;
892             return napi_generic_failure;
893         }
894     }
895     if (it->second.first(env, napiCastController, filter, callback) != napi_ok) {
896         SLOGE("add event callback failed");
897         NapiUtils::ThrowError(env, "add event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
898         return napi_generic_failure;
899     }
900     return napi_ok;
901 }
902 
IsThreeParamForOnEvent(const std::string & event)903 static bool IsThreeParamForOnEvent(const std::string& event)
904 {
905     return event == "metadataChange" || event == "playbackStateChange";
906 }
907 
OnEvent(napi_env env,napi_callback_info info)908 napi_value NapiAVCastController::OnEvent(napi_env env, napi_callback_info info)
909 {
910     auto context = std::make_shared<ContextBase>();
911     if (context == nullptr) {
912         SLOGE("OnEvent failed : no memory");
913         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
914         return NapiUtils::GetUndefinedValue(env);
915     }
916 
917     std::string eventName;
918     napi_value filter {};
919     napi_value callback {};
920     auto input = [&eventName, &callback, &filter, env, &context](size_t argc, napi_value* argv) {
921         CHECK_ARGS_RETURN_VOID(context, argc >= ARGC_ONE, "invalid argument number",
922             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
923         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
924         CHECK_STATUS_RETURN_VOID(context, "get event name failed",
925             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
926         napi_valuetype type = napi_undefined;
927         if (!IsThreeParamForOnEvent(eventName)) {
928             CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid argument number",
929                 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
930             context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
931             CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
932                                    "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
933             callback = argv[ARGV_SECOND];
934         } else {
935             CHECK_ARGS_RETURN_VOID(context, argc == ARGC_THREE, "invalid argument number",
936                 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
937             context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
938             CHECK_ARGS_RETURN_VOID(
939                 context, (context->status == napi_ok) && (type == napi_object || type == napi_string),
940                 "Second param type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
941             filter = argv[ARGV_SECOND];
942             context->status = napi_typeof(env, argv[ARGV_THIRD], &type);
943             CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
944                                    "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
945             callback = argv[ARGV_THIRD];
946         }
947     };
948     context->GetCbInfo(env, info, input, true);
949     if (context->status != napi_ok) {
950         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
951         return NapiUtils::GetUndefinedValue(env);
952     }
953     RegisterCallback(env, context, eventName, filter, callback);
954 
955     return NapiUtils::GetUndefinedValue(env);
956 }
957 
OffEvent(napi_env env,napi_callback_info info)958 napi_value NapiAVCastController::OffEvent(napi_env env, napi_callback_info info)
959 {
960     auto context = std::make_shared<ContextBase>();
961     if (context == nullptr) {
962         SLOGE("OnEvent failed : no memory");
963         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
964         return NapiUtils::GetUndefinedValue(env);
965     }
966 
967     std::string eventName;
968     napi_value callback = nullptr;
969     auto input = [&eventName, env, &context, &callback](size_t argc, napi_value* argv) {
970         uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
971         bool isSystemApp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
972         if (!isSystemApp) {
973             SLOGI("check is not system app but do nothing");
974         }
975 
976         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE || argc == ARGC_TWO, "invalid argument number",
977             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
978         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
979         CHECK_STATUS_RETURN_VOID(context, "get event name failed",
980             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
981         if (argc == ARGC_TWO) {
982             callback = argv[ARGV_SECOND];
983         }
984     };
985 
986     context->GetCbInfo(env, info, input, true);
987     if (context->status != napi_ok) {
988         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
989         return NapiUtils::GetUndefinedValue(env);
990     }
991 
992     auto it = EventHandlers_.find(eventName);
993     if (it == EventHandlers_.end()) {
994         SLOGE("event name invalid:%{public}s", eventName.c_str());
995         NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
996         return NapiUtils::GetUndefinedValue(env);
997     }
998 
999     auto* napiCastController = reinterpret_cast<NapiAVCastController*>(context->native);
1000     if (napiCastController->callback_ == nullptr) {
1001         SLOGI("function %{public}s not register yet", eventName.c_str());
1002         return NapiUtils::GetUndefinedValue(env);
1003     }
1004 
1005     if (it->second.second(env, napiCastController, callback) != napi_ok) {
1006         NapiUtils::ThrowError(env, "remove event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1007     }
1008     return NapiUtils::GetUndefinedValue(env);
1009 }
1010 
SetCastPlaybackStateFilter(napi_env env,NapiAVCastController * napiCastController,napi_value filter)1011 napi_status NapiAVCastController::SetCastPlaybackStateFilter(napi_env env, NapiAVCastController *napiCastController,
1012     napi_value filter)
1013 {
1014     AVPlaybackState::PlaybackStateMaskType playbackMask;
1015     auto status = NapiPlaybackState::ConvertFilter(env, filter, playbackMask);
1016     CHECK_RETURN(status == napi_ok, "convert filter failed", status);
1017     auto ret = napiCastController->castController_->SetCastPlaybackFilter(playbackMask);
1018     if (ret != AVSESSION_SUCCESS) {
1019         SLOGE("CastController SetCastPlaybackFilter failed:%{public}d", ret);
1020         status = napi_generic_failure;
1021     }
1022     return status;
1023 }
1024 
OnPlaybackStateChange(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1025 napi_status NapiAVCastController::OnPlaybackStateChange(napi_env env, NapiAVCastController* napiCastController,
1026     napi_value param, napi_value callback)
1027 {
1028     SLOGI("OnPlaybackStateChange");
1029     if (SetCastPlaybackStateFilter(env, napiCastController, param) != napi_ok) {
1030         return napi_generic_failure;
1031     }
1032     auto status = napiCastController->callback_->AddCallback(
1033         env, NapiAVCastControllerCallback::EVENT_CAST_PLAYBACK_STATE_CHANGE, callback);
1034     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "OnPlaybackStateChange AddCallback failed");
1035 
1036     int32_t ret = napiCastController->castController_->AddAvailableCommand(
1037         AVCastControlCommand::CAST_CONTROL_CMD_PLAY_STATE_CHANGE);
1038     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "OnPlaybackStateChange add cmd failed");
1039     return napi_ok;
1040 }
1041 
OnMediaItemChange(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1042 napi_status NapiAVCastController::OnMediaItemChange(napi_env env, NapiAVCastController* napiCastController,
1043     napi_value param, napi_value callback)
1044 {
1045     return napiCastController->callback_->AddCallback(env,
1046         NapiAVCastControllerCallback::EVENT_CAST_MEDIA_ITEM_CHANGE, callback);
1047 }
1048 
OnPlayNext(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1049 napi_status NapiAVCastController::OnPlayNext(napi_env env, NapiAVCastController* napiCastController,
1050     napi_value param, napi_value callback)
1051 {
1052     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1053         "NapiAVCastControllerCallback object is nullptr");
1054     auto status = napiCastController->callback_->AddCallback(env,
1055         NapiAVCastControllerCallback::EVENT_CAST_PLAY_NEXT, callback);
1056     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "AddCallback failed");
1057 
1058     int32_t ret = napiCastController->castController_
1059         ->AddAvailableCommand(AVCastControlCommand::CAST_CONTROL_CMD_PLAY_NEXT);
1060     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add cmd failed");
1061     return napi_ok;
1062 }
1063 
OnPlayPrevious(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1064 napi_status NapiAVCastController::OnPlayPrevious(napi_env env, NapiAVCastController* napiCastController,
1065     napi_value param, napi_value callback)
1066 {
1067     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1068         "NapiAVCastControllerCallback object is nullptr");
1069     auto status = napiCastController->callback_->AddCallback(env,
1070         NapiAVCastControllerCallback::EVENT_CAST_PLAY_PREVIOUS, callback);
1071     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "AddCallback failed");
1072 
1073     int32_t ret = napiCastController->castController_
1074         ->AddAvailableCommand(AVCastControlCommand::CAST_CONTROL_CMD_PLAY_PREVIOUS);
1075     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add cmd failed");
1076     return napi_ok;
1077 }
1078 
OnRequestPlay(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1079 napi_status NapiAVCastController::OnRequestPlay(napi_env env, NapiAVCastController* napiCastController,
1080     napi_value param, napi_value callback)
1081 {
1082     return napi_ok;
1083 }
1084 
OnSeekDone(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1085 napi_status NapiAVCastController::OnSeekDone(napi_env env, NapiAVCastController* napiCastController,
1086     napi_value param, napi_value callback)
1087 {
1088     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1089         "NapiAVCastControllerCallback object is nullptr");
1090     auto status = napiCastController->callback_->AddCallback(env,
1091         NapiAVCastControllerCallback::EVENT_CAST_SEEK_DONE, callback);
1092     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "AddCallback failed");
1093     return napi_ok;
1094 }
1095 
OnValidCommandChange(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1096 napi_status NapiAVCastController::OnValidCommandChange(napi_env env, NapiAVCastController* napiCastController,
1097     napi_value param, napi_value callback)
1098 {
1099     SLOGI("OnValidCommandChange");
1100     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1101         "NapiAVCastControllerCallback object is nullptr");
1102     return napiCastController->callback_->AddCallback(
1103         env, NapiAVCastControllerCallback::EVENT_CAST_VALID_COMMAND_CHANGED, callback);
1104 }
1105 
OnVideoSizeChange(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1106 napi_status NapiAVCastController::OnVideoSizeChange(napi_env env, NapiAVCastController* napiCastController,
1107     napi_value param, napi_value callback)
1108 {
1109     return napiCastController->callback_->AddCallback(env,
1110         NapiAVCastControllerCallback::EVENT_CAST_VIDEO_SIZE_CHANGE, callback);
1111 }
1112 
OnPlayerError(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1113 napi_status NapiAVCastController::OnPlayerError(napi_env env, NapiAVCastController* napiCastController,
1114     napi_value param, napi_value callback)
1115 {
1116     return napiCastController->callback_->AddCallback(env,
1117         NapiAVCastControllerCallback::EVENT_CAST_ERROR, callback);
1118 }
1119 
OnCastControlGenericError(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1120 napi_status NapiAVCastController::OnCastControlGenericError(napi_env env, NapiAVCastController* napiCastController,
1121     napi_value param, napi_value callback)
1122 {
1123     CHECK_AND_RETURN_RET_LOG(napiCastController != nullptr, napi_generic_failure, "napiCastController is nullptr");
1124     CHECK_AND_RETURN_RET_LOG(callback != nullptr, napi_generic_failure, "callback is nullptr");
1125     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1126         "napiCastController->callback_ is nullptr");
1127     return napiCastController->callback_->AddCallback(env,
1128         NapiAVCastControllerCallback::EVENT_CAST_GENERIC_ERR, callback);
1129 }
1130 
OnCastControlIoError(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1131 napi_status NapiAVCastController::OnCastControlIoError(napi_env env, NapiAVCastController* napiCastController,
1132     napi_value param, napi_value callback)
1133 {
1134     CHECK_AND_RETURN_RET_LOG(napiCastController != nullptr, napi_generic_failure, "napiCastController is nullptr");
1135     CHECK_AND_RETURN_RET_LOG(callback != nullptr, napi_generic_failure, "callback is nullptr");
1136     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1137         "napiCastController->callback_ is nullptr");
1138     return napiCastController->callback_->AddCallback(env,
1139         NapiAVCastControllerCallback::EVENT_CAST_IO_ERR, callback);
1140 }
1141 
OnCastControlParsingError(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1142 napi_status NapiAVCastController::OnCastControlParsingError(napi_env env, NapiAVCastController* napiCastController,
1143     napi_value param, napi_value callback)
1144 {
1145     CHECK_AND_RETURN_RET_LOG(napiCastController != nullptr, napi_generic_failure, "napiCastController is nullptr");
1146     CHECK_AND_RETURN_RET_LOG(callback != nullptr, napi_generic_failure, "callback is nullptr");
1147     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1148         "napiCastController->callback_ is nullptr");
1149     return napiCastController->callback_->AddCallback(env,
1150         NapiAVCastControllerCallback::EVENT_CAST_PARSING_ERR, callback);
1151 }
1152 
OnCastControlDecodingError(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1153 napi_status NapiAVCastController::OnCastControlDecodingError(napi_env env, NapiAVCastController* napiCastController,
1154     napi_value param, napi_value callback)
1155 {
1156     CHECK_AND_RETURN_RET_LOG(napiCastController != nullptr, napi_generic_failure, "napiCastController is nullptr");
1157     CHECK_AND_RETURN_RET_LOG(callback != nullptr, napi_generic_failure, "callback is nullptr");
1158     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1159         "napiCastController->callback_ is nullptr");
1160     return napiCastController->callback_->AddCallback(env,
1161         NapiAVCastControllerCallback::EVENT_CAST_DECOD_EERR, callback);
1162 }
1163 
OnCastControlAudioRendererError(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1164 napi_status NapiAVCastController::OnCastControlAudioRendererError(napi_env env,
1165     NapiAVCastController* napiCastController, napi_value param, napi_value callback)
1166 {
1167     CHECK_AND_RETURN_RET_LOG(napiCastController != nullptr, napi_generic_failure, "napiCastController is nullptr");
1168     CHECK_AND_RETURN_RET_LOG(callback != nullptr, napi_generic_failure, "callback is nullptr");
1169     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1170         "napiCastController->callback_ is nullptr");
1171     return napiCastController->callback_->AddCallback(env,
1172         NapiAVCastControllerCallback::EVENT_CAST_RENDER_ERR, callback);
1173 }
1174 
OnCastControlDrmError(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1175 napi_status NapiAVCastController::OnCastControlDrmError(napi_env env, NapiAVCastController* napiCastController,
1176     napi_value param, napi_value callback)
1177 {
1178     CHECK_AND_RETURN_RET_LOG(napiCastController != nullptr, napi_generic_failure, "napiCastController is nullptr");
1179     CHECK_AND_RETURN_RET_LOG(callback != nullptr, napi_generic_failure, "callback is nullptr");
1180     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1181         "napiCastController->callback_ is nullptr");
1182     return napiCastController->callback_->AddCallback(env,
1183         NapiAVCastControllerCallback::EVENT_CAST_DRM_ERR, callback);
1184 }
1185 
OnEndOfStream(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1186 napi_status NapiAVCastController::OnEndOfStream(napi_env env, NapiAVCastController* napiCastController,
1187     napi_value param, napi_value callback)
1188 {
1189     return napiCastController->callback_->AddCallback(env,
1190         NapiAVCastControllerCallback::EVENT_CAST_END_OF_STREAM, callback);
1191 }
1192 
OnPlayRequest(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1193 napi_status NapiAVCastController::OnPlayRequest(napi_env env, NapiAVCastController* napiCastController,
1194     napi_value param, napi_value callback)
1195 {
1196     return napiCastController->callback_->AddCallback(env,
1197         NapiAVCastControllerCallback::EVENT_CAST_PLAY_REQUEST, callback);
1198 }
1199 
OnKeyRequest(napi_env env,NapiAVCastController * napiCastController,napi_value param,napi_value callback)1200 napi_status NapiAVCastController::OnKeyRequest(napi_env env, NapiAVCastController* napiCastController,
1201     napi_value param, napi_value callback)
1202 {
1203     return napiCastController->callback_->AddCallback(env,
1204         NapiAVCastControllerCallback::EVENT_CAST_KEY_REQUEST, callback);
1205 }
1206 
OffPlaybackStateChange(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1207 napi_status NapiAVCastController::OffPlaybackStateChange(napi_env env, NapiAVCastController* napiCastController,
1208     napi_value callback)
1209 {
1210     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1211         napi_generic_failure, "callback has not been registered");
1212     auto status = napiCastController->callback_->RemoveCallback(env,
1213         NapiAVCastControllerCallback::EVENT_CAST_PLAYBACK_STATE_CHANGE, callback);
1214     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1215 
1216     if (napiCastController->callback_
1217             ->IsCallbacksEmpty(NapiAVCastControllerCallback::EVENT_CAST_PLAYBACK_STATE_CHANGE)) {
1218         int32_t ret = napiCastController->castController_
1219             ->RemoveAvailableCommand(AVCastControlCommand::CAST_CONTROL_CMD_PLAY_STATE_CHANGE);
1220         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure,
1221             "remove stateChange cmd failed");
1222     }
1223     return napi_ok;
1224 }
1225 
OffMediaItemChange(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1226 napi_status NapiAVCastController::OffMediaItemChange(napi_env env, NapiAVCastController* napiCastController,
1227     napi_value callback)
1228 {
1229     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1230         "callback has not been registered");
1231     return napiCastController->callback_->RemoveCallback(env,
1232         NapiAVCastControllerCallback::EVENT_CAST_MEDIA_ITEM_CHANGE, callback);
1233 }
1234 
OffPlayNext(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1235 napi_status NapiAVCastController::OffPlayNext(napi_env env, NapiAVCastController* napiCastController,
1236     napi_value callback)
1237 {
1238     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1239         "callback has not been registered");
1240     auto status = napiCastController->callback_->RemoveCallback(env,
1241         NapiAVCastControllerCallback::EVENT_CAST_PLAY_NEXT, callback);
1242     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1243 
1244     if (napiCastController->callback_->IsCallbacksEmpty(NapiAVCastControllerCallback::EVENT_CAST_PLAY_NEXT)) {
1245         int32_t ret = napiCastController->castController_
1246             ->RemoveAvailableCommand(AVCastControlCommand::CAST_CONTROL_CMD_PLAY_NEXT);
1247         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "add cmd failed");
1248     }
1249     return napi_ok;
1250 }
1251 
OffPlayPrevious(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1252 napi_status NapiAVCastController::OffPlayPrevious(napi_env env, NapiAVCastController* napiCastController,
1253     napi_value callback)
1254 {
1255     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1256         "callback has not been registered");
1257     auto status = napiCastController->callback_->RemoveCallback(env,
1258         NapiAVCastControllerCallback::EVENT_CAST_PLAY_PREVIOUS, callback);
1259     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1260 
1261     if (napiCastController->callback_->IsCallbacksEmpty(NapiAVCastControllerCallback::EVENT_CAST_PLAY_PREVIOUS)) {
1262         int32_t ret = napiCastController->castController_
1263             ->RemoveAvailableCommand(AVCastControlCommand::CAST_CONTROL_CMD_PLAY_PREVIOUS);
1264         CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, napi_generic_failure, "remove cmd failed");
1265     }
1266     return napi_ok;
1267 }
1268 
OffRequestPlay(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1269 napi_status NapiAVCastController::OffRequestPlay(napi_env env, NapiAVCastController* napiCastController,
1270     napi_value callback)
1271 {
1272     return napi_ok;
1273 }
1274 
OffSeekDone(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1275 napi_status NapiAVCastController::OffSeekDone(napi_env env, NapiAVCastController* napiCastController,
1276     napi_value callback)
1277 {
1278     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr, napi_generic_failure,
1279         "callback has not been registered");
1280     auto status = napiCastController->callback_->RemoveCallback(env,
1281         NapiAVCastControllerCallback::EVENT_CAST_SEEK_DONE, callback);
1282     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "RemoveCallback failed");
1283     return napi_ok;
1284 }
1285 
OffValidCommandChange(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1286 napi_status NapiAVCastController::OffValidCommandChange(napi_env env, NapiAVCastController* napiCastController,
1287     napi_value callback)
1288 {
1289     CHECK_AND_RETURN_RET_LOG(
1290         napiCastController->callback_ != nullptr, napi_generic_failure, "callback has not been registered");
1291     return napiCastController->callback_->RemoveCallback(
1292         env, NapiAVCastControllerCallback::EVENT_CAST_VALID_COMMAND_CHANGED, callback);
1293 }
1294 
OffVideoSizeChange(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1295 napi_status NapiAVCastController::OffVideoSizeChange(napi_env env,
1296     NapiAVCastController* napiCastController, napi_value callback)
1297 {
1298     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1299         napi_generic_failure, "callback has not been registered");
1300     return napiCastController->callback_->RemoveCallback(env,
1301         NapiAVCastControllerCallback::EVENT_CAST_VIDEO_SIZE_CHANGE, callback);
1302 }
1303 
OffPlayerError(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1304 napi_status NapiAVCastController::OffPlayerError(napi_env env, NapiAVCastController* napiCastController,
1305     napi_value callback)
1306 {
1307     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1308         napi_generic_failure, "callback has not been registered");
1309     return napiCastController->callback_->RemoveCallback(env,
1310         NapiAVCastControllerCallback::EVENT_CAST_ERROR, callback);
1311 }
1312 
OffCastControlGenericError(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1313 napi_status NapiAVCastController::OffCastControlGenericError(napi_env env, NapiAVCastController* napiCastController,
1314     napi_value callback)
1315 {
1316     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1317         napi_generic_failure, "callback has not been registered");
1318     return napiCastController->callback_->RemoveCallback(env,
1319         NapiAVCastControllerCallback::EVENT_CAST_GENERIC_ERR, callback);
1320 }
1321 
OffCastControlIoError(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1322 napi_status NapiAVCastController::OffCastControlIoError(napi_env env, NapiAVCastController* napiCastController,
1323     napi_value callback)
1324 {
1325     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1326         napi_generic_failure, "callback has not been registered");
1327     return napiCastController->callback_->RemoveCallback(env,
1328         NapiAVCastControllerCallback::EVENT_CAST_IO_ERR, callback);
1329 }
1330 
OffCastControlParsingError(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1331 napi_status NapiAVCastController::OffCastControlParsingError(napi_env env, NapiAVCastController* napiCastController,
1332     napi_value callback)
1333 {
1334     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1335         napi_generic_failure, "callback has not been registered");
1336     return napiCastController->callback_->RemoveCallback(env,
1337         NapiAVCastControllerCallback::EVENT_CAST_PARSING_ERR, callback);
1338 }
1339 
OffCastControlDecodingError(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1340 napi_status NapiAVCastController::OffCastControlDecodingError(napi_env env, NapiAVCastController* napiCastController,
1341     napi_value callback)
1342 {
1343     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1344         napi_generic_failure, "callback has not been registered");
1345     return napiCastController->callback_->RemoveCallback(env,
1346         NapiAVCastControllerCallback::EVENT_CAST_DECOD_EERR, callback);
1347 }
1348 
OffCastControlAudioRendererError(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1349 napi_status NapiAVCastController::OffCastControlAudioRendererError(napi_env env,
1350     NapiAVCastController* napiCastController, napi_value callback)
1351 {
1352     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1353         napi_generic_failure, "callback has not been registered");
1354     return napiCastController->callback_->RemoveCallback(env,
1355         NapiAVCastControllerCallback::EVENT_CAST_RENDER_ERR, callback);
1356 }
1357 
OffCastControlDrmError(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1358 napi_status NapiAVCastController::OffCastControlDrmError(napi_env env, NapiAVCastController* napiCastController,
1359     napi_value callback)
1360 {
1361     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1362         napi_generic_failure, "callback has not been registered");
1363     return napiCastController->callback_->RemoveCallback(env,
1364         NapiAVCastControllerCallback::EVENT_CAST_DRM_ERR, callback);
1365 }
1366 
OffEndOfStream(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1367 napi_status NapiAVCastController::OffEndOfStream(napi_env env, NapiAVCastController* napiCastController,
1368     napi_value callback)
1369 {
1370     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1371         napi_generic_failure, "callback has not been registered");
1372     return napiCastController->callback_->RemoveCallback(env,
1373         NapiAVCastControllerCallback::EVENT_CAST_END_OF_STREAM, callback);
1374 }
1375 
OffPlayRequest(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1376 napi_status NapiAVCastController::OffPlayRequest(napi_env env, NapiAVCastController* napiCastController,
1377     napi_value callback)
1378 {
1379     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1380         napi_generic_failure, "callback has not been registered");
1381     return napiCastController->callback_->RemoveCallback(env,
1382         NapiAVCastControllerCallback::EVENT_CAST_PLAY_REQUEST, callback);
1383 }
1384 
OffKeyRequest(napi_env env,NapiAVCastController * napiCastController,napi_value callback)1385 napi_status NapiAVCastController::OffKeyRequest(napi_env env, NapiAVCastController* napiCastController,
1386     napi_value callback)
1387 {
1388     CHECK_AND_RETURN_RET_LOG(napiCastController->callback_ != nullptr,
1389         napi_generic_failure, "callback has not been registered");
1390     return napiCastController->callback_->RemoveCallback(env,
1391         NapiAVCastControllerCallback::EVENT_CAST_KEY_REQUEST, callback);
1392 }
1393 
ErrCodeToMessage(int32_t errCode,std::string & message)1394 void NapiAVCastController::ErrCodeToMessage(int32_t errCode, std::string& message)
1395 {
1396     switch (errCode) {
1397         case ERR_SESSION_NOT_EXIST:
1398             message = "SetSessionEvent failed : native session not exist";
1399             break;
1400         case ERR_CONTROLLER_NOT_EXIST:
1401             message = "SendCommonCommand failed : native controller not exist";
1402             break;
1403         case ERR_SESSION_DEACTIVE:
1404             message = "SendCommonCommand failed : native session is not active";
1405             break;
1406         case ERR_NO_PERMISSION:
1407             message = "SetSessionEvent failed : native no permission";
1408             break;
1409         default:
1410             message = "SetSessionEvent failed : native server exception";
1411             break;
1412     }
1413 }
1414 
ReportStartFailInfo(int error)1415 void NapiAVCastController::ReportStartFailInfo(int error)
1416 {
1417     AVSessionRadarInfo info("NapiAVCastController::Start");
1418     info.errorCode_ = AVSessionRadar::GetRadarErrorCode(error);
1419     AVSessionRadar::GetInstance().StartPlayFailed(info);
1420 }
1421 
ReportSendControlCommandFailInfo(int error)1422 void NapiAVCastController::ReportSendControlCommandFailInfo(int error)
1423 {
1424     AVSessionRadarInfo info("NapiAVCastController::SendControlCommand");
1425     info.errorCode_ = AVSessionRadar::GetRadarErrorCode(error);
1426     AVSessionRadar::GetInstance().FailToSendControlCommand(info);
1427 }
1428 
CheckSendCtrlCmdReportRadar(bool condition,int32_t error)1429 void NapiAVCastController::CheckSendCtrlCmdReportRadar(bool condition, int32_t error)
1430 {
1431     if (!condition) {
1432         ReportSendControlCommandFailInfo(error);
1433     }
1434 }
1435 
CheckStartReportRadar(bool condition,int32_t error)1436 void NapiAVCastController::CheckStartReportRadar(bool condition, int32_t error)
1437 {
1438     if (!condition) {
1439         ReportStartFailInfo(error);
1440     }
1441 }
1442 
GetSendControlCommandErrMsg(int32_t error)1443 std::string NapiAVCastController::GetSendControlCommandErrMsg(int32_t error)
1444 {
1445     std::string msg;
1446     switch (error) {
1447         case ERR_SESSION_NOT_EXIST:
1448             msg = "SendControlCommand failed : native session not exist";
1449             break;
1450         case ERR_CONTROLLER_NOT_EXIST:
1451             msg = "SendControlCommand failed : native controller not exist";
1452             break;
1453         case ERR_SESSION_DEACTIVE:
1454             msg = "SendControlCommand failed : native session is not active";
1455             break;
1456         case ERR_NO_PERMISSION:
1457             msg = "SendControlCommand failed : native no permission";
1458             break;
1459         case ERR_COMMAND_NOT_SUPPORT:
1460             msg = "SendControlCommand failed : native command not support";
1461             break;
1462         case ERR_COMMAND_SEND_EXCEED_MAX:
1463             msg = "SendControlCommand failed : native command send nums overload";
1464             break;
1465         default:
1466             msg = "SendControlCommand failed : native server exception";
1467             break;
1468     }
1469     return msg;
1470 }
1471 } // namespace OHOS::AVSession
1472