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