• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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