• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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  */
15 
16 #include "native_screenshot_module.h"
17 
18 #include <cinttypes>
19 #include <cstddef>
20 #include <cstdint>
21 #include <image_type.h>
22 #include <iosfwd>
23 #include <js_native_api.h>
24 #include <js_native_api_types.h>
25 #include <memory>
26 #include <napi/native_api.h>
27 #include <napi/native_common.h>
28 #include <string>
29 #include <type_traits>
30 
31 #include "display_manager.h"
32 #include "pixel_map.h"
33 #include "pixel_map_napi.h"
34 #include "window_manager_hilog.h"
35 #include "dm_common.h"
36 #include "dm_napi_common.h"
37 
38 namespace OHOS::Rosen {
39 namespace save {
40 static const uint32_t PIXMAP_VECTOR_ONLY_SDR_SIZE = 1;
41 static const uint32_t PIXMAP_VECTOR_SIZE = 2;
42 static const uint32_t SDR_PIXMAP = 0;
43 static const uint32_t HDR_PIXMAP = 1;
44 struct Option {
45     Media::Rect rect;
46     Media::Size size;
47     int rotation = 0;
48     DisplayId displayId = 0;
49     bool isNeedNotify = true;
50     bool isNeedPointer = true;
51     bool isCaptureFullOfScreen = false;
52 };
53 
54 struct Param {
55     DmErrorCode wret;
56     Option option;
57     std::string errMessage;
58     bool useInputOption;
59     bool validInputParam;
60     std::shared_ptr<Media::PixelMap> image;
61     Media::Rect imageRect;
62     bool isPick;
63 };
64 
65 struct HdrParam {
66     DmErrorCode wret;
67     Option option;
68     std::string errMessage;
69     bool useInputOption;
70     bool validInputParam;
71     std::vector<std::shared_ptr<Media::PixelMap>> imageVec;
72     Media::Rect imageRect;
73     bool isPick;
74 };
75 
GetType(napi_env env,napi_value root)76 static napi_valuetype GetType(napi_env env, napi_value root)
77 {
78     napi_valuetype res = napi_undefined;
79     napi_typeof(env, root, &res);
80     return res;
81 }
82 
GetDisplayId(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)83 static void GetDisplayId(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
84 {
85     TLOGI(WmsLogTag::DMS, "Get Screenshot Option: GetDisplayId");
86     napi_value displayId;
87     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "displayId", &displayId));
88     if (displayId != nullptr && GetType(env, displayId) == napi_number) {
89         int64_t dispId;
90         NAPI_CALL_RETURN_VOID(env, napi_get_value_int64(env, displayId, &dispId));
91         param->option.displayId = static_cast<DisplayId>(dispId);
92         TLOGI(WmsLogTag::DMS, "GetDisplayId success, displayId = %{public}" PRIu64"", param->option.displayId);
93     } else {
94         TLOGI(WmsLogTag::DMS, "GetDisplayId failed, invalid param, use default displayId = 0");
95     }
96 }
97 
GetRotation(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)98 static void GetRotation(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
99 {
100     TLOGI(WmsLogTag::DMS, "Get Screenshot Option: GetRotation");
101     napi_value rotation;
102     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "rotation", &rotation));
103     if (rotation != nullptr && GetType(env, rotation) == napi_number) {
104         NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, rotation, &param->option.rotation));
105         TLOGI(WmsLogTag::DMS, "GetRotation success, rotation = %{public}d", param->option.rotation);
106     } else {
107         TLOGI(WmsLogTag::DMS, "GetRotation failed, invalid param, use default rotation = 0");
108     }
109 }
110 
GetScreenRect(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)111 static void GetScreenRect(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
112 {
113     TLOGI(WmsLogTag::DMS, "Get Screenshot Option: GetScreenRect");
114     napi_value screenRect;
115     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "screenRect", &screenRect));
116     if (screenRect != nullptr && GetType(env, screenRect) == napi_object) {
117         TLOGI(WmsLogTag::DMS, "get ScreenRect success");
118 
119         napi_value left;
120         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, screenRect, "left", &left));
121         if (left != nullptr && GetType(env, left) == napi_number) {
122             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, left, &param->option.rect.left));
123             TLOGI(WmsLogTag::DMS, "left success, left = %{public}d", param->option.rect.left);
124         } else {
125             TLOGI(WmsLogTag::DMS, "left failed, invalid param, use default left = 0");
126         }
127 
128         napi_value top;
129         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, screenRect, "top", &top));
130         if (top != nullptr && GetType(env, top) == napi_number) {
131             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, top, &param->option.rect.top));
132             TLOGI(WmsLogTag::DMS, "top success, top = %{public}d", param->option.rect.top);
133         } else {
134             TLOGI(WmsLogTag::DMS, "top failed, invalid param, use default top = 0");
135         }
136 
137         napi_value width;
138         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, screenRect, "width", &width));
139         if (width != nullptr && GetType(env, width) == napi_number) {
140             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, width, &param->option.rect.width));
141             TLOGI(WmsLogTag::DMS, "width success, width = %{public}d", param->option.rect.width);
142         } else {
143             TLOGI(WmsLogTag::DMS, "width failed, invalid param, use default width = 0");
144         }
145 
146         napi_value height;
147         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, screenRect, "height", &height));
148         if (height != nullptr && GetType(env, height) == napi_number) {
149             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, height, &param->option.rect.height));
150             TLOGI(WmsLogTag::DMS, "height success, height = %{public}d", param->option.rect.height);
151         } else {
152             TLOGI(WmsLogTag::DMS, "height failed, invalid param, use default height = 0");
153         }
154     } else {
155         TLOGI(WmsLogTag::DMS, "get ScreenRect failed, use default ScreenRect param");
156     }
157 }
158 
GetImageSize(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)159 static void GetImageSize(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
160 {
161     TLOGI(WmsLogTag::DMS, "Get Screenshot Option: ImageSize");
162     napi_value imageSize;
163     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "imageSize", &imageSize));
164     if (imageSize != nullptr && GetType(env, imageSize) == napi_object) {
165         napi_value width;
166         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, imageSize, "width", &width));
167         if (width != nullptr && GetType(env, width) == napi_number) {
168             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, width, &param->option.size.width));
169             TLOGI(WmsLogTag::DMS, "width success, width = %{public}d", param->option.size.width);
170         } else {
171             TLOGI(WmsLogTag::DMS, "width failed, invalid param, use default width = 0");
172         }
173 
174         napi_value height;
175         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, imageSize, "height", &height));
176         if (height != nullptr && GetType(env, height) == napi_number) {
177             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, height, &param->option.size.height));
178             TLOGI(WmsLogTag::DMS, "height success, height = %{public}d", param->option.size.height);
179         } else {
180             TLOGI(WmsLogTag::DMS, "height failed, invalid param, use default height = 0");
181         }
182     }
183 }
184 
IsNeedNotify(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)185 static void IsNeedNotify(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
186 {
187     TLOGI(WmsLogTag::DMS, "Get Screenshot Option: IsNeedNotify");
188     napi_value isNeedNotify;
189     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "isNotificationNeeded", &isNeedNotify));
190     if (isNeedNotify != nullptr && GetType(env, isNeedNotify) == napi_boolean) {
191         NAPI_CALL_RETURN_VOID(env, napi_get_value_bool(env, isNeedNotify, &param->option.isNeedNotify));
192         TLOGI(WmsLogTag::DMS, "IsNeedNotify: %{public}d", param->option.isNeedNotify);
193     } else {
194         TLOGI(WmsLogTag::DMS, "IsNeedNotify failed, invalid param, use default true.");
195     }
196 }
197 
IsNeedPointer(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)198 static void IsNeedPointer(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
199 {
200     TLOGI(WmsLogTag::DMS, "Get Screenshot Option: IsNeedPointer");
201     napi_value isNeedPointer;
202     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "isPointerNeeded", &isNeedPointer));
203     if (isNeedPointer != nullptr && GetType(env, isNeedPointer) == napi_boolean) {
204         NAPI_CALL_RETURN_VOID(env, napi_get_value_bool(env, isNeedPointer, &param->option.isNeedPointer));
205         TLOGI(WmsLogTag::DMS, "IsNeedPointer: %{public}d", param->option.isNeedPointer);
206     } else {
207         TLOGI(WmsLogTag::DMS, "IsNeedPointer failed, invalid param, use default true.");
208     }
209 }
210 
IsCaptureFullOfScreen(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)211 static void IsCaptureFullOfScreen(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
212 {
213     TLOGI(WmsLogTag::DMS, "Get Screenshot Option: isCaptureFullOfScreen");
214     napi_value isCaptureFullOfScreen;
215     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "isCaptureFullOfScreen", &isCaptureFullOfScreen));
216     if (isCaptureFullOfScreen != nullptr && GetType(env, isCaptureFullOfScreen) == napi_boolean) {
217         NAPI_CALL_RETURN_VOID(env, napi_get_value_bool(env, isCaptureFullOfScreen,
218             &param->option.isCaptureFullOfScreen));
219         TLOGI(WmsLogTag::DMS, "isCaptureFullOfScreen: %{public}d", param->option.isCaptureFullOfScreen);
220     } else {
221         TLOGI(WmsLogTag::DMS, "isCaptureFullOfScreen failed, invalid param, use default false.");
222     }
223 }
224 
GetScreenshotParam(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)225 static void GetScreenshotParam(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
226 {
227     if (param == nullptr) {
228         TLOGI(WmsLogTag::DMS, "param == nullptr, use default param");
229         return;
230     }
231     GetDisplayId(env, param, argv);
232     GetRotation(env, param, argv);
233     GetScreenRect(env, param, argv);
234     GetImageSize(env, param, argv);
235     IsNeedNotify(env, param, argv);
236     IsNeedPointer(env, param, argv);
237     IsCaptureFullOfScreen(env, param, argv);
238 }
239 
AsyncGetScreenshot(napi_env env,std::unique_ptr<Param> & param)240 static void AsyncGetScreenshot(napi_env env, std::unique_ptr<Param> &param)
241 {
242     if (!param->validInputParam) {
243         TLOGE(WmsLogTag::DMS, "Invalid Input Param!");
244         param->image = nullptr;
245         param->wret = DmErrorCode::DM_ERROR_INVALID_PARAM;
246         param->errMessage = "Get Screenshot Failed: Invalid input param";
247         return;
248     }
249     CaptureOption option = { param->option.displayId, param->option.isNeedNotify, param->option.isNeedPointer,
250         param->option.isCaptureFullOfScreen};
251     if (!param->isPick && (!option.isNeedNotify_ || !option.isNeedPointer_)) {
252         if (param->useInputOption) {
253             param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option,
254                 param->option.rect, param->option.size, param->option.rotation, &param->wret);
255         } else {
256             param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option, &param->wret);
257         }
258     } else {
259         if (param->useInputOption) {
260             TLOGI(WmsLogTag::DMS, "Get Screenshot by input option");
261             SnapShotConfig snapConfig;
262             snapConfig.displayId_ = param->option.displayId;
263             snapConfig.imageRect_ = param->option.rect;
264             snapConfig.imageSize_ = param->option.size;
265             snapConfig.rotation_ = param->option.rotation;
266             snapConfig.isCaptureFullOfScreen_ = param->option.isCaptureFullOfScreen;
267             param->image = DisplayManager::GetInstance().GetScreenshotwithConfig(snapConfig, &param->wret, true);
268         } else if (param->isPick) {
269             TLOGI(WmsLogTag::DMS, "Get Screenshot by picker");
270             param->image = DisplayManager::GetInstance().GetSnapshotByPicker(param->imageRect, &param->wret);
271         } else {
272             TLOGI(WmsLogTag::DMS, "Get Screenshot by default option");
273             param->image = DisplayManager::GetInstance().GetScreenshot(param->option.displayId, &param->wret, true,
274                 param->option.isCaptureFullOfScreen);
275         }
276     }
277     if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) {
278         TLOGI(WmsLogTag::DMS, "Get Screenshot failed!");
279         param->wret = DmErrorCode::DM_ERROR_INVALID_SCREEN;
280         param->errMessage = "Get Screenshot failed: Screenshot image is nullptr";
281         return;
282     }
283 }
284 
AsyncGetScreenHDRshot(napi_env env,std::unique_ptr<HdrParam> & param)285 static void AsyncGetScreenHDRshot(napi_env env, std::unique_ptr<HdrParam>& param)
286 {
287     if (!param->validInputParam) {
288         TLOGE(WmsLogTag::DMS, "Invalid Input Param!");
289         param->imageVec = {};
290         param->wret = DmErrorCode::DM_ERROR_INVALID_PARAM;
291         param->errMessage = "Get Screenshot Failed: Invalid input param";
292         return;
293     }
294     CaptureOption option = { param->option.displayId, param->option.isNeedNotify, param->option.isNeedPointer,
295         param->option.isCaptureFullOfScreen};
296     if (!option.isNeedNotify_) {
297         param->imageVec = DisplayManager::GetInstance().GetScreenHDRshotWithOption(option, param->wret);
298     } else {
299         TLOGI(WmsLogTag::DMS, "Get Screenshot by default option");
300         param->imageVec = DisplayManager::GetInstance().GetScreenHDRshot(param->option.displayId, param->wret,
301             true, param->option.isCaptureFullOfScreen);
302     }
303     if ((param->imageVec.size() != PIXMAP_VECTOR_SIZE || param->imageVec[SDR_PIXMAP] == nullptr) &&
304         param->wret == DmErrorCode::DM_OK) {
305         TLOGI(WmsLogTag::DMS, "Get Screenshot failed!");
306         param->wret = DmErrorCode::DM_ERROR_INVALID_SCREEN;
307         param->errMessage = "Get Screenshot failed: Screenshot imageVec is nullptr";
308         return;
309     }
310 }
311 
CreateJsNumber(napi_env env,int32_t value)312 napi_value CreateJsNumber(napi_env env, int32_t value)
313 {
314     napi_value valRet = nullptr;
315     napi_create_int32(env, value, &valRet);
316     return valRet;
317 }
318 
CreateJsRectObject(napi_env env,Media::Rect imageRect)319 napi_value CreateJsRectObject(napi_env env, Media::Rect imageRect)
320 {
321     napi_value objValue = nullptr;
322     NAPI_CALL(env, napi_create_object(env, &objValue));
323     napi_set_named_property(env, objValue, "left", CreateJsNumber(env, imageRect.left));
324     napi_set_named_property(env, objValue, "top", CreateJsNumber(env, imageRect.top));
325     napi_set_named_property(env, objValue, "width", CreateJsNumber(env, imageRect.width));
326     napi_set_named_property(env, objValue, "height", CreateJsNumber(env, imageRect.height));
327     return objValue;
328 }
329 
CreateJsPickerObject(napi_env env,std::unique_ptr<Param> & param)330 napi_value CreateJsPickerObject(napi_env env, std::unique_ptr<Param> &param)
331 {
332     napi_value objValue = nullptr;
333     NAPI_CALL(env, napi_create_object(env, &objValue));
334     if (param == nullptr) {
335         napi_value result;
336         TLOGE(WmsLogTag::DMS, "param nullptr.");
337         NAPI_CALL(env, napi_get_undefined(env, &result));
338         return result;
339     }
340     napi_set_named_property(env, objValue, "pixelMap", OHOS::Media::PixelMapNapi::CreatePixelMap(env, param->image));
341     napi_set_named_property(env, objValue, "pickRect", CreateJsRectObject(env, param->imageRect));
342     TLOGI(WmsLogTag::DMS, "pick end");
343     return objValue;
344 }
345 
Resolve(napi_env env,std::unique_ptr<Param> & param)346 napi_value Resolve(napi_env env, std::unique_ptr<Param> &param)
347 {
348     napi_value result;
349     napi_value error;
350     napi_value code;
351     bool isThrowError = true;
352     if (param->wret != DmErrorCode::DM_OK) {
353         napi_create_error(env, nullptr, nullptr, &error);
354         napi_create_int32(env, (int32_t)param->wret, &code);
355     }
356     switch (param->wret) {
357         case DmErrorCode::DM_ERROR_NO_PERMISSION:
358             napi_set_named_property(env, error, "DM_ERROR_NO_PERMISSION", code);
359             break;
360         case DmErrorCode::DM_ERROR_INVALID_PARAM:
361             napi_set_named_property(env, error, "DM_ERROR_INVALID_PARAM", code);
362             break;
363         case DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT:
364             napi_set_named_property(env, error, "DM_ERROR_DEVICE_NOT_SUPPORT", code);
365             break;
366         case DmErrorCode::DM_ERROR_SYSTEM_INNORMAL:
367             napi_set_named_property(env, error, "DM_ERROR_SYSTEM_INNORMAL", code);
368             break;
369         default:
370             isThrowError = false;
371             TLOGI(WmsLogTag::DMS, "screen shot default.");
372             break;
373     }
374     TLOGI(WmsLogTag::DMS, "screen shot ret=%{public}d.", param->wret);
375     if (isThrowError) {
376         napi_throw(env, error);
377         return error;
378     }
379     if (param->wret != DmErrorCode::DM_OK) {
380         NAPI_CALL(env, napi_get_undefined(env, &result));
381         return result;
382     }
383     if (param->isPick) {
384         TLOGI(WmsLogTag::DMS, "Resolve Screenshot by picker");
385         return CreateJsPickerObject(env, param);
386     }
387     if (param->image != nullptr) {
388         TLOGI(WmsLogTag::DMS, "Screenshot image Width %{public}d, Height %{public}d",
389             param->image->GetWidth(), param->image->GetHeight());
390     }
391     napi_value jsImage = OHOS::Media::PixelMapNapi::CreatePixelMap(env, param->image);
392     return jsImage;
393 }
394 
CreateJsPixelmapVec(napi_env env,std::unique_ptr<HdrParam> & param)395 napi_value CreateJsPixelmapVec(napi_env env, std::unique_ptr<HdrParam>& param)
396 {
397     napi_value jsPixelmapVec = nullptr;
398     napi_value result;
399     uint32_t pixReturnJsVecLength = 0;
400     if (param->imageVec[HDR_PIXMAP] == nullptr) {
401         pixReturnJsVecLength = PIXMAP_VECTOR_ONLY_SDR_SIZE;
402     } else {
403         pixReturnJsVecLength = PIXMAP_VECTOR_SIZE;
404     }
405     napi_create_array_with_length(env, pixReturnJsVecLength, &jsPixelmapVec);
406     if (jsPixelmapVec == nullptr) {
407         TLOGE(WmsLogTag::DMS, "Failed to create pixelmap array");
408         NAPI_CALL(env, napi_get_undefined(env, &result));
409         return result;
410     }
411     uint32_t index = 0;
412     for (const auto& pixelmap : param->imageVec) {
413         if (pixelmap == nullptr) {
414             break;
415         }
416         napi_set_element(env, jsPixelmapVec, index++, OHOS::Media::PixelMapNapi::CreatePixelMap(env, pixelmap));
417     }
418     return jsPixelmapVec;
419 }
420 
HDRResolve(napi_env env,std::unique_ptr<HdrParam> & param)421 napi_value HDRResolve(napi_env env, std::unique_ptr<HdrParam>& param)
422 {
423     napi_status ret = napi_ok;
424     napi_value result;
425     napi_value error;
426     napi_value code;
427     bool isThrowError = true;
428     if (param->wret != DmErrorCode::DM_OK) {
429         napi_create_error(env, nullptr, nullptr, &error);
430         napi_create_int32(env, (int32_t)param->wret, &code);
431     }
432     switch (param->wret) {
433         case DmErrorCode::DM_ERROR_NO_PERMISSION:
434             ret = napi_set_named_property(env, error, "DM_ERROR_NO_PERMISSION", code);
435             if (ret != napi_ok) {
436                 TLOGE(WmsLogTag::DMS, "napi_set_named_property error, code is %{public}d", ret);
437             }
438             break;
439         case DmErrorCode::DM_ERROR_INVALID_PARAM:
440             ret = napi_set_named_property(env, error, "DM_ERROR_INVALID_PARAM", code);
441             if (ret != napi_ok) {
442                 TLOGE(WmsLogTag::DMS, "napi_set_named_property error, code is %{public}d", ret);
443             }
444             break;
445         case DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT:
446             ret = napi_set_named_property(env, error, "DM_ERROR_DEVICE_NOT_SUPPORT", code);
447             if (ret != napi_ok) {
448                 TLOGE(WmsLogTag::DMS, "napi_set_named_property error, code is %{public}d", ret);
449             }
450             break;
451         case DmErrorCode::DM_ERROR_SYSTEM_INNORMAL:
452             ret = napi_set_named_property(env, error, "DM_ERROR_SYSTEM_INNORMAL", code);
453             if (ret != napi_ok) {
454                 TLOGE(WmsLogTag::DMS, "napi_set_named_property error, code is %{public}d", ret);
455             }
456             break;
457         default:
458             isThrowError = false;
459             break;
460     }
461     TLOGI(WmsLogTag::DMS, "screen shot ret=%{public}d.", param->wret);
462     if (isThrowError) {
463         napi_throw(env, error);
464         return error;
465     }
466     if (param->wret != DmErrorCode::DM_OK) {
467         NAPI_CALL(env, napi_get_undefined(env, &result));
468         return result;
469     }
470 
471     return CreateJsPixelmapVec(env, param);
472 }
473 
PickFunc(napi_env env,napi_callback_info info)474 napi_value PickFunc(napi_env env, napi_callback_info info)
475 {
476     TLOGI(WmsLogTag::DMS, "%{public}s called", __PRETTY_FUNCTION__);
477     napi_value argv[1] = { nullptr };  // the max number of input parameters is 1
478     size_t argc = 1;  // the max number of input parameters is 1
479     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
480 
481     auto param = std::make_unique<Param>();
482     if (param == nullptr) {
483         TLOGE(WmsLogTag::DMS, "Create param failed.");
484         return nullptr;
485     }
486     napi_ref ref = nullptr;
487     if (argc == 0) {  // 0 valid parameters
488         TLOGI(WmsLogTag::DMS, "argc == 0");
489         param->validInputParam = true;
490     } else if (GetType(env, argv[0]) == napi_function) {  // 1 valid parameters napi_function
491         TLOGI(WmsLogTag::DMS, "argc >= 1, argv[0]'s type is napi_function");
492         param->validInputParam = true;
493         NAPI_CALL(env, napi_create_reference(env, argv[0], 1, &ref));
494     } else {  // 0 valid parameters
495         TLOGI(WmsLogTag::DMS, "argc == 0");
496         param->validInputParam = true;
497     }
498     param->isPick = true;
499     return AsyncProcess<Param>(env, __PRETTY_FUNCTION__, AsyncGetScreenshot, Resolve, ref, param);
500 }
501 
AsyncGetScreenCapture(napi_env env,std::unique_ptr<Param> & param)502 static void AsyncGetScreenCapture(napi_env env, std::unique_ptr<Param> &param)
503 {
504     CaptureOption captureOption;
505     captureOption.displayId_ = param->option.displayId;
506     captureOption.isNeedNotify_ = param->option.isNeedNotify;
507     captureOption.isNeedPointer_ = param->option.isNeedPointer;
508     TLOGI(WmsLogTag::DMS, "capture option isNeedNotify=%{public}d isNeedPointer=%{public}d", captureOption.isNeedNotify_,
509         captureOption.isNeedPointer_);
510     param->image = DisplayManager::GetInstance().GetScreenCapture(captureOption, &param->wret);
511     if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) {
512         TLOGI(WmsLogTag::DMS, "screen capture failed!");
513         param->wret = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
514         param->errMessage = "ScreenCapture failed: image is null.";
515         return;
516     }
517 }
518 
CaptureFunc(napi_env env,napi_callback_info info)519 napi_value CaptureFunc(napi_env env, napi_callback_info info)
520 {
521     TLOGI(WmsLogTag::DMS, "%{public}s called", __PRETTY_FUNCTION__);
522     napi_value argv[1] = { nullptr };
523     size_t argc = 1;
524     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
525 
526     auto param = std::make_unique<Param>();
527     if (param == nullptr) {
528         TLOGE(WmsLogTag::DMS, "Create param failed.");
529         return nullptr;
530     }
531     param->option.displayId = DisplayManager::GetInstance().GetDefaultDisplayId();
532     napi_ref ref = nullptr;
533     if (argc > 0 && GetType(env, argv[0]) == napi_object) {
534         TLOGI(WmsLogTag::DMS, "argv[0]'s type is napi_object");
535         GetScreenshotParam(env, param, argv[0]);
536     } else {
537         TLOGI(WmsLogTag::DMS, "use default.");
538     }
539     return AsyncProcess<Param>(env, __PRETTY_FUNCTION__, AsyncGetScreenCapture, Resolve, ref, param);
540 }
541 
MainFunc(napi_env env,napi_callback_info info)542 napi_value MainFunc(napi_env env, napi_callback_info info)
543 {
544     TLOGI(WmsLogTag::DMS, "%{public}s called", __PRETTY_FUNCTION__);
545     napi_value argv[2] = {nullptr}; // the max number of input parameters is 2
546     size_t argc = 2; // the max number of input parameters is 2
547     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
548 
549     auto param = std::make_unique<Param>();
550     if (param == nullptr) {
551         TLOGE(WmsLogTag::DMS, "Create param failed.");
552         return nullptr;
553     }
554     param->option.displayId = DisplayManager::GetInstance().GetDefaultDisplayId();
555     napi_ref ref = nullptr;
556     if (argc == 0) { // 0 valid parameters
557         TLOGI(WmsLogTag::DMS, "argc == 0");
558         param->validInputParam = true;
559     } else if (GetType(env, argv[0]) == napi_function) { // 1 valid parameters napi_function
560         TLOGI(WmsLogTag::DMS, "argc >= 1, argv[0]'s type is napi_function");
561         param->validInputParam = true;
562         NAPI_CALL(env, napi_create_reference(env, argv[0], 1, &ref));
563     } else if (GetType(env, argv[0]) == napi_object) {
564         if ((argc >= 2) && (GetType(env, argv[1]) == napi_function)) { // 2 valid parameters napi_object napi_function
565             TLOGI(WmsLogTag::DMS, "argc >= 2, argv[0]'s type is napi_object, argv[1]'s type is napi_function");
566             param->validInputParam = true;
567             param->useInputOption = true;
568             GetScreenshotParam(env, param, argv[0]);
569             NAPI_CALL(env, napi_create_reference(env, argv[1], 1, &ref));
570         } else { // 1 valid parameters napi_object
571             TLOGI(WmsLogTag::DMS, "argc >= 1, argv[0]'s type is napi_object");
572             param->validInputParam = true;
573             param->useInputOption = true;
574             GetScreenshotParam(env, param, argv[0]);
575         }
576     } else { // 0 valid parameters
577         TLOGI(WmsLogTag::DMS, "argc == 0");
578         param->validInputParam = true;
579     }
580     param->isPick = false;
581     return AsyncProcess<Param>(env, __PRETTY_FUNCTION__, AsyncGetScreenshot, Resolve, ref, param);
582 }
583 
SaveHDRFunc(napi_env env,napi_callback_info info)584 napi_value SaveHDRFunc(napi_env env, napi_callback_info info)
585 {
586     TLOGI(WmsLogTag::DMS, "%{public}s called", __PRETTY_FUNCTION__);
587     napi_value argv[1] = {nullptr}; // the max number of input parameters is 1
588     size_t argc = 1; // the max number of input parameters is 1
589     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
590 
591     auto param = std::make_unique<Param>();
592     auto hdrParam = std::make_unique<HdrParam>();
593     if ((param == nullptr) || (hdrParam == nullptr)) {
594         TLOGE(WmsLogTag::DMS, "Create param failed.");
595         return nullptr;
596     }
597     param->option.displayId = DisplayManager::GetInstance().GetDefaultDisplayId();
598     napi_ref ref = nullptr;
599     if (argc == 0) { // 0 valid parameters
600         TLOGI(WmsLogTag::DMS, "argc == 0");
601         param->validInputParam = true;
602     } else if (GetType(env, argv[0]) == napi_object) {
603         TLOGI(WmsLogTag::DMS, "argc = 1, argv[0]'s type is napi_object");
604         param->validInputParam = true;
605         param->useInputOption = true;
606         GetScreenshotParam(env, param, argv[0]);
607     } else { // parameters > 1
608         TLOGI(WmsLogTag::DMS, "argc == 0");
609         param->validInputParam = true;
610     }
611     hdrParam->wret = param->wret;
612     hdrParam->option = param->option;
613     hdrParam->errMessage = param->errMessage;
614     hdrParam->validInputParam = param->validInputParam;
615     hdrParam->useInputOption = param->useInputOption;
616     return AsyncProcess<HdrParam>(env, __PRETTY_FUNCTION__, AsyncGetScreenHDRshot, HDRResolve, ref, hdrParam);
617 }
618 } // namespace save
619 
SetNamedProperty(napi_env env,napi_value dstObj,const int32_t objValue,const char * propName)620 void SetNamedProperty(napi_env env, napi_value dstObj, const int32_t objValue, const char *propName)
621 {
622     napi_value prop = nullptr;
623     napi_create_int32(env, objValue, &prop);
624     napi_set_named_property(env, dstObj, propName, prop);
625 }
626 
ScreenshotModuleInit(napi_env env,napi_value exports)627 napi_value ScreenshotModuleInit(napi_env env, napi_value exports)
628 {
629     TLOGI(WmsLogTag::DMS, "%{public}s called", __PRETTY_FUNCTION__);
630 
631     napi_value errorCode = nullptr;
632     napi_value dmErrorCode = nullptr;
633     napi_create_object(env, &errorCode);
634     napi_create_object(env, &dmErrorCode);
635 
636     SetNamedProperty(env, errorCode,
637         (int32_t)DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED, "DM_ERROR_INIT_DMS_PROXY_LOCKED");
638     SetNamedProperty(env, errorCode,
639         (int32_t)DMError::DM_ERROR_IPC_FAILED, "DM_ERROR_IPC_FAILED");
640     SetNamedProperty(env, errorCode,
641         (int32_t)DMError::DM_ERROR_REMOTE_CREATE_FAILED, "DM_ERROR_REMOTE_CREATE_FAILED");
642     SetNamedProperty(env, errorCode,
643         (int32_t)DMError::DM_ERROR_NULLPTR, "DM_ERROR_NULLPTR");
644     SetNamedProperty(env, errorCode,
645         (int32_t)DMError::DM_ERROR_INVALID_PARAM, "DM_ERROR_INVALID_PARAM");
646     SetNamedProperty(env, errorCode,
647         (int32_t)DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED, "DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED");
648     SetNamedProperty(env, errorCode,
649         (int32_t)DMError::DM_ERROR_DEATH_RECIPIENT, "DM_ERROR_DEATH_RECIPIENT");
650     SetNamedProperty(env, errorCode,
651         (int32_t)DMError::DM_ERROR_INVALID_MODE_ID, "DM_ERROR_INVALID_MODE_ID");
652     SetNamedProperty(env, errorCode,
653         (int32_t)DMError::DM_ERROR_WRITE_DATA_FAILED, "DM_ERROR_WRITE_DATA_FAILED");
654     SetNamedProperty(env, errorCode,
655         (int32_t)DMError::DM_ERROR_RENDER_SERVICE_FAILED, "DM_ERROR_RENDER_SERVICE_FAILED");
656     SetNamedProperty(env, errorCode,
657         (int32_t)DMError::DM_ERROR_UNREGISTER_AGENT_FAILED, "DM_ERROR_UNREGISTER_AGENT_FAILED");
658     SetNamedProperty(env, errorCode,
659         (int32_t)DMError::DM_ERROR_INVALID_CALLING, "DM_ERROR_INVALID_CALLING");
660     SetNamedProperty(env, errorCode,
661         (int32_t)DMError::DM_ERROR_UNKNOWN, "DM_ERROR_UNKNOWN");
662 
663     SetNamedProperty(env, dmErrorCode,
664         (int32_t)DmErrorCode::DM_ERROR_NO_PERMISSION, "DM_ERROR_NO_PERMISSION");
665     SetNamedProperty(env, dmErrorCode,
666         (int32_t)DmErrorCode::DM_ERROR_INVALID_PARAM, "DM_ERROR_INVALID_PARAM");
667     SetNamedProperty(env, dmErrorCode,
668         (int32_t)DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT, "DM_ERROR_DEVICE_NOT_SUPPORT");
669     SetNamedProperty(env, dmErrorCode,
670         (int32_t)DmErrorCode::DM_ERROR_INVALID_SCREEN, "DM_ERROR_INVALID_SCREEN");
671     SetNamedProperty(env, dmErrorCode,
672         (int32_t)DmErrorCode::DM_ERROR_INVALID_CALLING, "DM_ERROR_INVALID_CALLING");
673     SetNamedProperty(env, dmErrorCode,
674         (int32_t)DmErrorCode::DM_ERROR_SYSTEM_INNORMAL, "DM_ERROR_SYSTEM_INNORMAL");
675 
676     napi_property_descriptor properties[] = {
677         DECLARE_NAPI_FUNCTION("save", save::MainFunc),
678         DECLARE_NAPI_FUNCTION("saveHdrPicture", save::SaveHDRFunc),
679         DECLARE_NAPI_FUNCTION("pick", save::PickFunc),
680         DECLARE_NAPI_FUNCTION("capture", save::CaptureFunc),
681         DECLARE_NAPI_PROPERTY("DMError", errorCode),
682         DECLARE_NAPI_PROPERTY("DmErrorCode", dmErrorCode),
683     };
684 
685     NAPI_CALL(env, napi_define_properties(env,
686         exports, sizeof(properties) / sizeof(properties[0]), properties));
687     return exports;
688 }
689 } // namespace OHOS::Rosen
690 
691 static napi_module g_screenshotModule = {
692     .nm_version = 1, // NAPI v1
693     .nm_flags = 0, // normal
694     .nm_filename = nullptr,
695     .nm_register_func = OHOS::Rosen::ScreenshotModuleInit,
696     .nm_modname = "screenshot",
697     .nm_priv = nullptr,
698 };
699 
RegisterModule(void)700 extern "C" __attribute__((constructor)) void RegisterModule(void)
701 {
702     napi_module_register(&g_screenshotModule);
703 }
704