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 #include "native_screenshot_module.h"
16 
17 #include <cinttypes>
18 #include <cstddef>
19 #include <cstdint>
20 #include <image_type.h>
21 #include <iosfwd>
22 #include <js_native_api.h>
23 #include <js_native_api_types.h>
24 #include <memory>
25 #include <napi/native_api.h>
26 #include <napi/native_common.h>
27 #include <string>
28 #include <type_traits>
29 
30 #include "display_manager.h"
31 #include "pixel_map.h"
32 #include "pixel_map_napi.h"
33 #include "window_manager_hilog.h"
34 #include "dm_common.h"
35 #include "dm_napi_common.h"
36 
37 namespace OHOS::Rosen {
38 namespace save {
39 struct Option {
40     Media::Rect rect;
41     Media::Size size;
42     int rotation = 0;
43     DisplayId displayId = 0;
44     bool isNeedNotify = true;
45 };
46 
47 struct Param {
48     DmErrorCode wret;
49     Option option;
50     std::string errMessage;
51     bool useInputOption;
52     bool validInputParam;
53     std::shared_ptr<Media::PixelMap> image;
54     Media::Rect imageRect;
55     bool isPick;
56 };
57 
GetType(napi_env env,napi_value root)58 static napi_valuetype GetType(napi_env env, napi_value root)
59 {
60     napi_valuetype res = napi_undefined;
61     napi_typeof(env, root, &res);
62     return res;
63 }
64 
GetDisplayId(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)65 static void GetDisplayId(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
66 {
67     GNAPI_LOG("Get Screenshot Option: GetDisplayId");
68     napi_value displayId;
69     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "displayId", &displayId));
70     if (displayId != nullptr && GetType(env, displayId) == napi_number) {
71         int64_t dispId;
72         NAPI_CALL_RETURN_VOID(env, napi_get_value_int64(env, displayId, &dispId));
73         param->option.displayId = static_cast<DisplayId>(dispId);
74         GNAPI_LOG("GetDisplayId success, displayId = %{public}" PRIu64"", param->option.displayId);
75     } else {
76         GNAPI_LOG("GetDisplayId failed, invalid param, use default displayId = 0");
77     }
78 }
79 
GetRotation(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)80 static void GetRotation(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
81 {
82     GNAPI_LOG("Get Screenshot Option: GetRotation");
83     napi_value rotation;
84     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "rotation", &rotation));
85     if (rotation != nullptr && GetType(env, rotation) == napi_number) {
86         NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, rotation, &param->option.rotation));
87         GNAPI_LOG("GetRotation success, rotation = %{public}d", param->option.rotation);
88     } else {
89         GNAPI_LOG("GetRotation failed, invalid param, use default rotation = 0");
90     }
91 }
92 
GetScreenRect(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)93 static void GetScreenRect(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
94 {
95     GNAPI_LOG("Get Screenshot Option: GetScreenRect");
96     napi_value screenRect;
97     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "screenRect", &screenRect));
98     if (screenRect != nullptr && GetType(env, screenRect) == napi_object) {
99         GNAPI_LOG("get ScreenRect success");
100 
101         napi_value left;
102         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, screenRect, "left", &left));
103         if (left != nullptr && GetType(env, left) == napi_number) {
104             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, left, &param->option.rect.left));
105             GNAPI_LOG("get ScreenRect.left success, left = %{public}d", param->option.rect.left);
106         } else {
107             GNAPI_LOG("get ScreenRect.left failed, invalid param, use default left = 0");
108         }
109 
110         napi_value top;
111         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, screenRect, "top", &top));
112         if (top != nullptr && GetType(env, top) == napi_number) {
113             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, top, &param->option.rect.top));
114             GNAPI_LOG("get ScreenRect.top success, top = %{public}d", param->option.rect.top);
115         } else {
116             GNAPI_LOG("get ScreenRect.top failed, invalid param, use default top = 0");
117         }
118 
119         napi_value width;
120         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, screenRect, "width", &width));
121         if (width != nullptr && GetType(env, width) == napi_number) {
122             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, width, &param->option.rect.width));
123             GNAPI_LOG("get ScreenRect.width success, width = %{public}d", param->option.rect.width);
124         } else {
125             GNAPI_LOG("get ScreenRect.width failed, invalid param, use default width = 0");
126         }
127 
128         napi_value height;
129         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, screenRect, "height", &height));
130         if (height != nullptr && GetType(env, height) == napi_number) {
131             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, height, &param->option.rect.height));
132             GNAPI_LOG("get ScreenRect.height success, height = %{public}d", param->option.rect.height);
133         } else {
134             GNAPI_LOG("get ScreenRect.height failed, invalid param, use default height = 0");
135         }
136     } else {
137         GNAPI_LOG("get ScreenRect failed, use default ScreenRect param");
138     }
139 }
140 
GetImageSize(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)141 static void GetImageSize(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
142 {
143     GNAPI_LOG("Get Screenshot Option: ImageSize");
144     napi_value imageSize;
145     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "imageSize", &imageSize));
146     if (imageSize != nullptr && GetType(env, imageSize) == napi_object) {
147         napi_value width;
148         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, imageSize, "width", &width));
149         if (width != nullptr && GetType(env, width) == napi_number) {
150             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, width, &param->option.size.width));
151             GNAPI_LOG("get ImageSize.width success, width = %{public}d", param->option.size.width);
152         } else {
153             GNAPI_LOG("get ImageSize.width failed, invalid param, use default width = 0");
154         }
155 
156         napi_value height;
157         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, imageSize, "height", &height));
158         if (height != nullptr && GetType(env, height) == napi_number) {
159             NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, height, &param->option.size.height));
160             GNAPI_LOG("get ImageSize.height success, height = %{public}d", param->option.size.height);
161         } else {
162             GNAPI_LOG("get ImageSize.height failed, invalid param, use default height = 0");
163         }
164     }
165 }
166 
IsNeedNotify(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)167 static void IsNeedNotify(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
168 {
169     GNAPI_LOG("Get Screenshot Option: IsNeedNotify");
170     napi_value isNeedNotify;
171     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "isNotificationNeeded", &isNeedNotify));
172     if (isNeedNotify != nullptr && GetType(env, isNeedNotify) == napi_boolean) {
173         NAPI_CALL_RETURN_VOID(env, napi_get_value_bool(env, isNeedNotify, &param->option.isNeedNotify));
174         GNAPI_LOG("IsNeedNotify: %{public}d", param->option.isNeedNotify);
175     } else {
176         GNAPI_LOG("IsNeedNotify failed, invalid param, use default true.");
177     }
178 }
179 
GetScreenshotParam(napi_env env,std::unique_ptr<Param> & param,napi_value & argv)180 static void GetScreenshotParam(napi_env env, std::unique_ptr<Param> &param, napi_value &argv)
181 {
182     if (param == nullptr) {
183         GNAPI_LOG("param == nullptr, use default param");
184         return;
185     }
186     GetDisplayId(env, param, argv);
187     GetRotation(env, param, argv);
188     GetScreenRect(env, param, argv);
189     GetImageSize(env, param, argv);
190     IsNeedNotify(env, param, argv);
191 }
192 
AsyncGetScreenshot(napi_env env,std::unique_ptr<Param> & param)193 static void AsyncGetScreenshot(napi_env env, std::unique_ptr<Param> &param)
194 {
195     if (!param->validInputParam) {
196         WLOGFE("Invalid Input Param!");
197         param->image = nullptr;
198         param->wret = DmErrorCode::DM_ERROR_INVALID_PARAM;
199         param->errMessage = "Get Screenshot Failed: Invalid input param";
200         return;
201     }
202     CaptureOption option = { param->option.displayId, param->option.isNeedNotify};
203     if (!param->isPick && !option.isNeedNotify_) {
204         if (param->useInputOption) {
205             param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option,
206                 param->option.rect, param->option.size, param->option.rotation, &param->wret);
207         } else {
208             param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option, &param->wret);
209         }
210     } else {
211         if (param->useInputOption) {
212             GNAPI_LOG("Get Screenshot by input option");
213             SnapShotConfig snapConfig;
214             snapConfig.displayId_ = param->option.displayId;
215             snapConfig.imageRect_ = param->option.rect;
216             snapConfig.imageSize_ = param->option.size;
217             snapConfig.rotation_ = param->option.rotation;
218             param->image = DisplayManager::GetInstance().GetScreenshotwithConfig(snapConfig, &param->wret, true);
219         } else if (param->isPick) {
220             GNAPI_LOG("Get Screenshot by picker");
221             param->image = DisplayManager::GetInstance().GetSnapshotByPicker(param->imageRect, &param->wret);
222         } else {
223             GNAPI_LOG("Get Screenshot by default option");
224             param->image = DisplayManager::GetInstance().GetScreenshot(param->option.displayId, &param->wret, true);
225         }
226     }
227     if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) {
228         GNAPI_LOG("Get Screenshot failed!");
229         param->wret = DmErrorCode::DM_ERROR_INVALID_SCREEN;
230         param->errMessage = "Get Screenshot failed: Screenshot image is nullptr";
231         return;
232     }
233 }
234 
CreateJsNumber(napi_env env,int32_t value)235 napi_value CreateJsNumber(napi_env env, int32_t value)
236 {
237     napi_value valRet = nullptr;
238     napi_create_int32(env, value, &valRet);
239     return valRet;
240 }
241 
CreateJsRectObject(napi_env env,Media::Rect imageRect)242 napi_value CreateJsRectObject(napi_env env, Media::Rect imageRect)
243 {
244     napi_value objValue = nullptr;
245     NAPI_CALL(env, napi_create_object(env, &objValue));
246     napi_set_named_property(env, objValue, "left", CreateJsNumber(env, imageRect.left));
247     napi_set_named_property(env, objValue, "top", CreateJsNumber(env, imageRect.top));
248     napi_set_named_property(env, objValue, "width", CreateJsNumber(env, imageRect.width));
249     napi_set_named_property(env, objValue, "height", CreateJsNumber(env, imageRect.height));
250     return objValue;
251 }
252 
CreateJsPickerObject(napi_env env,std::unique_ptr<Param> & param)253 napi_value CreateJsPickerObject(napi_env env, std::unique_ptr<Param> &param)
254 {
255     napi_value objValue = nullptr;
256     NAPI_CALL(env, napi_create_object(env, &objValue));
257     if (param == nullptr) {
258         napi_value result;
259         WLOGFE("param nullptr.");
260         NAPI_CALL(env, napi_get_undefined(env, &result));
261         return result;
262     }
263     napi_set_named_property(env, objValue, "pixelMap", OHOS::Media::PixelMapNapi::CreatePixelMap(env, param->image));
264     napi_set_named_property(env, objValue, "pickRect", CreateJsRectObject(env, param->imageRect));
265     WLOGFI("pick end");
266     return objValue;
267 }
268 
Resolve(napi_env env,std::unique_ptr<Param> & param)269 napi_value Resolve(napi_env env, std::unique_ptr<Param> &param)
270 {
271     napi_value result;
272     napi_value error;
273     napi_value code;
274     bool isThrowError = true;
275     if (param->wret != DmErrorCode::DM_OK) {
276         napi_create_error(env, nullptr, nullptr, &error);
277         napi_create_int32(env, (int32_t)param->wret, &code);
278     }
279     switch (param->wret) {
280         case DmErrorCode::DM_ERROR_NO_PERMISSION:
281             napi_set_named_property(env, error, "DM_ERROR_NO_PERMISSION", code);
282             break;
283         case DmErrorCode::DM_ERROR_INVALID_PARAM:
284             napi_set_named_property(env, error, "DM_ERROR_INVALID_PARAM", code);
285             break;
286         case DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT:
287             napi_set_named_property(env, error, "DM_ERROR_DEVICE_NOT_SUPPORT", code);
288             break;
289         case DmErrorCode::DM_ERROR_SYSTEM_INNORMAL:
290             napi_set_named_property(env, error, "DM_ERROR_SYSTEM_INNORMAL", code);
291             break;
292         default:
293             isThrowError = false;
294             WLOGFI("screen shot default.");
295             break;
296     }
297     WLOGFI("screen shot ret=%{public}d.", param->wret);
298     if (isThrowError) {
299         napi_throw(env, error);
300         return error;
301     }
302     if (param->wret != DmErrorCode::DM_OK) {
303         NAPI_CALL(env, napi_get_undefined(env, &result));
304         return result;
305     }
306     if (param->isPick) {
307         GNAPI_LOG("Resolve Screenshot by picker");
308         return CreateJsPickerObject(env, param);
309     }
310     GNAPI_LOG("Screenshot image Width %{public}d, Height %{public}d",
311         param->image->GetWidth(), param->image->GetHeight());
312     napi_value jsImage = OHOS::Media::PixelMapNapi::CreatePixelMap(env, param->image);
313     return jsImage;
314 }
315 
PickFunc(napi_env env,napi_callback_info info)316 napi_value PickFunc(napi_env env, napi_callback_info info)
317 {
318     GNAPI_LOG("%{public}s called", __PRETTY_FUNCTION__);
319     napi_value argv[1] = { nullptr };  // the max number of input parameters is 1
320     size_t argc = 1;  // the max number of input parameters is 1
321     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
322 
323     auto param = std::make_unique<Param>();
324     if (param == nullptr) {
325         WLOGFE("Create param failed.");
326         return nullptr;
327     }
328     napi_ref ref = nullptr;
329     if (argc == 0) {  // 0 valid parameters
330         GNAPI_LOG("argc == 0");
331         param->validInputParam = true;
332     } else if (GetType(env, argv[0]) == napi_function) {  // 1 valid parameters napi_function
333         GNAPI_LOG("argc >= 1, argv[0]'s type is napi_function");
334         param->validInputParam = true;
335         NAPI_CALL(env, napi_create_reference(env, argv[0], 1, &ref));
336     } else {  // 0 valid parameters
337         GNAPI_LOG("argc == 0");
338         param->validInputParam = true;
339     }
340     param->isPick = true;
341     return AsyncProcess<Param>(env, __PRETTY_FUNCTION__, AsyncGetScreenshot, Resolve, ref, param);
342 }
343 
AsyncGetScreenCapture(napi_env env,std::unique_ptr<Param> & param)344 static void AsyncGetScreenCapture(napi_env env, std::unique_ptr<Param> &param)
345 {
346     CaptureOption captureOption;
347     captureOption.displayId_ = param->option.displayId;
348     captureOption.isNeedNotify_ = param->option.isNeedNotify;
349     GNAPI_LOG("capture option isNeedNotify=%{public}d", captureOption.isNeedNotify_);
350     param->image = DisplayManager::GetInstance().GetScreenCapture(captureOption, &param->wret);
351     if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) {
352         GNAPI_LOG("screen capture failed!");
353         param->wret = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
354         param->errMessage = "ScreenCapture failed: image is null.";
355         return;
356     }
357 }
358 
CaptureFunc(napi_env env,napi_callback_info info)359 napi_value CaptureFunc(napi_env env, napi_callback_info info)
360 {
361     GNAPI_LOG("%{public}s called", __PRETTY_FUNCTION__);
362     napi_value argv[1] = { nullptr };
363     size_t argc = 1;
364     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
365 
366     auto param = std::make_unique<Param>();
367     if (param == nullptr) {
368         WLOGFE("Create param failed.");
369         return nullptr;
370     }
371     param->option.displayId = DisplayManager::GetInstance().GetDefaultDisplayId();
372     napi_ref ref = nullptr;
373     if (argc > 0 && GetType(env, argv[0]) == napi_object) {
374         GNAPI_LOG("argv[0]'s type is napi_object");
375         GetScreenshotParam(env, param, argv[0]);
376     } else {
377         GNAPI_LOG("use default.");
378     }
379     return AsyncProcess<Param>(env, __PRETTY_FUNCTION__, AsyncGetScreenCapture, Resolve, ref, param);
380 }
381 
MainFunc(napi_env env,napi_callback_info info)382 napi_value MainFunc(napi_env env, napi_callback_info info)
383 {
384     GNAPI_LOG("%{public}s called", __PRETTY_FUNCTION__);
385     napi_value argv[2] = {nullptr}; // the max number of input parameters is 2
386     size_t argc = 2; // the max number of input parameters is 2
387     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
388 
389     auto param = std::make_unique<Param>();
390     if (param == nullptr) {
391         WLOGFE("Create param failed.");
392         return nullptr;
393     }
394     param->option.displayId = DisplayManager::GetInstance().GetDefaultDisplayId();
395     napi_ref ref = nullptr;
396     if (argc == 0) { // 0 valid parameters
397         GNAPI_LOG("argc == 0");
398         param->validInputParam = true;
399     } else if (GetType(env, argv[0]) == napi_function) { // 1 valid parameters napi_function
400         GNAPI_LOG("argc >= 1, argv[0]'s type is napi_function");
401         param->validInputParam = true;
402         NAPI_CALL(env, napi_create_reference(env, argv[0], 1, &ref));
403     } else if (GetType(env, argv[0]) == napi_object) {
404         if ((argc >= 2) && (GetType(env, argv[1]) == napi_function)) { // 2 valid parameters napi_object napi_function
405             GNAPI_LOG("argc >= 2, argv[0]'s type is napi_object, argv[1]'s type is napi_function");
406             param->validInputParam = true;
407             param->useInputOption = true;
408             GetScreenshotParam(env, param, argv[0]);
409             NAPI_CALL(env, napi_create_reference(env, argv[1], 1, &ref));
410         } else { // 1 valid parameters napi_object
411             GNAPI_LOG("argc >= 1, argv[0]'s type is napi_object");
412             param->validInputParam = true;
413             param->useInputOption = true;
414             GetScreenshotParam(env, param, argv[0]);
415         }
416     } else { // 0 valid parameters
417         GNAPI_LOG("argc == 0");
418         param->validInputParam = true;
419     }
420     param->isPick = false;
421     return AsyncProcess<Param>(env, __PRETTY_FUNCTION__, AsyncGetScreenshot, Resolve, ref, param);
422 }
423 } // namespace save
424 
SetNamedProperty(napi_env env,napi_value dstObj,const int32_t objValue,const char * propName)425 void SetNamedProperty(napi_env env, napi_value dstObj, const int32_t objValue, const char *propName)
426 {
427     napi_value prop = nullptr;
428     napi_create_int32(env, objValue, &prop);
429     napi_set_named_property(env, dstObj, propName, prop);
430 }
431 
SetDmErrorObjectProperty(napi_env env,napi_value errorCode)432 void SetDmErrorObjectProperty(napi_env env, napi_value errorCode)
433 {
434     SetNamedProperty(env, errorCode,
435         (int32_t)DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED, "DM_ERROR_INIT_DMS_PROXY_LOCKED");
436     SetNamedProperty(env, errorCode,
437         (int32_t)DMError::DM_ERROR_IPC_FAILED, "DM_ERROR_IPC_FAILED");
438     SetNamedProperty(env, errorCode,
439         (int32_t)DMError::DM_ERROR_REMOTE_CREATE_FAILED, "DM_ERROR_REMOTE_CREATE_FAILED");
440     SetNamedProperty(env, errorCode,
441         (int32_t)DMError::DM_ERROR_NULLPTR, "DM_ERROR_NULLPTR");
442     SetNamedProperty(env, errorCode,
443         (int32_t)DMError::DM_ERROR_INVALID_PARAM, "DM_ERROR_INVALID_PARAM");
444     SetNamedProperty(env, errorCode,
445         (int32_t)DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED, "DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED");
446     SetNamedProperty(env, errorCode,
447         (int32_t)DMError::DM_ERROR_DEATH_RECIPIENT, "DM_ERROR_DEATH_RECIPIENT");
448     SetNamedProperty(env, errorCode,
449         (int32_t)DMError::DM_ERROR_INVALID_MODE_ID, "DM_ERROR_INVALID_MODE_ID");
450     SetNamedProperty(env, errorCode,
451         (int32_t)DMError::DM_ERROR_WRITE_DATA_FAILED, "DM_ERROR_WRITE_DATA_FAILED");
452     SetNamedProperty(env, errorCode,
453         (int32_t)DMError::DM_ERROR_RENDER_SERVICE_FAILED, "DM_ERROR_RENDER_SERVICE_FAILED");
454     SetNamedProperty(env, errorCode,
455         (int32_t)DMError::DM_ERROR_UNREGISTER_AGENT_FAILED, "DM_ERROR_UNREGISTER_AGENT_FAILED");
456     SetNamedProperty(env, errorCode,
457         (int32_t)DMError::DM_ERROR_INVALID_CALLING, "DM_ERROR_INVALID_CALLING");
458     SetNamedProperty(env, errorCode,
459         (int32_t)DMError::DM_ERROR_UNKNOWN, "DM_ERROR_UNKNOWN");
460 }
461 
SetDmErrorCodeObjectProperty(napi_env env,napi_value dmErrorCode)462 void SetDmErrorCodeObjectProperty(napi_env env, napi_value dmErrorCode)
463 {
464     SetNamedProperty(env, dmErrorCode,
465         (int32_t)DmErrorCode::DM_ERROR_NO_PERMISSION, "DM_ERROR_NO_PERMISSION");
466     SetNamedProperty(env, dmErrorCode,
467         (int32_t)DmErrorCode::DM_ERROR_INVALID_PARAM, "DM_ERROR_INVALID_PARAM");
468     SetNamedProperty(env, dmErrorCode,
469         (int32_t)DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT, "DM_ERROR_DEVICE_NOT_SUPPORT");
470     SetNamedProperty(env, dmErrorCode,
471         (int32_t)DmErrorCode::DM_ERROR_INVALID_SCREEN, "DM_ERROR_INVALID_SCREEN");
472     SetNamedProperty(env, dmErrorCode,
473         (int32_t)DmErrorCode::DM_ERROR_INVALID_CALLING, "DM_ERROR_INVALID_CALLING");
474     SetNamedProperty(env, dmErrorCode,
475         (int32_t)DmErrorCode::DM_ERROR_SYSTEM_INNORMAL, "DM_ERROR_SYSTEM_INNORMAL");
476 }
477 
ScreenshotModuleInit(napi_env env,napi_value exports)478 napi_value ScreenshotModuleInit(napi_env env, napi_value exports)
479 {
480     GNAPI_LOG("%{public}s called", __PRETTY_FUNCTION__);
481 
482     napi_value errorCode = nullptr;
483     napi_value dmErrorCode = nullptr;
484     napi_create_object(env, &errorCode);
485     napi_create_object(env, &dmErrorCode);
486     SetDmErrorObjectProperty(env, errorCode);
487     SetDmErrorCodeObjectProperty(env, dmErrorCode);
488     napi_property_descriptor properties[] = {
489         DECLARE_NAPI_FUNCTION("save", save::MainFunc),
490         DECLARE_NAPI_FUNCTION("pick", save::PickFunc),
491         DECLARE_NAPI_FUNCTION("capture", save::CaptureFunc),
492         DECLARE_NAPI_PROPERTY("DMError", errorCode),
493         DECLARE_NAPI_PROPERTY("DmErrorCode", dmErrorCode),
494     };
495 
496     NAPI_CALL(env, napi_define_properties(env,
497         exports, sizeof(properties) / sizeof(properties[0]), properties));
498     return exports;
499 }
500 } // namespace OHOS::Rosen
501 
502 static napi_module g_screenshotModule = {
503     .nm_version = 1, // NAPI v1
504     .nm_flags = 0, // normal
505     .nm_filename = nullptr,
506     .nm_register_func = OHOS::Rosen::ScreenshotModuleInit,
507     .nm_modname = "screenshot",
508     .nm_priv = nullptr,
509 };
510 
RegisterModule(void)511 extern "C" __attribute__((constructor)) void RegisterModule(void)
512 {
513     napi_module_register(&g_screenshotModule);
514 }
515