• 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 
Resolve(std::unique_ptr<Param> & param,RetStruct ret)92 static RetStruct Resolve(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     TLOGI(WmsLogTag::WMS_SCB, "screen shot ret=%{public}d.", param->wret);
117     if (isThrowError) {
118         return ret;
119     }
120     if (param->wret != DmErrorCode::DM_OK) {
121         ret.code = static_cast<int32_t>(param->wret);
122         TLOGE(WmsLogTag::WMS_SCB, "ret is not DmErrorCode DM_OK, errorCode:%{public}d", param->wret);
123         return ret;
124     }
125     if (param->isPick) {
126         TLOGI(WmsLogTag::WMS_SCB, "Resolve Screenshot by picker");
127         std::unique_ptr<CPickInfo> pickInfoPtr(CreatePickerObject(param));
128         ret.data = static_cast<void*>(pickInfoPtr.get());
129         return ret;
130     }
131     TLOGI(WmsLogTag::WMS_SCB, "Screenshot image Width %{public}d, Height %{public}d",
132         param->image->GetWidth(), param->image->GetHeight());
133     auto nativeImage = FFIData::Create<PixelMapImpl>(move(param->image));
134     if (nativeImage == nullptr) {
135         TLOGE(WmsLogTag::WMS_SCB, "create image failed");
136         return ret;
137     }
138     int64_t* pixelId = new int64_t(nativeImage->GetID());
139     ret.data = pixelId;
140     return ret;
141 }
142 
GetScreenshot(std::unique_ptr<Param> & param)143 static void GetScreenshot(std::unique_ptr<Param>& param)
144 {
145     if (!param->validInputParam) {
146         TLOGE(WmsLogTag::WMS_SCB, "Invalid Input Param!");
147         param->image = nullptr;
148         param->wret = DmErrorCode::DM_ERROR_INVALID_PARAM;
149         param->errMessage = "Get Screenshot Failed: Invalid input param";
150         return;
151     }
152     CaptureOption option = { param->option.displayId, param->option.isNeedNotify, param->option.isNeedPointer };
153     if (!param->isPick && (!option.isNeedNotify_ || !option.isNeedPointer_)) {
154         if (param->useInputOption) {
155             param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option,
156                 param->option.rect, param->option.size, param->option.rotation, &param->wret);
157         } else {
158             param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option, &param->wret);
159         }
160     } else {
161         if (param->useInputOption) {
162             TLOGI(WmsLogTag::WMS_SCB, "Get Screenshot by input option");
163             SnapShotConfig snapConfig;
164             snapConfig.displayId_ = param->option.displayId;
165             snapConfig.imageRect_ = param->option.rect;
166             snapConfig.imageSize_ = param->option.size;
167             snapConfig.rotation_ = param->option.rotation;
168             param->image = DisplayManager::GetInstance().GetScreenshotwithConfig(snapConfig, &param->wret, true);
169         } else if (param->isPick) {
170             TLOGI(WmsLogTag::WMS_SCB, "Get Screenshot by picker");
171             param->image = DisplayManager::GetInstance().GetSnapshotByPicker(param->imageRect, &param->wret);
172         } else {
173             TLOGI(WmsLogTag::WMS_SCB, "Get Screenshot by default option");
174             param->image = DisplayManager::GetInstance().GetScreenshot(param->option.displayId, &param->wret, true);
175         }
176     }
177     if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) {
178         TLOGE(WmsLogTag::WMS_SCB, "Get Screenshot failed!");
179         param->wret = DmErrorCode::DM_ERROR_INVALID_SCREEN;
180         param->errMessage = "Get Screenshot failed: Screenshot image is nullptr";
181     }
182 }
183 
GetScreenCapture(std::unique_ptr<Param> & param)184 static void GetScreenCapture(std::unique_ptr<Param>& param)
185 {
186     CaptureOption captureOption;
187     captureOption.displayId_ = param->option.displayId;
188     captureOption.isNeedNotify_ = param->option.isNeedNotify;
189     captureOption.isNeedPointer_ = param->option.isNeedPointer;
190     TLOGI(WmsLogTag::WMS_SCB, "capture option isNeedNotify=%{public}d isNeedPointer=%{public}d",
191         captureOption.isNeedNotify_, captureOption.isNeedPointer_);
192     param->image = DisplayManager::GetInstance().GetScreenCapture(captureOption, &param->wret);
193     if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) {
194         TLOGE(WmsLogTag::WMS_SCB, "screen capture failed!");
195         param->wret = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
196         param->errMessage = "ScreenCapture failed: image is null.";
197     }
198 }
199 
PickFunc()200 RetStruct CJScreenshotModule::PickFunc()
201 {
202     TLOGI(WmsLogTag::WMS_SCB, "%{public}s called", __PRETTY_FUNCTION__);
203 
204     RetStruct ret = { .code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr };
205     auto param = std::make_unique<Param>();
206     if (param == nullptr) {
207         TLOGE(WmsLogTag::WMS_SCB, "Create param failed.");
208         return ret;
209     }
210     param->validInputParam = true;
211     param->isPick = true;
212     GetScreenshot(param);
213     Resolve(param, ret);
214     return ret;
215 }
216 
CaptureFunc(uint32_t displayId)217 RetStruct CJScreenshotModule::CaptureFunc(uint32_t displayId)
218 {
219     TLOGI(WmsLogTag::WMS_SCB, "%{public}s called", __PRETTY_FUNCTION__);
220 
221     RetStruct ret = { .code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr };
222     auto param = std::make_unique<Param>();
223     if (param == nullptr) {
224         TLOGE(WmsLogTag::WMS_SCB, "Create param failed.");
225         return ret;
226     }
227     param->option.displayId = displayId;
228     GetScreenCapture(param);
229     Resolve(param, ret);
230     return ret;
231 }
232 } // namespace Rosen
233 } // namespace OHOS
234