• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "cj_screenshot_module.h"
17 
18 #include <cinttypes>
19 #include <cstddef>
20 #include <cstdint>
21 #include <image_type.h>
22 #include <iosfwd>
23 #include <memory>
24 #include <string>
25 #include <type_traits>
26 #include <thread>
27 #include <queue>
28 #include <mutex>
29 #include <condition_variable>
30 #include <functional>
31 
32 #include "display_manager.h"
33 #include "pixel_map.h"
34 #include "pixel_map_impl.h"
35 #include "window_manager_hilog.h"
36 #include "dm_common.h"
37 
38 using namespace OHOS::FFI;
39 using namespace OHOS::Media;
40 
41 namespace OHOS {
42 namespace Rosen {
43 struct Option {
44     Media::Rect rect;
45     Media::Size size;
46     int rotation = 0;
47     DisplayId displayId = 0;
48     bool isNeedNotify = true;
49     bool isNeedPointer = true;
50 };
51 
52 struct Param {
53     DmErrorCode wret;
54     Option option;
55     std::string errMessage;
56     bool useInputOption;
57     bool validInputParam;
58     std::shared_ptr<Media::PixelMap> image;
59     Media::Rect imageRect;
60     bool isPick;
61 };
62 
CreateRectObject(const Media::Rect & imageRect)63 static CRect CreateRectObject(const Media::Rect& imageRect)
64 {
65     CRect rect;
66     rect.left = imageRect.left;
67     rect.top = imageRect.top;
68     rect.width = imageRect.width;
69     rect.height = imageRect.height;
70     return rect;
71 }
72 
CreatePickerObject(const std::unique_ptr<Param> & param)73 static std::unique_ptr<CPickInfo> CreatePickerObject(const std::unique_ptr<Param>& param)
74 {
75     if (param == nullptr) {
76         TLOGE(WmsLogTag::WMS_SCB, "param nullptr.");
77         return nullptr;
78     }
79     auto pickInfo = std::make_unique<CPickInfo>();
80     pickInfo->pickRect = CreateRectObject(param->imageRect);
81 
82     auto nativeImage = FFIData::Create<PixelMapImpl>(move(param->image));
83     if (nativeImage == nullptr) {
84         TLOGE(WmsLogTag::WMS_SCB, "create image failed");
85         return pickInfo;
86     }
87     TLOGI(WmsLogTag::WMS_SCB, "pick end");
88     pickInfo->pixelMap = nativeImage->GetID();
89     return pickInfo;
90 }
91 
CheckWretParam(std::unique_ptr<Param> & param,RetStruct ret)92 static bool CheckWretParam(std::unique_ptr<Param>& param, RetStruct ret)
93 {
94     bool isThrowError = true;
95     switch (param->wret) {
96         case DmErrorCode::DM_ERROR_NO_PERMISSION:
97             TLOGE(WmsLogTag::WMS_SCB, "[CJScreenshotModule] Get default DmErrorCode is DM_ERROR_NO_PERMISSION");
98             ret.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_NO_PERMISSION);
99             break;
100         case DmErrorCode::DM_ERROR_INVALID_PARAM:
101             TLOGE(WmsLogTag::WMS_SCB, "[CJScreenshotModule] Get default DmErrorCode is DM_ERROR_INVALID_PARAM");
102             ret.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM);
103             break;
104         case DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT:
105             TLOGE(WmsLogTag::WMS_SCB, "[CJScreenshotModule] Get default DmErrorCode is DM_ERROR_DEVICE_NOT_SUPPORT");
106             ret.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT);
107             break;
108         case DmErrorCode::DM_ERROR_SYSTEM_INNORMAL:
109             ret.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL);
110             break;
111         default:
112             isThrowError = false;
113             ret.code = static_cast<int32_t>(DmErrorCode::DM_OK);
114             break;
115     }
116     return isThrowError;
117 }
118 
Resolve(std::unique_ptr<Param> & param,RetStruct ret)119 static RetStruct Resolve(std::unique_ptr<Param>& param, RetStruct ret)
120 {
121     TLOGI(WmsLogTag::WMS_SCB, "screen shot ret=%{public}d.", param->wret);
122     bool isThrowError = CheckWretParam(param, ret);
123     if (isThrowError) {
124         return ret;
125     }
126     if (param->wret != DmErrorCode::DM_OK) {
127         ret.code = static_cast<int32_t>(param->wret);
128         TLOGE(WmsLogTag::WMS_SCB, "ret is not DmErrorCode DM_OK, errorCode:%{public}d", param->wret);
129         return ret;
130     }
131     if (param->isPick) {
132         TLOGI(WmsLogTag::WMS_SCB, "Resolve Screenshot by picker");
133         auto pickInfo = CreatePickerObject(param);
134         if (pickInfo == nullptr) {
135             ret.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM);
136             return ret;
137         }
138         ret.data = pickInfo.release();
139         return ret;
140     }
141     TLOGI(WmsLogTag::WMS_SCB, "Screenshot image Width %{public}d, Height %{public}d",
142         param->image->GetWidth(), param->image->GetHeight());
143     auto nativeImage = FFIData::Create<PixelMapImpl>(move(param->image));
144     if (nativeImage == nullptr) {
145         TLOGE(WmsLogTag::WMS_SCB, "create image failed");
146         return ret;
147     }
148     int64_t* pixelId = new int64_t(nativeImage->GetID());
149     ret.data = pixelId;
150     return ret;
151 }
152 
GetScreenshot(std::unique_ptr<Param> & param)153 static void GetScreenshot(std::unique_ptr<Param>& param)
154 {
155     if (!param->validInputParam) {
156         TLOGE(WmsLogTag::WMS_SCB, "Invalid Input Param!");
157         param->image = nullptr;
158         param->wret = DmErrorCode::DM_ERROR_INVALID_PARAM;
159         param->errMessage = "Get Screenshot Failed: Invalid input param";
160         return;
161     }
162     CaptureOption option = { param->option.displayId, param->option.isNeedNotify, param->option.isNeedPointer };
163     if (!param->isPick && (!option.isNeedNotify_ || !option.isNeedPointer_)) {
164         if (param->useInputOption) {
165             param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option,
166                 param->option.rect, param->option.size, param->option.rotation, &param->wret);
167         } else {
168             param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option, &param->wret);
169         }
170     } else {
171         if (param->useInputOption) {
172             TLOGI(WmsLogTag::WMS_SCB, "Get Screenshot by input option");
173             SnapShotConfig snapConfig;
174             snapConfig.displayId_ = param->option.displayId;
175             snapConfig.imageRect_ = param->option.rect;
176             snapConfig.imageSize_ = param->option.size;
177             snapConfig.rotation_ = param->option.rotation;
178             param->image = DisplayManager::GetInstance().GetScreenshotwithConfig(snapConfig, &param->wret, true);
179         } else if (param->isPick) {
180             TLOGI(WmsLogTag::WMS_SCB, "Get Screenshot by picker");
181             param->image = DisplayManager::GetInstance().GetSnapshotByPicker(param->imageRect, &param->wret);
182         } else {
183             TLOGI(WmsLogTag::WMS_SCB, "Get Screenshot by default option");
184             param->image = DisplayManager::GetInstance().GetScreenshot(param->option.displayId, &param->wret, true);
185         }
186     }
187     if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) {
188         TLOGE(WmsLogTag::WMS_SCB, "Get Screenshot failed!");
189         param->wret = DmErrorCode::DM_ERROR_INVALID_SCREEN;
190         param->errMessage = "Get Screenshot failed: Screenshot image is nullptr";
191     }
192 }
193 
GetScreenCapture(std::unique_ptr<Param> & param)194 static void GetScreenCapture(std::unique_ptr<Param>& param)
195 {
196     CaptureOption captureOption;
197     captureOption.displayId_ = param->option.displayId;
198     captureOption.isNeedNotify_ = param->option.isNeedNotify;
199     captureOption.isNeedPointer_ = param->option.isNeedPointer;
200     TLOGI(WmsLogTag::WMS_SCB, "capture option isNeedNotify=%{public}d isNeedPointer=%{public}d",
201         captureOption.isNeedNotify_, captureOption.isNeedPointer_);
202     param->image = DisplayManager::GetInstance().GetScreenCapture(captureOption, &param->wret);
203     if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) {
204         TLOGE(WmsLogTag::WMS_SCB, "screen capture failed!");
205         param->wret = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
206         param->errMessage = "ScreenCapture failed: image is null.";
207     }
208 }
209 
PickFunc()210 RetStruct CJScreenshotModule::PickFunc()
211 {
212     TLOGI(WmsLogTag::WMS_SCB, "%{public}s called", __PRETTY_FUNCTION__);
213 
214     RetStruct ret = { .code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr };
215     auto param = std::make_unique<Param>();
216     if (param == nullptr) {
217         TLOGE(WmsLogTag::WMS_SCB, "Create param failed.");
218         return ret;
219     }
220     param->validInputParam = true;
221     param->isPick = true;
222     GetScreenshot(param);
223     Resolve(param, ret);
224     return ret;
225 }
226 
CaptureFunc(uint32_t displayId)227 RetStruct CJScreenshotModule::CaptureFunc(uint32_t displayId)
228 {
229     TLOGI(WmsLogTag::WMS_SCB, "%{public}s called", __PRETTY_FUNCTION__);
230 
231     RetStruct ret = { .code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr };
232     auto param = std::make_unique<Param>();
233     if (param == nullptr) {
234         TLOGE(WmsLogTag::WMS_SCB, "Create param failed.");
235         return ret;
236     }
237     param->option.displayId = displayId;
238     GetScreenCapture(param);
239     Resolve(param, ret);
240     return ret;
241 }
242 } // namespace Rosen
243 } // namespace OHOS
244