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> ¶m, 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> ¶m, 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, ¶m->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> ¶m, 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, ¶m->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, ¶m->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, ¶m->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, ¶m->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> ¶m, 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, ¶m->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, ¶m->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> ¶m, 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, ¶m->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> ¶m, 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, ¶m->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> ¶m, 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 ¶m->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> ¶m, 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> ¶m)
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, ¶m->wret);
255 } else {
256 param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option, ¶m->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, ¶m->wret, true);
268 } else if (param->isPick) {
269 TLOGI(WmsLogTag::DMS, "Get Screenshot by picker");
270 param->image = DisplayManager::GetInstance().GetSnapshotByPicker(param->imageRect, ¶m->wret);
271 } else {
272 TLOGI(WmsLogTag::DMS, "Get Screenshot by default option");
273 param->image = DisplayManager::GetInstance().GetScreenshot(param->option.displayId, ¶m->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> ¶m)
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> ¶m)
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> ¶m)
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, ¶m->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