• 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 "screen_cutout_controller.h"
17 
18 #include "screen_scene_config.h"
19 #include "screen_session_manager.h"
20 #include "window_manager_hilog.h"
21 
22 namespace OHOS::Rosen {
23 namespace {
24 constexpr std::vector<int>::size_type LEFT = 0;
25 constexpr std::vector<int>::size_type TOP = 1;
26 constexpr std::vector<int>::size_type RIGHT = 2;
27 constexpr std::vector<int>::size_type BOTTOM = 3;
28 constexpr uint8_t HALF_SCREEN = 2;
29 }
30 
GetScreenCutoutInfo(DisplayId displayId) const31 sptr<CutoutInfo> ScreenCutoutController::GetScreenCutoutInfo(DisplayId displayId) const
32 {
33     sptr<DisplayInfo> displayInfo = ScreenSessionManager::GetInstance().GetDisplayInfoById(displayId);
34     if (!displayInfo) {
35         TLOGE(WmsLogTag::DMS, "displayInfo invalid");
36         return nullptr;
37     }
38     uint32_t width = static_cast<uint32_t>(displayInfo->GetWidth());
39     uint32_t height = static_cast<uint32_t>(displayInfo->GetHeight());
40     Rotation rotation = displayInfo->GetOriginRotation();
41 
42     return GetScreenCutoutInfo(displayId, width, height, rotation);
43 }
44 
GetScreenCutoutInfo(DisplayId displayId,uint32_t width,uint32_t height,Rotation rotation) const45 sptr<CutoutInfo> ScreenCutoutController::GetScreenCutoutInfo(DisplayId displayId, uint32_t width,
46                                                              uint32_t height, Rotation rotation) const
47 {
48     std::vector<DMRect> boundaryRects;
49     GetCutoutArea(displayId, width, height, rotation, boundaryRects);
50 
51     WaterfallDisplayAreaRects waterfallArea = {};
52     GetWaterfallArea(width, height, rotation, waterfallArea);
53 
54     return sptr<CutoutInfo>::MakeSptr(boundaryRects, waterfallArea);
55 }
56 
GetCutoutArea(DisplayId displayId,uint32_t width,uint32_t height,Rotation rotation,std::vector<DMRect> & cutoutArea) const57 void ScreenCutoutController::GetCutoutArea(DisplayId displayId, uint32_t width, uint32_t height,
58                                            Rotation rotation, std::vector<DMRect>& cutoutArea) const
59 {
60     FoldDisplayMode displayMode = ScreenSceneConfig::GetFoldDisplayMode(width, height);
61 
62     TLOGI(WmsLogTag::DMS, "display:[ID: %{public}" PRIu64 ", W: %{public}u, H: %{public}u, R: %{public}u,"
63         "Mode %{public}u]", displayId, width, height, rotation, displayMode);
64 
65     std::vector<DMRect> boundaryRects;
66     if (ScreenSessionManager::GetInstance().IsFoldable() &&
67         (displayMode == FoldDisplayMode::MAIN || displayMode == FoldDisplayMode::GLOBAL_FULL)) {
68         boundaryRects = ScreenSceneConfig::GetSubCutoutBoundaryRect();
69     } else {
70         boundaryRects = ScreenSceneConfig::GetCutoutBoundaryRect(displayId);
71     }
72 
73     if (!boundaryRects.empty()) {
74         CalcCutoutRects(boundaryRects, width, height, rotation, cutoutArea);
75     }
76 }
77 
CalcCutoutRects(const std::vector<DMRect> & boundaryRects,uint32_t width,uint32_t height,Rotation rotation,std::vector<DMRect> & cutoutRects) const78 void ScreenCutoutController::CalcCutoutRects(const std::vector<DMRect>& boundaryRects, uint32_t width,
79     uint32_t height, Rotation rotation, std::vector<DMRect>& cutoutRects) const
80 {
81     for (const DMRect& rect : boundaryRects) {
82         switch (rotation) {
83             case Rotation::ROTATION_0: {
84                 cutoutRects.emplace_back(rect);
85                 break;
86             }
87             case Rotation::ROTATION_90: {
88                 cutoutRects.emplace_back(
89                     DMRect{ width - rect.posY_ - rect.height_, rect.posX_, rect.height_, rect.width_ });
90                 break;
91             }
92             case Rotation::ROTATION_180: {
93                 cutoutRects.emplace_back(DMRect{
94                     width - rect.posX_ - rect.width_, height - rect.posY_ - rect.height_, rect.width_, rect.height_ });
95                 break;
96             }
97             case Rotation::ROTATION_270: {
98                 cutoutRects.emplace_back(
99                     DMRect{ rect.posY_, height - rect.posX_ - rect.width_, rect.height_, rect.width_ });
100                 break;
101             }
102             default:
103                 break;
104         }
105     }
106 }
107 
GetWaterfallArea(uint32_t width,uint32_t height,Rotation rotation,WaterfallDisplayAreaRects & waterfallArea) const108 void ScreenCutoutController::GetWaterfallArea(uint32_t width, uint32_t height, Rotation rotation,
109                                               WaterfallDisplayAreaRects& waterfallArea) const
110 {
111     TLOGI(WmsLogTag::DMS, "display:[W: %{public}u, H: %{public}u, R: %{public}u]", width, height, rotation);
112 
113     std::vector<int> numberVec = ScreenSceneConfig::GetCurvedScreenBoundaryConfig();
114     if (ScreenSceneConfig::IsWaterfallDisplay() && !numberVec.empty()) {
115         CalcWaterfallRects(numberVec, width, height, rotation, waterfallArea);
116     }
117 }
118 
CalcWaterfallRects(const std::vector<int> & numberVec,uint32_t displayWidth,uint32_t displayHeight,Rotation rotation,WaterfallDisplayAreaRects & waterfallArea) const119 void ScreenCutoutController::CalcWaterfallRects(const std::vector<int> &numberVec, uint32_t displayWidth,
120     uint32_t displayHeight, Rotation rotation, WaterfallDisplayAreaRects& waterfallArea) const
121 {
122     std::vector<uint32_t> realNumVec = { 0, 0, 0, 0 };
123     for (auto i = LEFT; i <= BOTTOM; i++) {
124         if (numberVec.size() > i) {
125             realNumVec[i] = static_cast<uint32_t>(numberVec[i]);
126         }
127     }
128     if (std::all_of(realNumVec.begin(), realNumVec.end(), [](uint32_t result) { return result == 0; })) {
129         return;
130     }
131 
132     if ((realNumVec[LEFT] > displayWidth / HALF_SCREEN) || (realNumVec[RIGHT] > displayWidth / HALF_SCREEN) ||
133         (realNumVec[TOP] > displayHeight / HALF_SCREEN) || (realNumVec[BOTTOM] > displayHeight / HALF_SCREEN)) {
134         TLOGE(WmsLogTag::DMS, "curved screen boundary data is not correct");
135         return;
136     }
137 
138     switch (rotation) {
139         case Rotation::ROTATION_0: {
140             InitRect(0, 0, realNumVec[LEFT], displayHeight, waterfallArea.left);
141             InitRect(0, 0, displayWidth, realNumVec[TOP], waterfallArea.top);
142             InitRect(displayWidth - realNumVec[RIGHT], 0, realNumVec[RIGHT], displayHeight, waterfallArea.right);
143             InitRect(0, displayHeight - realNumVec[BOTTOM], displayWidth, realNumVec[BOTTOM], waterfallArea.bottom);
144             return;
145         }
146         case Rotation::ROTATION_90: {
147             InitRect(0, 0, realNumVec[BOTTOM], displayHeight, waterfallArea.left);
148             InitRect(0, 0, displayWidth, realNumVec[LEFT], waterfallArea.top);
149             InitRect(displayWidth - realNumVec[TOP], 0, realNumVec[TOP], displayHeight, waterfallArea.right);
150             InitRect(0, displayHeight - realNumVec[RIGHT], displayWidth, realNumVec[RIGHT], waterfallArea.bottom);
151             return;
152         }
153         case Rotation::ROTATION_180: {
154             InitRect(0, 0, realNumVec[RIGHT], displayHeight, waterfallArea.left);
155             InitRect(0, 0, displayWidth, realNumVec[BOTTOM], waterfallArea.top);
156             InitRect(displayWidth - realNumVec[LEFT], 0, realNumVec[LEFT], displayHeight, waterfallArea.right);
157             InitRect(0, displayHeight - realNumVec[TOP], displayWidth, realNumVec[TOP], waterfallArea.bottom);
158             return;
159         }
160         case Rotation::ROTATION_270: {
161             InitRect(0, 0, realNumVec[TOP], displayHeight, waterfallArea.left);
162             InitRect(0, 0, displayWidth, realNumVec[RIGHT], waterfallArea.top);
163             InitRect(displayWidth - realNumVec[BOTTOM], 0, realNumVec[BOTTOM], displayHeight, waterfallArea.right);
164             InitRect(0, displayHeight - realNumVec[LEFT], displayWidth, realNumVec[LEFT], waterfallArea.bottom);
165             return;
166         }
167         default: {
168         }
169     }
170     return;
171 }
172 
InitRect(uint32_t left,uint32_t top,uint32_t width,uint32_t height,DMRect & rect) const173 void ScreenCutoutController::InitRect(uint32_t left, uint32_t top, uint32_t width, uint32_t height, DMRect& rect) const
174 {
175     if (width == 0 || height == 0) {
176         rect = DMRect::NONE();
177         return;
178     }
179     rect.posX_ = static_cast<int32_t>(left);
180     rect.posY_ = static_cast<int32_t>(top);
181     rect.width_ = width;
182     rect.height_ = height;
183 }
184 
185 } // namespace OHOS::Rosen