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