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