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