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 };
359 auto napiAsyntask = std::make_shared<ConcreteTask>();
360 if (napiAsyntask == nullptr) {
361 CLOGE("Create NapiAsyncTask failed");
362 return GetUndefinedValue(env);
363 }
364
365 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
366 constexpr size_t expectedArgc = 1;
367 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
368 NapiErrors::errcode_[ERR_INVALID_PARAM]);
369 napi_valuetype expectedTypes[expectedArgc] = { napi_string };
370 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
371 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
372 NapiErrors::errcode_[ERR_INVALID_PARAM]);
373 napiAsyntask->deviceId_ = ParseString(env, argv[0]);
374 };
375 napiAsyntask->GetJSInfo(env, info, inputParser);
376 auto executor = [napiAsyntask]() {
377 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
378 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
379 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
380 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
381 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
382 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
383 int32_t ret = castSession->RemoveDevice(napiAsyntask->deviceId_);
384 if (ret != CAST_ENGINE_SUCCESS) {
385 if (ret == ERR_NO_PERMISSION) {
386 napiAsyntask->errMessage = "RemoveDevice failed : no permission";
387 } else if (ret == ERR_INVALID_PARAM) {
388 napiAsyntask->errMessage = "RemoveDevice failed : invalid parameters";
389 } else {
390 napiAsyntask->errMessage = "RemoveDevice failed : native server exception";
391 }
392 napiAsyntask->status = napi_generic_failure;
393 napiAsyntask->errCode = NapiErrors::errcode_[ret];
394 }
395 };
396
397 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
398 return NapiAsyncWork::Enqueue(env, napiAsyntask, "RemoveDevice", executor, complete);
399 }
400
GetSessionId(napi_env env,napi_callback_info info)401 napi_value NapiCastSession::GetSessionId(napi_env env, napi_callback_info info)
402 {
403 CLOGD("Start to get sessionId in");
404 struct ConcreteTask : public NapiAsyncTask {
405 string sessionId_;
406 };
407 auto napiAsyntask = std::make_shared<ConcreteTask>();
408 if (napiAsyntask == nullptr) {
409 CLOGE("Create NapiAsyncTask failed");
410 return GetUndefinedValue(env);
411 }
412
413 napiAsyntask->GetJSInfo(env, info);
414 auto executor = [napiAsyntask]() {
415 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
416 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
417 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
418 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
419 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
420 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
421 int32_t ret = castSession->GetSessionId(napiAsyntask->sessionId_);
422 if (ret != CAST_ENGINE_SUCCESS) {
423 if (ret == ERR_NO_PERMISSION) {
424 napiAsyntask->errMessage = "GetSessionId failed : no permission";
425 } else {
426 napiAsyntask->errMessage = "GetSessionId failed : native server exception";
427 }
428 napiAsyntask->status = napi_generic_failure;
429 napiAsyntask->errCode = NapiErrors::errcode_[ret];
430 }
431 };
432
433 auto complete = [env, napiAsyntask](napi_value &output) {
434 napiAsyntask->status =
435 napi_create_string_utf8(env, napiAsyntask->sessionId_.c_str(), NAPI_AUTO_LENGTH, &output);
436 CHECK_STATUS_RETURN_VOID(napiAsyntask, "napi_create_string_utf8 failed",
437 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
438 };
439 return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetSessionId", executor, complete);
440 }
441
SetSessionProperty(napi_env env,napi_callback_info info)442 napi_value NapiCastSession::SetSessionProperty(napi_env env, napi_callback_info info)
443 {
444 CLOGD("Start to set sessionProperty in");
445 struct ConcreteTask : public NapiAsyncTask {
446 CastSessionProperty castSessionProperty_;
447 };
448 auto napiAsyntask = std::make_shared<ConcreteTask>();
449 if (napiAsyntask == nullptr) {
450 CLOGE("Create NapiAsyncTask failed");
451 return GetUndefinedValue(env);
452 }
453
454 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
455 constexpr size_t expectedArgc = 1;
456 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
457 NapiErrors::errcode_[ERR_INVALID_PARAM]);
458 napi_valuetype expectedTypes[expectedArgc] = { napi_object };
459 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
460 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
461 NapiErrors::errcode_[ERR_INVALID_PARAM]);
462 napiAsyntask->castSessionProperty_ = GetCastSessionPropertyFromJS(env, argv[0]);
463 };
464 napiAsyntask->GetJSInfo(env, info, inputParser);
465 auto executor = [napiAsyntask]() {
466 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
467 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
468 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
469 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
470 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
471 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
472 int32_t ret = castSession->SetSessionProperty(napiAsyntask->castSessionProperty_);
473 if (ret != CAST_ENGINE_SUCCESS) {
474 if (ret == ERR_NO_PERMISSION) {
475 napiAsyntask->errMessage = "SetSessionProperty failed : no permission";
476 } else if (ret == ERR_INVALID_PARAM) {
477 napiAsyntask->errMessage = "SetSessionProperty failed : invalid parameters";
478 } else {
479 napiAsyntask->errMessage = "SetSessionProperty failed : native server exception";
480 }
481 napiAsyntask->status = napi_generic_failure;
482 napiAsyntask->errCode = NapiErrors::errcode_[ret];
483 }
484 };
485
486 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
487 return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetSessionProperty", executor, complete);
488 }
489
CreateMirrorPlayer(napi_env env,napi_callback_info info)490 napi_value NapiCastSession::CreateMirrorPlayer(napi_env env, napi_callback_info info)
491 {
492 CLOGD("Start to create mirror Player");
493 struct ConcreteTask : public NapiAsyncTask {
494 shared_ptr<IMirrorPlayer> player_;
495 };
496 auto napiAsyntask = std::make_shared<ConcreteTask>();
497 if (napiAsyntask == nullptr) {
498 CLOGE("Create NapiAsyncTask failed");
499 return GetUndefinedValue(env);
500 }
501
502 napiAsyntask->GetJSInfo(env, info);
503 auto executor = [napiAsyntask]() {
504 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
505 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
506 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
507 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
508 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
509 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
510 int32_t ret = castSession->CreateMirrorPlayer(napiAsyntask->player_);
511 if (ret != CAST_ENGINE_SUCCESS) {
512 if (ret == ERR_NO_PERMISSION) {
513 napiAsyntask->errMessage = "CreateMirrorPlayer failed : no permission";
514 } else {
515 napiAsyntask->errMessage = "CreateMirrorPlayer failed : native server exception";
516 }
517 napiAsyntask->status = napi_generic_failure;
518 napiAsyntask->errCode = NapiErrors::errcode_[ret];
519 }
520 };
521
522 auto complete = [napiAsyntask](napi_value &output) {
523 napiAsyntask->status =
524 NapiMirrorPlayer::CreateNapiMirrorPlayer(napiAsyntask->env, napiAsyntask->player_, output);
525 CHECK_STATUS_RETURN_VOID(napiAsyntask, "convert native object to javascript object failed",
526 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
527 };
528 return NapiAsyncWork::Enqueue(env, napiAsyntask, "CreateMirrorPlayer", executor, complete);
529 }
530
CreateStreamPlayer(napi_env env,napi_callback_info info)531 napi_value NapiCastSession::CreateStreamPlayer(napi_env env, napi_callback_info info)
532 {
533 CLOGD("Start to create Stream Player");
534 struct ConcreteTask : public NapiAsyncTask {
535 shared_ptr<IStreamPlayer> player_;
536 };
537 auto napiAsyntask = std::make_shared<ConcreteTask>();
538 if (napiAsyntask == nullptr) {
539 CLOGE("Create NapiAsyncTask failed");
540 return GetUndefinedValue(env);
541 }
542
543 napiAsyntask->GetJSInfo(env, info);
544 auto executor = [napiAsyntask]() {
545 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
546 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
547 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
548 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
549 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
550 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
551 int32_t ret = castSession->CreateStreamPlayer(napiAsyntask->player_);
552 if (ret != CAST_ENGINE_SUCCESS) {
553 if (ret == ERR_NO_PERMISSION) {
554 napiAsyntask->errMessage = "CreateStreamPlayer failed : no permission";
555 } else {
556 napiAsyntask->errMessage = "CreateStreamPlayer failed : native server exception";
557 }
558 napiAsyntask->status = napi_generic_failure;
559 napiAsyntask->errCode = NapiErrors::errcode_[ret];
560 }
561 };
562
563 auto complete = [napiAsyntask](napi_value &output) {
564 napiAsyntask->status =
565 NapiStreamPlayer::CreateNapiStreamPlayer(napiAsyntask->env, napiAsyntask->player_, output);
566 CHECK_STATUS_RETURN_VOID(napiAsyntask, "convert native object to javascript object failed",
567 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
568 };
569 return NapiAsyncWork::Enqueue(env, napiAsyntask, "CreateStreamPlayer", executor, complete);
570 }
571
SetCastMode(napi_env env,napi_callback_info info)572 napi_value NapiCastSession::SetCastMode(napi_env env, napi_callback_info info)
573 {
574 CLOGD("Start to set cast mode in");
575 struct ConcreteTask : public NapiAsyncTask {
576 CastMode castMode_;
577 string jsonParam_;
578 };
579 auto napiAsyntask = std::make_shared<ConcreteTask>();
580 if (napiAsyntask == nullptr) {
581 CLOGE("Create NapiAsyncTask failed");
582 return GetUndefinedValue(env);
583 }
584
585 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
586 constexpr size_t expectedArgc = 2;
587 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
588 NapiErrors::errcode_[ERR_INVALID_PARAM]);
589 napi_valuetype expectedTypes[expectedArgc] = { napi_number, napi_string };
590 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
591 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
592 NapiErrors::errcode_[ERR_INVALID_PARAM]);
593 napiAsyntask->castMode_ = static_cast<CastMode>(ParseInt32(env, argv[0]));
594 napiAsyntask->jsonParam_ = ParseString(env, argv[1]);
595 };
596 napiAsyntask->GetJSInfo(env, info, inputParser);
597 auto executor = [napiAsyntask]() {
598 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
599 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
600 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
601 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
602 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
603 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
604 int32_t ret = castSession->SetCastMode(napiAsyntask->castMode_, napiAsyntask->jsonParam_);
605 if (ret != CAST_ENGINE_SUCCESS) {
606 if (ret == ERR_NO_PERMISSION) {
607 napiAsyntask->errMessage = "SetCastMode failed : no permission";
608 } else if (ret == ERR_INVALID_PARAM) {
609 napiAsyntask->errMessage = "SetCastMode failed : invalid parameters";
610 } else {
611 napiAsyntask->errMessage = "SetCastMode failed : native server exception";
612 }
613 napiAsyntask->status = napi_generic_failure;
614 napiAsyntask->errCode = NapiErrors::errcode_[ret];
615 }
616 };
617
618 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
619 return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetCastMode", executor, complete);
620 }
621
Release(napi_env env,napi_callback_info info)622 napi_value NapiCastSession::Release(napi_env env, napi_callback_info info)
623 {
624 CLOGD("Start to release in");
625 auto napiAsyntask = std::make_shared<NapiAsyncTask>();
626 if (napiAsyntask == nullptr) {
627 CLOGE("Create NapiAsyncTask failed");
628 return GetUndefinedValue(env);
629 }
630 napiAsyntask->GetJSInfo(env, info);
631
632 auto executor = [napiAsyntask]() {
633 auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
634 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
635 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
636 shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
637 CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
638 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
639 int32_t ret = castSession->Release();
640 if (ret == CAST_ENGINE_SUCCESS) {
641 napiSession->Reset();
642 } else if (ret == ERR_NO_PERMISSION) {
643 napiAsyntask->errMessage = "Release failed : no permission";
644 napiAsyntask->status = napi_generic_failure;
645 napiAsyntask->errCode = NapiErrors::errcode_[ret];
646 } else {
647 napiAsyntask->errMessage = "Release failed : native server exception";
648 napiAsyntask->status = napi_generic_failure;
649 napiAsyntask->errCode = NapiErrors::errcode_[ret];
650 }
651 };
652
653 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
654 return NapiAsyncWork::Enqueue(env, napiAsyntask, "Release", executor, complete);
655 }
656
NapiListenerGetter()657 std::shared_ptr<NapiCastSessionListener> NapiCastSession::NapiListenerGetter()
658 {
659 return listener_;
660 }
661
NapiListenerSetter(std::shared_ptr<NapiCastSessionListener> listener)662 void NapiCastSession::NapiListenerSetter(std::shared_ptr<NapiCastSessionListener> listener)
663 {
664 listener_ = listener;
665 }
666 } // namespace CastEngineClient
667 } // namespace CastEngine
668 } // namespace OHOS