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