1 /*
2 * Copyright (C) 2023-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 * Description: supply napi interface realization for cast session.
15 * Author: zhangjingnan
16 * Create: 2022-7-11
17 */
18
19 #include <memory>
20 #include "napi/native_api.h"
21 #include "napi/native_node_api.h"
22 #include "cast_engine_log.h"
23 #include "cast_engine_common.h"
24 #include "oh_remote_control_event.h"
25 #include "i_cast_session.h"
26 #include "cast_session_manager.h"
27 #include "napi_castengine_utils.h"
28 #include "napi_cast_session_listener.h"
29 #include "napi_cast_session.h"
30 #include "napi_stream_player.h"
31 #include "napi_mirror_player.h"
32 #include "napi_async_work.h"
33
34 using namespace OHOS::CastEngine::CastEngineClient;
35 using namespace std;
36
37 namespace OHOS {
38 namespace CastEngine {
39 namespace CastEngineClient {
40 DEFINE_CAST_ENGINE_LABEL("Cast-Napi-Session");
41
42 thread_local napi_ref NapiCastSession::consRef_ = nullptr;
43
44 std::map<std::string, std::pair<NapiCastSession::OnEventHandlerType,
45 NapiCastSession::OffEventHandlerType>>
46 NapiCastSession::eventHandlers_ = {
47 { "event", { OnInnerEvent, OffInnerEvent } },
48 { "deviceState", { OnDeviceState, OffDeviceState } }
49 };
50
DefineCastSessionJSClass(napi_env env)51 void NapiCastSession::DefineCastSessionJSClass(napi_env env)
52 {
53 napi_property_descriptor NapiCastSessionDesc[] = {
54 DECLARE_NAPI_FUNCTION("on", OnEvent),
55 DECLARE_NAPI_FUNCTION("off", OffEvent),
56 DECLARE_NAPI_FUNCTION("addDevice", AddDevice),
57 DECLARE_NAPI_FUNCTION("removeDevice", RemoveDevice),
58 DECLARE_NAPI_FUNCTION("getSessionId", GetSessionId),
59 DECLARE_NAPI_FUNCTION("setSessionProperty", SetSessionProperty),
60 DECLARE_NAPI_FUNCTION("createMirrorPlayer", CreateMirrorPlayer),
61 DECLARE_NAPI_FUNCTION("createStreamPlayer", CreateStreamPlayer),
62 DECLARE_NAPI_FUNCTION("setCastMode", SetCastMode),
63 DECLARE_NAPI_FUNCTION("release", Release)
64 };
65
66 napi_value castSession = nullptr;
67 constexpr int initialRefCount = 1;
68 napi_status status = napi_define_class(env, "castSession", NAPI_AUTO_LENGTH, NapiCastSessionConstructor, nullptr,
69 sizeof(NapiCastSessionDesc) / sizeof(NapiCastSessionDesc[0]), NapiCastSessionDesc, &castSession);
70 if (status != napi_ok) {
71 CLOGE("napi_define_class failed");
72 return;
73 }
74 status = napi_create_reference(env, castSession, initialRefCount, &consRef_);
75 if (status != napi_ok) {
76 CLOGE("DefineCastSessionJSClass napi_create_reference failed");
77 }
78 }
79
NapiCastSessionConstructor(napi_env env,napi_callback_info info)80 napi_value NapiCastSession::NapiCastSessionConstructor(napi_env env, napi_callback_info info)
81 {
82 CLOGD("NapiCastSession start to construct in");
83 napi_value thisVar = nullptr;
84 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
85 CLOGD("NapiCastSession construct successfully");
86 return thisVar;
87 }
88
CreateNapiCastSession(napi_env env,shared_ptr<ICastSession> session,napi_value & out)89 napi_status NapiCastSession::CreateNapiCastSession(napi_env env, shared_ptr<ICastSession> session, napi_value &out)
90 {
91 CLOGD("Start to create napiCastSession in");
92 napi_value result = nullptr;
93 napi_value constructor = nullptr;
94 if (consRef_ == nullptr || session == nullptr) {
95 CLOGE("CreateNapiCastSession input is null");
96 return napi_generic_failure;
97 }
98 napi_status status = napi_get_reference_value(env, consRef_, &constructor);
99 if (status != napi_ok || constructor == nullptr) {
100 CLOGE("CreateNapiCastSession napi_get_reference_value failed");
101 return napi_generic_failure;
102 }
103
104 constexpr size_t argc = 0;
105 status = napi_new_instance(env, constructor, argc, nullptr, &result);
106 if (status != napi_ok) {
107 CLOGE("CreateNapiCastSession napi_new_instance failed");
108 return napi_generic_failure;
109 }
110
111 NapiCastSession *napiCastSession = new NapiCastSession(session);
112 if (napiCastSession == nullptr) {
113 CLOGE("NapiCastSession is nullptr");
114 return napi_generic_failure;
115 }
116 auto finalize = [](napi_env env, void *data, void *hint) {
117 NapiCastSession *session = reinterpret_cast<NapiCastSession *>(data);
118 if (session != nullptr) {
119 CLOGI("Session deconstructed");
120 delete session;
121 session = nullptr;
122 }
123 };
124 if (napi_wrap(env, result, napiCastSession, finalize, nullptr, nullptr) != napi_ok) {
125 CLOGE("CreateNapiCastSession napi_wrap failed");
126 delete napiCastSession;
127 napiCastSession = nullptr;
128 return napi_generic_failure;
129 }
130 out = result;
131 CLOGD("Create napiCastSession successfully");
132 return napi_ok;
133 }
134
GetNapiCastSession(napi_env env,napi_callback_info info)135 NapiCastSession *NapiCastSession::GetNapiCastSession(napi_env env, napi_callback_info info)
136 {
137 napi_value thisVar = nullptr;
138 NAPI_CALL_BASE(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr), nullptr);
139
140 NapiCastSession *napiCastSession = nullptr;
141 NAPI_CALL_BASE(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiCastSession)), nullptr);
142 if (napiCastSession == nullptr) {
143 CLOGE("napi_unwrap napiStreamPlayer is null");
144 return nullptr;
145 }
146
147 return napiCastSession;
148 }
149
OnEvent(napi_env env,napi_callback_info info)150 napi_value NapiCastSession::OnEvent(napi_env env, napi_callback_info info)
151 {
152 constexpr size_t expectedArgc = 2;
153 napi_value argv[expectedArgc] = { 0 };
154 napi_valuetype expectedTypes[expectedArgc] = { napi_string, napi_function };
155 if (!GetJSFuncParams(env, info, argv, expectedArgc, expectedTypes)) {
156 return GetUndefinedValue(env);
157 }
158 std::string eventName = ParseString(env, argv[0]);
159 NapiCastSession *napiSession = GetNapiCastSession(env, info);
160 if (napiSession == nullptr) {
161 CLOGE("napiSession is null");
162 return GetUndefinedValue(env);
163 }
164 auto it = eventHandlers_.find(eventName);
165 if (it == eventHandlers_.end()) {
166 CLOGE("event name invalid");
167 return GetUndefinedValue(env);
168 }
169
170 if (RegisterNativeSessionListener(napiSession) == napi_generic_failure) {
171 return GetUndefinedValue(env);
172 }
173 if (it->second.first(env, argv[1], napiSession) != napi_ok) {
174 CLOGE("event name invalid");
175 }
176
177 return GetUndefinedValue(env);
178 }
179
OffEvent(napi_env env,napi_callback_info info)180 napi_value NapiCastSession::OffEvent(napi_env env, napi_callback_info info)
181 {
182 constexpr size_t expectedArgc = 2;
183 napi_value argv[expectedArgc] = { 0 };
184 napi_valuetype expectedTypes[expectedArgc] = { napi_string, napi_function};
185 if (!GetJSFuncParams(env, info, argv, expectedArgc, expectedTypes)) {
186 return GetUndefinedValue(env);
187 }
188
189 std::string eventName = ParseString(env, argv[0]);
190 auto it = eventHandlers_.find(eventName);
191 if (it == eventHandlers_.end()) {
192 CLOGE("event name invalid");
193 return GetUndefinedValue(env);
194 }
195 NapiCastSession *napiSession = GetNapiCastSession(env, info);
196 if (napiSession == nullptr) {
197 CLOGE("napiSession is null");
198 return GetUndefinedValue(env);
199 }
200 if (it->second.second(env, argv[1], napiSession) != napi_ok) {
201 CLOGE("event name invalid");
202 }
203
204 return GetUndefinedValue(env);
205 }
206
RegisterNativeSessionListener(NapiCastSession * napiSession)207 napi_status NapiCastSession::RegisterNativeSessionListener(NapiCastSession *napiSession)
208 {
209 if (napiSession == nullptr) {
210 CLOGE("napiSession is null");
211 return napi_generic_failure;
212 }
213 if (napiSession->NapiListenerGetter()) {
214 return napi_ok;
215 }
216 auto session = napiSession->GetCastSession();
217 if (!session) {
218 CLOGE("Session is null");
219 return napi_generic_failure;
220 }
221
222 auto listener = std::make_shared<NapiCastSessionListener>();
223 if (!listener) {
224 CLOGE("Failed to malloc session listener");
225 return napi_generic_failure;
226 }
227 int32_t ret = session->RegisterListener(listener);
228 if (ret != CAST_ENGINE_SUCCESS) {
229 CLOGE("native register session listener failed");
230 return napi_generic_failure;
231 }
232 napiSession->NapiListenerSetter(listener);
233
234 return napi_ok;
235 }
236
OnInnerEvent(napi_env env,napi_value callback,NapiCastSession * napiSession)237 napi_status NapiCastSession::OnInnerEvent(napi_env env, napi_value callback, NapiCastSession *napiSession)
238 {
239 if (napiSession == nullptr) {
240 CLOGE("napiSession is null");
241 return napi_generic_failure;
242 }
243 if (!napiSession->NapiListenerGetter()) {
244 CLOGE("cast session manager callback is null");
245 return napi_generic_failure;
246 }
247 if (napiSession->NapiListenerGetter()->AddCallback(env, NapiCastSessionListener::EVENT_ON_EVENT,
248 callback) != napi_ok) {
249 return napi_generic_failure;
250 }
251 return napi_ok;
252 }
253
OnDeviceState(napi_env env,napi_value callback,NapiCastSession * napiSession)254 napi_status NapiCastSession::OnDeviceState(napi_env env, napi_value callback, NapiCastSession *napiSession)
255 {
256 if (napiSession == nullptr) {
257 CLOGE("napiSession is null");
258 return napi_generic_failure;
259 }
260 if (!napiSession->NapiListenerGetter()) {
261 CLOGE("cast session manager callback is null");
262 return napi_generic_failure;
263 }
264 if (napiSession->NapiListenerGetter()->AddCallback(env, NapiCastSessionListener::EVENT_DEVICE_STATE,
265 callback) != napi_ok) {
266 return napi_generic_failure;
267 }
268 return napi_ok;
269 }
270
OffInnerEvent(napi_env env,napi_value callback,NapiCastSession * napiSession)271 napi_status NapiCastSession::OffInnerEvent(napi_env env, napi_value callback, NapiCastSession *napiSession)
272 {
273 if (napiSession == nullptr) {
274 CLOGE("napiSession is null");
275 return napi_generic_failure;
276 }
277 if (!napiSession->NapiListenerGetter()) {
278 CLOGE("cast session manager callback is null");
279 return napi_generic_failure;
280 }
281 if (napiSession->NapiListenerGetter()->RemoveCallback(env, NapiCastSessionListener::EVENT_ON_EVENT,
282 callback) != napi_ok) {
283 return napi_generic_failure;
284 }
285 return napi_ok;
286 }
287
OffDeviceState(napi_env env,napi_value callback,NapiCastSession * napiSession)288 napi_status NapiCastSession::OffDeviceState(napi_env env, napi_value callback, NapiCastSession *napiSession)
289 {
290 if (napiSession == nullptr) {
291 CLOGE("napiSession is null");
292 return napi_generic_failure;
293 }
294 if (!napiSession->NapiListenerGetter()) {
295 CLOGE("cast session manager callback is null");
296 return napi_generic_failure;
297 }
298 if (napiSession->NapiListenerGetter()->RemoveCallback(env, NapiCastSessionListener::EVENT_DEVICE_STATE,
299 callback) != napi_ok) {
300 return napi_generic_failure;
301 }
302 return napi_ok;
303 }
304
AddDevice(napi_env env,napi_callback_info info)305 napi_value NapiCastSession::AddDevice(napi_env env, napi_callback_info info)
306 {
307 CLOGD("Start to add device in");
308 struct ConcreteTask : public NapiAsyncTask {
309 CastRemoteDevice castRemoteDevice_;
310 };
311 auto napiAsyntask = std::make_shared<ConcreteTask>();
312 if (napiAsyntask == nullptr) {
313 CLOGE("Create NapiAsyncTask failed");
314 return GetUndefinedValue(env);
315 }
316
317 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
318 constexpr size_t expectedArgc = 1;
319 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
320 NapiErrors::errcode_[ERR_INVALID_PARAM]);
321 napi_valuetype expectedTypes[expectedArgc] = { napi_object };
322 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
323 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
324 NapiErrors::errcode_[ERR_INVALID_PARAM]);
325 napiAsyntask->castRemoteDevice_ = GetCastRemoteDeviceFromJS(env, argv[0]);
326 };
327 napiAsyntask->GetJSInfo(env, info, inputParser);
328 auto executor = [napiAsyntask]() {
329 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
330 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
331 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
332 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
333 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
334 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
335 int32_t ret = castSession->AddDevice(napiAsyntask->castRemoteDevice_);
336 if (ret != CAST_ENGINE_SUCCESS) {
337 if (ret == ERR_NO_PERMISSION) {
338 napiAsyntask->errMessage = "AddDevice failed : no permission";
339 } else if (ret == ERR_INVALID_PARAM) {
340 napiAsyntask->errMessage = "AddDevice failed : invalid parameters";
341 } else {
342 napiAsyntask->errMessage = "AddDevice failed : native server exception";
343 }
344 napiAsyntask->status = napi_generic_failure;
345 napiAsyntask->errCode = NapiErrors::errcode_[ret];
346 }
347 };
348
349 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
350 return NapiAsyncWork::Enqueue(env, napiAsyntask, "AddDevice", executor, complete);
351 }
352
RemoveDevice(napi_env env,napi_callback_info info)353 napi_value NapiCastSession::RemoveDevice(napi_env env, napi_callback_info info)
354 {
355 CLOGD("Start to remove device in");
356 struct ConcreteTask : public NapiAsyncTask {
357 string deviceId_;
358 DeviceRemoveAction actionType_;
359 };
360 auto napiAsyntask = std::make_shared<ConcreteTask>();
361 if (napiAsyntask == nullptr) {
362 CLOGE("Create NapiAsyncTask failed");
363 return GetUndefinedValue(env);
364 }
365
366 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
367 constexpr size_t expectedArgcDeviceId = 1;
368 constexpr size_t expectedArgcType = 2;
369 CHECK_ARGS_RETURN_VOID(napiAsyntask, (argc == expectedArgcDeviceId || argc == expectedArgcType),
370 "invalid arguments", NapiErrors::errcode_[ERR_INVALID_PARAM]);
371 napi_valuetype expectedTypes[expectedArgcType] = {napi_string, napi_number};
372 bool isParamsTypeValid = CheckJSParamsType(env, argv, argc, expectedTypes);
373 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
374 NapiErrors::errcode_[ERR_INVALID_PARAM]);
375 napiAsyntask->deviceId_ = ParseString(env, argv[0]);
376 napiAsyntask->actionType_ = (argc == expectedArgcType) ?
377 static_cast<DeviceRemoveAction>(ParseInt32(env, argv[1])) : DeviceRemoveAction::ACTION_DISCONNECT;
378 };
379 napiAsyntask->GetJSInfo(env, info, inputParser);
380 auto executor = [napiAsyntask]() {
381 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
382 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
383 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
384 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
385 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
386 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
387 int32_t ret = castSession->RemoveDevice(napiAsyntask->deviceId_);
388 if (ret != CAST_ENGINE_SUCCESS) {
389 if (ret == ERR_NO_PERMISSION) {
390 napiAsyntask->errMessage = "RemoveDevice failed : no permission";
391 } else if (ret == ERR_INVALID_PARAM) {
392 napiAsyntask->errMessage = "RemoveDevice failed : invalid parameters";
393 } else {
394 napiAsyntask->errMessage = "RemoveDevice failed : native server exception";
395 }
396 napiAsyntask->status = napi_generic_failure;
397 napiAsyntask->errCode = NapiErrors::errcode_[ret];
398 }
399 };
400
401 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
402 return NapiAsyncWork::Enqueue(env, napiAsyntask, "RemoveDevice", executor, complete);
403 }
404
GetSessionId(napi_env env,napi_callback_info info)405 napi_value NapiCastSession::GetSessionId(napi_env env, napi_callback_info info)
406 {
407 CLOGD("Start to get sessionId in");
408 struct ConcreteTask : public NapiAsyncTask {
409 string sessionId_;
410 };
411 auto napiAsyntask = std::make_shared<ConcreteTask>();
412 if (napiAsyntask == nullptr) {
413 CLOGE("Create NapiAsyncTask failed");
414 return GetUndefinedValue(env);
415 }
416
417 napiAsyntask->GetJSInfo(env, info);
418 auto executor = [napiAsyntask]() {
419 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
420 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
421 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
422 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
423 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
424 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
425 int32_t ret = castSession->GetSessionId(napiAsyntask->sessionId_);
426 if (ret != CAST_ENGINE_SUCCESS) {
427 if (ret == ERR_NO_PERMISSION) {
428 napiAsyntask->errMessage = "GetSessionId failed : no permission";
429 } else {
430 napiAsyntask->errMessage = "GetSessionId failed : native server exception";
431 }
432 napiAsyntask->status = napi_generic_failure;
433 napiAsyntask->errCode = NapiErrors::errcode_[ret];
434 }
435 };
436
437 auto complete = [env, napiAsyntask](napi_value &output) {
438 napiAsyntask->status =
439 napi_create_string_utf8(env, napiAsyntask->sessionId_.c_str(), NAPI_AUTO_LENGTH, &output);
440 CHECK_STATUS_RETURN_VOID(napiAsyntask, "napi_create_string_utf8 failed",
441 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
442 };
443 return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetSessionId", executor, complete);
444 }
445
SetSessionProperty(napi_env env,napi_callback_info info)446 napi_value NapiCastSession::SetSessionProperty(napi_env env, napi_callback_info info)
447 {
448 CLOGD("Start to set sessionProperty in");
449 struct ConcreteTask : public NapiAsyncTask {
450 CastSessionProperty castSessionProperty_;
451 };
452 auto napiAsyntask = std::make_shared<ConcreteTask>();
453 if (napiAsyntask == nullptr) {
454 CLOGE("Create NapiAsyncTask failed");
455 return GetUndefinedValue(env);
456 }
457
458 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
459 constexpr size_t expectedArgc = 1;
460 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
461 NapiErrors::errcode_[ERR_INVALID_PARAM]);
462 napi_valuetype expectedTypes[expectedArgc] = { napi_object };
463 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
464 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
465 NapiErrors::errcode_[ERR_INVALID_PARAM]);
466 napiAsyntask->castSessionProperty_ = GetCastSessionPropertyFromJS(env, argv[0]);
467 };
468 napiAsyntask->GetJSInfo(env, info, inputParser);
469 auto executor = [napiAsyntask]() {
470 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
471 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
472 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
473 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
474 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
475 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
476 int32_t ret = castSession->SetSessionProperty(napiAsyntask->castSessionProperty_);
477 if (ret != CAST_ENGINE_SUCCESS) {
478 if (ret == ERR_NO_PERMISSION) {
479 napiAsyntask->errMessage = "SetSessionProperty failed : no permission";
480 } else if (ret == ERR_INVALID_PARAM) {
481 napiAsyntask->errMessage = "SetSessionProperty failed : invalid parameters";
482 } else {
483 napiAsyntask->errMessage = "SetSessionProperty failed : native server exception";
484 }
485 napiAsyntask->status = napi_generic_failure;
486 napiAsyntask->errCode = NapiErrors::errcode_[ret];
487 }
488 };
489
490 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
491 return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetSessionProperty", executor, complete);
492 }
493
CreateMirrorPlayer(napi_env env,napi_callback_info info)494 napi_value NapiCastSession::CreateMirrorPlayer(napi_env env, napi_callback_info info)
495 {
496 CLOGD("Start to create mirror Player");
497 struct ConcreteTask : public NapiAsyncTask {
498 shared_ptr<IMirrorPlayer> player_;
499 };
500 auto napiAsyntask = std::make_shared<ConcreteTask>();
501 if (napiAsyntask == nullptr) {
502 CLOGE("Create NapiAsyncTask failed");
503 return GetUndefinedValue(env);
504 }
505
506 napiAsyntask->GetJSInfo(env, info);
507 auto executor = [napiAsyntask]() {
508 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
509 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
510 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
511 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
512 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
513 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
514 int32_t ret = castSession->CreateMirrorPlayer(napiAsyntask->player_);
515 if (ret != CAST_ENGINE_SUCCESS) {
516 if (ret == ERR_NO_PERMISSION) {
517 napiAsyntask->errMessage = "CreateMirrorPlayer failed : no permission";
518 } else {
519 napiAsyntask->errMessage = "CreateMirrorPlayer failed : native server exception";
520 }
521 napiAsyntask->status = napi_generic_failure;
522 napiAsyntask->errCode = NapiErrors::errcode_[ret];
523 }
524 };
525
526 auto complete = [napiAsyntask](napi_value &output) {
527 napiAsyntask->status =
528 NapiMirrorPlayer::CreateNapiMirrorPlayer(napiAsyntask->env, napiAsyntask->player_, output);
529 CHECK_STATUS_RETURN_VOID(napiAsyntask, "convert native object to javascript object failed",
530 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
531 };
532 return NapiAsyncWork::Enqueue(env, napiAsyntask, "CreateMirrorPlayer", executor, complete);
533 }
534
CreateStreamPlayer(napi_env env,napi_callback_info info)535 napi_value NapiCastSession::CreateStreamPlayer(napi_env env, napi_callback_info info)
536 {
537 CLOGD("Start to create Stream Player");
538 struct ConcreteTask : public NapiAsyncTask {
539 shared_ptr<IStreamPlayer> player_;
540 };
541 auto napiAsyntask = std::make_shared<ConcreteTask>();
542 if (napiAsyntask == nullptr) {
543 CLOGE("Create NapiAsyncTask failed");
544 return GetUndefinedValue(env);
545 }
546
547 napiAsyntask->GetJSInfo(env, info);
548 auto executor = [napiAsyntask]() {
549 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
550 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
551 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
552 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
553 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
554 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
555 int32_t ret = castSession->CreateStreamPlayer(napiAsyntask->player_);
556 if (ret != CAST_ENGINE_SUCCESS) {
557 if (ret == ERR_NO_PERMISSION) {
558 napiAsyntask->errMessage = "CreateStreamPlayer failed : no permission";
559 } else {
560 napiAsyntask->errMessage = "CreateStreamPlayer failed : native server exception";
561 }
562 napiAsyntask->status = napi_generic_failure;
563 napiAsyntask->errCode = NapiErrors::errcode_[ret];
564 }
565 };
566
567 auto complete = [napiAsyntask](napi_value &output) {
568 napiAsyntask->status =
569 NapiStreamPlayer::CreateNapiStreamPlayer(napiAsyntask->env, napiAsyntask->player_, output);
570 CHECK_STATUS_RETURN_VOID(napiAsyntask, "convert native object to javascript object failed",
571 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
572 };
573 return NapiAsyncWork::Enqueue(env, napiAsyntask, "CreateStreamPlayer", executor, complete);
574 }
575
SetCastMode(napi_env env,napi_callback_info info)576 napi_value NapiCastSession::SetCastMode(napi_env env, napi_callback_info info)
577 {
578 CLOGD("Start to set cast mode in");
579 struct ConcreteTask : public NapiAsyncTask {
580 CastMode castMode_;
581 string jsonParam_;
582 };
583 auto napiAsyntask = std::make_shared<ConcreteTask>();
584 if (napiAsyntask == nullptr) {
585 CLOGE("Create NapiAsyncTask failed");
586 return GetUndefinedValue(env);
587 }
588
589 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
590 constexpr size_t expectedArgc = 2;
591 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
592 NapiErrors::errcode_[ERR_INVALID_PARAM]);
593 napi_valuetype expectedTypes[expectedArgc] = { napi_number, napi_string };
594 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
595 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
596 NapiErrors::errcode_[ERR_INVALID_PARAM]);
597 napiAsyntask->castMode_ = static_cast<CastMode>(ParseInt32(env, argv[0]));
598 napiAsyntask->jsonParam_ = ParseString(env, argv[1]);
599 };
600 napiAsyntask->GetJSInfo(env, info, inputParser);
601 auto executor = [napiAsyntask]() {
602 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
603 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
604 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
605 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
606 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
607 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
608 int32_t ret = castSession->SetCastMode(napiAsyntask->castMode_, napiAsyntask->jsonParam_);
609 if (ret != CAST_ENGINE_SUCCESS) {
610 if (ret == ERR_NO_PERMISSION) {
611 napiAsyntask->errMessage = "SetCastMode failed : no permission";
612 } else if (ret == ERR_INVALID_PARAM) {
613 napiAsyntask->errMessage = "SetCastMode failed : invalid parameters";
614 } else {
615 napiAsyntask->errMessage = "SetCastMode failed : native server exception";
616 }
617 napiAsyntask->status = napi_generic_failure;
618 napiAsyntask->errCode = NapiErrors::errcode_[ret];
619 }
620 };
621
622 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
623 return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetCastMode", executor, complete);
624 }
625
Release(napi_env env,napi_callback_info info)626 napi_value NapiCastSession::Release(napi_env env, napi_callback_info info)
627 {
628 CLOGD("Start to release in");
629 auto napiAsyntask = std::make_shared<NapiAsyncTask>();
630 if (napiAsyntask == nullptr) {
631 CLOGE("Create NapiAsyncTask failed");
632 return GetUndefinedValue(env);
633 }
634 napiAsyntask->GetJSInfo(env, info);
635
636 auto executor = [napiAsyntask]() {
637 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
638 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
639 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
640 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
641 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
642 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
643 int32_t ret = castSession->Release();
644 if (ret == CAST_ENGINE_SUCCESS) {
645 napiSession->Reset();
646 } else if (ret == ERR_NO_PERMISSION) {
647 napiAsyntask->errMessage = "Release failed : no permission";
648 napiAsyntask->status = napi_generic_failure;
649 napiAsyntask->errCode = NapiErrors::errcode_[ret];
650 } else {
651 napiAsyntask->errMessage = "Release failed : native server exception";
652 napiAsyntask->status = napi_generic_failure;
653 napiAsyntask->errCode = NapiErrors::errcode_[ret];
654 }
655 };
656
657 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
658 return NapiAsyncWork::Enqueue(env, napiAsyntask, "Release", executor, complete);
659 }
660
NapiListenerGetter()661 std::shared_ptr<NapiCastSessionListener> NapiCastSession::NapiListenerGetter()
662 {
663 return listener_;
664 }
665
NapiListenerSetter(std::shared_ptr<NapiCastSessionListener> listener)666 void NapiCastSession::NapiListenerSetter(std::shared_ptr<NapiCastSessionListener> listener)
667 {
668 listener_ = listener;
669 }
670 } // namespace CastEngineClient
671 } // namespace CastEngine
672 } // namespace OHOS