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 mirror player.
15 * Author: zhangjingnan
16 * Create: 2023-5-27
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_mirror_player.h"
26 #include "napi_castengine_utils.h"
27 #include "napi_mirror_player.h"
28 #include "napi_async_work.h"
29 #include "pixel_map_napi.h"
30
31 using namespace OHOS::CastEngine::CastEngineClient;
32 using namespace std;
33
34 namespace OHOS {
35 namespace CastEngine {
36 namespace CastEngineClient {
37 DEFINE_CAST_ENGINE_LABEL("Cast-Napi-MirrorPlayer");
38
39 thread_local napi_ref NapiMirrorPlayer::consRef_ = nullptr;
40
DefineMirrorPlayerJSClass(napi_env env)41 void NapiMirrorPlayer::DefineMirrorPlayerJSClass(napi_env env)
42 {
43 napi_property_descriptor NapiMirrorPlayerDesc[] = {
44 DECLARE_NAPI_FUNCTION("play", Play),
45 DECLARE_NAPI_FUNCTION("pause", Pause),
46 DECLARE_NAPI_FUNCTION("setAppInfo", SetAppInfo),
47 DECLARE_NAPI_FUNCTION("setSurface", SetSurface),
48 DECLARE_NAPI_FUNCTION("release", Release),
49 DECLARE_NAPI_FUNCTION("resizeVirtualScreen", ResizeVirtualScreen),
50 DECLARE_NAPI_FUNCTION("setCastRoute", SetCastRoute),
51 DECLARE_NAPI_FUNCTION("getScreenshot", GetScreenshot)
52 };
53
54 napi_value mirrorPlayer = nullptr;
55 constexpr int initialRefCount = 1;
56 napi_status status = napi_define_class(env, "mirrorPlayer", NAPI_AUTO_LENGTH, NapiMirrorPlayerConstructor, nullptr,
57 sizeof(NapiMirrorPlayerDesc) / sizeof(NapiMirrorPlayerDesc[0]), NapiMirrorPlayerDesc, &mirrorPlayer);
58 if (status != napi_ok) {
59 CLOGE("napi_define_class failed");
60 return;
61 }
62 status = napi_create_reference(env, mirrorPlayer, initialRefCount, &consRef_);
63 if (status != napi_ok) {
64 CLOGE("DefineMirrorPlayerJSClass napi_create_reference failed");
65 }
66 }
67
NapiMirrorPlayerConstructor(napi_env env,napi_callback_info info)68 napi_value NapiMirrorPlayer::NapiMirrorPlayerConstructor(napi_env env, napi_callback_info info)
69 {
70 CLOGD("NapiMirrorPlayer start to construct in");
71 napi_value thisVar = nullptr;
72 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
73 CLOGD("NapiMirrorPlayer construct successfully");
74 return thisVar;
75 }
76
CreateNapiMirrorPlayer(napi_env env,shared_ptr<IMirrorPlayer> player,napi_value & out)77 napi_status NapiMirrorPlayer::CreateNapiMirrorPlayer(napi_env env, shared_ptr<IMirrorPlayer> player, napi_value &out)
78 {
79 CLOGD("Start to create napiMirrorPlayer in");
80 napi_value result = nullptr;
81 napi_value constructor = nullptr;
82 if (consRef_ == nullptr || player == nullptr) {
83 CLOGE("CreateNapiMirrorPlayer input is null");
84 return napi_generic_failure;
85 }
86 napi_status status = napi_get_reference_value(env, consRef_, &constructor);
87 if (status != napi_ok || constructor == nullptr) {
88 CLOGE("CreateNapiMirrorPlayer napi_get_reference_value failed");
89 return napi_generic_failure;
90 }
91
92 constexpr size_t argc = 0;
93 status = napi_new_instance(env, constructor, argc, nullptr, &result);
94 if (status != napi_ok) {
95 CLOGE("CreateNapiMirrorPlayer napi_new_instance failed");
96 return napi_generic_failure;
97 }
98
99 NapiMirrorPlayer *napiMirrorPlayer = new (std::nothrow) NapiMirrorPlayer(player);
100 if (napiMirrorPlayer == nullptr) {
101 CLOGE("NapiMirrorPlayer is nullptr");
102 return napi_generic_failure;
103 }
104 auto finalize = [](napi_env env, void *data, void *hint) {
105 NapiMirrorPlayer *player = reinterpret_cast<NapiMirrorPlayer *>(data);
106 if (player != nullptr) {
107 CLOGI("Session deconstructed");
108 delete player;
109 player = nullptr;
110 }
111 };
112 if (napi_wrap(env, result, napiMirrorPlayer, finalize, nullptr, nullptr) != napi_ok) {
113 CLOGE("CreateNapiMirrorPlayer napi_wrap failed");
114 delete napiMirrorPlayer;
115 napiMirrorPlayer = nullptr;
116 return napi_generic_failure;
117 }
118 out = result;
119 CLOGD("Create napiMirrorPlayer successfully");
120 return napi_ok;
121 }
122
Play(napi_env env,napi_callback_info info)123 napi_value NapiMirrorPlayer::Play(napi_env env, napi_callback_info info)
124 {
125 CLOGD("Start to play in");
126 struct ConcreteTask : public NapiAsyncTask {
127 string deviceId_;
128 };
129 auto napiAsyntask = std::make_shared<ConcreteTask>();
130 if (napiAsyntask == nullptr) {
131 CLOGE("Create NapiAsyncTask failed");
132 return GetUndefinedValue(env);
133 }
134
135 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
136 constexpr size_t expectedArgc = 1;
137 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
138 NapiErrors::errcode_[ERR_INVALID_PARAM]);
139 napi_valuetype expectedTypes[expectedArgc] = { napi_string };
140 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
141 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
142 NapiErrors::errcode_[ERR_INVALID_PARAM]);
143 napiAsyntask->deviceId_ = ParseString(env, argv[0]);
144 };
145 napiAsyntask->GetJSInfo(env, info, inputParser);
146 auto executor = [napiAsyntask]() {
147 auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
148 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
149 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
150 shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
151 CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
152 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
153 int32_t ret = mirrorPlayer->Play(napiAsyntask->deviceId_);
154 if (ret != CAST_ENGINE_SUCCESS) {
155 if (ret == ERR_NO_PERMISSION) {
156 napiAsyntask->errMessage = "Play failed : no permission";
157 } else {
158 napiAsyntask->errMessage = "Play failed : native server exception";
159 }
160 napiAsyntask->status = napi_generic_failure;
161 napiAsyntask->errCode = NapiErrors::errcode_[ret];
162 }
163 };
164
165 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
166 return NapiAsyncWork::Enqueue(env, napiAsyntask, "Play", executor, complete);
167 }
168
Pause(napi_env env,napi_callback_info info)169 napi_value NapiMirrorPlayer::Pause(napi_env env, napi_callback_info info)
170 {
171 CLOGD("Start to pause in");
172 struct ConcreteTask : public NapiAsyncTask {
173 string deviceId_;
174 };
175 auto napiAsyntask = std::make_shared<ConcreteTask>();
176 if (napiAsyntask == nullptr) {
177 CLOGE("Create NapiAsyncTask failed");
178 return GetUndefinedValue(env);
179 }
180
181 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
182 constexpr size_t expectedArgc = 1;
183 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
184 NapiErrors::errcode_[ERR_INVALID_PARAM]);
185 napi_valuetype expectedTypes[expectedArgc] = { napi_string };
186 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
187 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
188 NapiErrors::errcode_[ERR_INVALID_PARAM]);
189 napiAsyntask->deviceId_ = ParseString(env, argv[0]);
190 };
191 napiAsyntask->GetJSInfo(env, info, inputParser);
192 auto executor = [napiAsyntask]() {
193 auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
194 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
195 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
196 shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
197 CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
198 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
199 int32_t ret = mirrorPlayer->Pause(napiAsyntask->deviceId_);
200 if (ret != CAST_ENGINE_SUCCESS) {
201 if (ret == ERR_NO_PERMISSION) {
202 napiAsyntask->errMessage = "Pause failed : no permission";
203 } else {
204 napiAsyntask->errMessage = "Pause failed : native server exception";
205 }
206 napiAsyntask->status = napi_generic_failure;
207 napiAsyntask->errCode = NapiErrors::errcode_[ret];
208 }
209 };
210
211 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
212 return NapiAsyncWork::Enqueue(env, napiAsyntask, "Pause", executor, complete);
213 }
214
SetSurface(napi_env env,napi_callback_info info)215 napi_value NapiMirrorPlayer::SetSurface(napi_env env, napi_callback_info info)
216 {
217 CLOGD("Start to set surface in");
218 struct ConcreteTask : public NapiAsyncTask {
219 string surfaceId_;
220 };
221 auto napiAsyntask = std::make_shared<ConcreteTask>();
222 if (napiAsyntask == nullptr) {
223 CLOGE("Create NapiAsyncTask failed");
224 return GetUndefinedValue(env);
225 }
226
227 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
228 constexpr size_t expectedArgc = 1;
229 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
230 NapiErrors::errcode_[ERR_INVALID_PARAM]);
231 napi_valuetype expectedTypes[expectedArgc] = { napi_string };
232 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
233 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
234 NapiErrors::errcode_[ERR_INVALID_PARAM]);
235 napiAsyntask->surfaceId_ = ParseString(env, argv[0]);
236 };
237 napiAsyntask->GetJSInfo(env, info, inputParser);
238 auto executor = [napiAsyntask]() {
239 auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
240 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
241 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
242 shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
243 CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
244 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
245 int32_t ret = mirrorPlayer->SetSurface(napiAsyntask->surfaceId_);
246 if (ret != CAST_ENGINE_SUCCESS) {
247 if (ret == ERR_NO_PERMISSION) {
248 napiAsyntask->errMessage = "SetSurface failed : no permission";
249 } else {
250 napiAsyntask->errMessage = "SetSurface failed : native server exception";
251 }
252 napiAsyntask->status = napi_generic_failure;
253 napiAsyntask->errCode = NapiErrors::errcode_[ret];
254 }
255 };
256
257 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
258 return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetSurface", executor, complete);
259 }
260
SetAppInfo(napi_env env,napi_callback_info info)261 napi_value NapiMirrorPlayer::SetAppInfo(napi_env env, napi_callback_info info)
262 {
263 CLOGD("Start to set appInfo in");
264 struct ConcreteTask : public NapiAsyncTask {
265 int32_t appUid;
266 uint32_t appTokenId;
267 int32_t appPid;
268 };
269 auto napiAsyntask = std::make_shared<ConcreteTask>();
270 if (napiAsyntask == nullptr) {
271 CLOGE("Create NapiAsyncTask failed");
272 return GetUndefinedValue(env);
273 }
274
275 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
276 constexpr size_t expectedArgc = 3;
277 napi_valuetype expectedTypes[expectedArgc] = { napi_number, napi_number, napi_number};
278 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
279 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
280 NapiErrors::errcode_[ERR_INVALID_PARAM]);
281 napiAsyntask->appUid = ParseInt32(env, argv[0]);
282 napiAsyntask->appTokenId = static_cast<uint32_t>(ParseInt32(env, argv[1]));
283 napiAsyntask->appPid = ParseInt32(env, argv[2]);
284 };
285
286 napiAsyntask->GetJSInfo(env, info, inputParser);
287 auto executor = [napiAsyntask]() {
288 auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
289 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
290 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
291 shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
292 CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
293 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
294 CLOGI("SetAppInfo in");
295 int32_t ret = mirrorPlayer->SetAppInfo({napiAsyntask->appUid, napiAsyntask->appTokenId, napiAsyntask->appPid});
296 CLOGI("SetAppInfo out");
297 if (ret != CAST_ENGINE_SUCCESS) {
298 if (ret == ERR_NO_PERMISSION) {
299 napiAsyntask->errMessage = "SetAppInfo failed : no permission";
300 } else {
301 napiAsyntask->errMessage = "SetAppInfo failed : native server exception";
302 }
303 napiAsyntask->status = napi_generic_failure;
304 napiAsyntask->errCode = NapiErrors::errcode_[ret];
305 }
306 };
307 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
308 return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetAppInfo", executor, complete);
309 }
310
Release(napi_env env,napi_callback_info info)311 napi_value NapiMirrorPlayer::Release(napi_env env, napi_callback_info info)
312 {
313 CLOGD("Start to release in");
314 auto napiAsyntask = std::make_shared<NapiAsyncTask>();
315 if (napiAsyntask == nullptr) {
316 CLOGE("Create NapiAsyncTask failed");
317 return GetUndefinedValue(env);
318 }
319 napiAsyntask->GetJSInfo(env, info);
320
321 auto executor = [napiAsyntask]() {
322 auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
323 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
324 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
325 shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
326 CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
327 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
328 int32_t ret = mirrorPlayer->Release();
329 if (ret == CAST_ENGINE_SUCCESS) {
330 napiPlayer->Reset();
331 } else if (ret == ERR_NO_PERMISSION) {
332 napiAsyntask->errMessage = "Release failed : no permission";
333 napiAsyntask->status = napi_generic_failure;
334 napiAsyntask->errCode = NapiErrors::errcode_[ret];
335 } else {
336 napiAsyntask->errMessage = "Release failed : native server exception";
337 napiAsyntask->status = napi_generic_failure;
338 napiAsyntask->errCode = NapiErrors::errcode_[ret];
339 }
340 };
341
342 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
343 return NapiAsyncWork::Enqueue(env, napiAsyntask, "Release", executor, complete);
344 }
345
ResizeVirtualScreen(napi_env env,napi_callback_info info)346 napi_value NapiMirrorPlayer::ResizeVirtualScreen(napi_env env, napi_callback_info info)
347 {
348 struct ConcreteTask : public NapiAsyncTask {
349 uint32_t width_;
350 uint32_t height_;
351 };
352 auto napiAsyntask = std::make_shared<ConcreteTask>();
353 if (napiAsyntask == nullptr) {
354 CLOGE("Create NapiAsyncTask failed");
355 return GetUndefinedValue(env);
356 }
357
358 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
359 constexpr size_t expectedArgc = 2;
360 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
361 NapiErrors::errcode_[ERR_INVALID_PARAM]);
362 napi_valuetype expectedTypes[expectedArgc] = { napi_number, napi_number };
363 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
364 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
365 NapiErrors::errcode_[ERR_INVALID_PARAM]);
366 napiAsyntask->width_ = ParseUint32(env, argv[0]);
367 napiAsyntask->height_ = ParseUint32(env, argv[1]);
368 };
369 napiAsyntask->GetJSInfo(env, info, inputParser);
370 auto executor = [napiAsyntask]() {
371 auto *napiMirrorPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
372 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiMirrorPlayer != nullptr, "napiMirrorPlayer is null",
373 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
374 std::shared_ptr<IMirrorPlayer> mirrorPlayer = napiMirrorPlayer->GetMirrorPlayer();
375 CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
376 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
377 int32_t ret = mirrorPlayer->ResizeVirtualScreen(napiAsyntask->width_, napiAsyntask->height_);
378 if (ret != CAST_ENGINE_SUCCESS) {
379 if (ret == ERR_NO_PERMISSION) {
380 napiAsyntask->errMessage = "ResizeVirtualScreen failed : no permission";
381 } else if (ret == ERR_INVALID_PARAM) {
382 napiAsyntask->errMessage = "ResizeVirtualScreen failed : invalid parameters";
383 } else {
384 napiAsyntask->errMessage = "ResizeVirtualScreen failed : native server exception";
385 }
386 napiAsyntask->status = napi_generic_failure;
387 napiAsyntask->errCode = NapiErrors::errcode_[ret];
388 }
389 };
390
391 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
392 return NapiAsyncWork::Enqueue(env, napiAsyntask, "ResizeVirtualScreen", executor, complete);
393 }
394
SetCastRoute(napi_env env,napi_callback_info info)395 napi_value NapiMirrorPlayer::SetCastRoute(napi_env env, napi_callback_info info)
396 {
397 struct ConcreteTask : public NapiAsyncTask {
398 bool remote_;
399 };
400
401 auto napiAsyntask = std::make_shared<ConcreteTask>();
402 if (napiAsyntask == nullptr) {
403 CLOGE("Create NapiAsyncTask failed");
404 return GetUndefinedValue(env);
405 }
406
407 auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
408 constexpr size_t expectedArgc = 1;
409 CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
410 NapiErrors::errcode_[ERR_INVALID_PARAM]);
411 napi_valuetype expectedTypes[expectedArgc] = { napi_boolean };
412 bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
413 CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
414 NapiErrors::errcode_[ERR_INVALID_PARAM]);
415 napiAsyntask->remote_ = ParseBool(env, argv[0]);
416 };
417
418 napiAsyntask->GetJSInfo(env, info, inputParser);
419 auto executor = [napiAsyntask]() {
420 auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
421 CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
422 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
423 shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
424 CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
425 NapiErrors::errcode_[CAST_ENGINE_ERROR]);
426 int32_t ret = mirrorPlayer->SetCastRoute(napiAsyntask->remote_);
427 if (ret != CAST_ENGINE_SUCCESS) {
428 if (ret == ERR_NO_PERMISSION) {
429 napiAsyntask->errMessage = "SetCastRoute failed : no permission";
430 } else if (ret == ERR_INVALID_PARAM) {
431 napiAsyntask->errMessage = "SetCastRoute failed : invalid parameters";
432 } else {
433 napiAsyntask->errMessage = "SetCastRoute failed : native server exception";
434 }
435 napiAsyntask->status = napi_generic_failure;
436 napiAsyntask->errCode = NapiErrors::errcode_[ret];
437 }
438 };
439
440 auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
441 return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetCastRoute", executor, complete);
442 }
443
GetScreenshot(napi_env env,napi_callback_info info)444 napi_value NapiMirrorPlayer::GetScreenshot(napi_env env, napi_callback_info info)
445 {
446 struct ConcreteTask : public NapiAsyncTask {
447 std::shared_ptr<Media::PixelMap> screenShot_;
448 };
449
450 auto napiAsyntask = std::make_shared<ConcreteTask>();
451 if (napiAsyntask == nullptr) {
452 CLOGE("Create NapiAsyncTask failed");
453 return GetUndefinedValue(env);
454 }
455
456 napiAsyntask->GetJSInfo(env, info);
457 auto executor = [napiAsyntask]() {
458 auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
459 CHECK_ARGS_RETURN_VOID(
460 napiAsyntask, napiPlayer != nullptr, "napiPlayer is null", NapiErrors::errcode_[CAST_ENGINE_ERROR]);
461 shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
462 CHECK_ARGS_RETURN_VOID(
463 napiAsyntask, mirrorPlayer, "IMirrorPlayer is null", NapiErrors::errcode_[CAST_ENGINE_ERROR]);
464 int32_t ret = mirrorPlayer->GetScreenshot(napiAsyntask->screenShot_);
465 if (ret != CAST_ENGINE_SUCCESS) {
466 if (ret == ERR_NO_PERMISSION) {
467 napiAsyntask->errMessage = "GetScreenshot failed : no permission";
468 } else if (ret == ERR_INVALID_PARAM) {
469 napiAsyntask->errMessage = "GetScreenshot failed : invalid parameters";
470 } else {
471 napiAsyntask->errMessage = "GetScreenshot failed : native server exception";
472 }
473 napiAsyntask->status = napi_generic_failure;
474 napiAsyntask->errCode = NapiErrors::errcode_[ret];
475 }
476 };
477 auto complete = [env, napiAsyntask](napi_value &output) {
478 output = Media::PixelMapNapi::CreatePixelMap(env, napiAsyntask->screenShot_);
479 };
480 return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetScreenshot", executor, complete);
481 }
482 } // namespace CastEngineClient
483 } // namespace CastEngine
484 } // namespace OHOS