• 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 "session/host/include/layout_controller.h"
17 
18 #include <cinttypes>
19 #include <transaction/rs_transaction.h>
20 #include <ui/rs_surface_node.h>
21 
22 #include "display_manager.h"
23 #include "screen_session_manager_client/include/screen_session_manager_client.h"
24 #include "session/host/include/scene_persistent_storage.h"
25 #include "session/host/include/scene_session.h"
26 #include "session/host/include/session_utils.h"
27 #include "session_helper.h"
28 #include "window_helper.h"
29 #include "window_manager_hilog.h"
30 #include "wm_common_inner.h"
31 
32 namespace OHOS::Rosen {
33 namespace {
34 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "LayoutController"};
35 }
36 
LayoutController(const sptr<WindowSessionProperty> & property)37 LayoutController::LayoutController(const sptr<WindowSessionProperty>& property)
38 {
39     sessionProperty_ = property;
40 }
41 
42 // LCOV_EXCL_START
SetSessionGlobalRect(const WSRect & rect)43 bool LayoutController::SetSessionGlobalRect(const WSRect& rect)
44 {
45     std::lock_guard<std::mutex> lock(globalRectMutex_);
46     if (globalRect_ == rect) {
47         return false;
48     }
49     globalRect_ = rect;
50     return true;
51 }
52 // LCOV_EXCL_STOP
53 
GetSessionGlobalRect() const54 WSRect LayoutController::GetSessionGlobalRect() const
55 {
56     if (Session::IsScbCoreEnabled()) {
57         std::lock_guard<std::mutex> lock(globalRectMutex_);
58         return globalRect_;
59     }
60     return winRect_;
61 }
62 
SetClientRect(const WSRect & rect)63 void LayoutController::SetClientRect(const WSRect& rect)
64 {
65     if (clientRect_ == rect) {
66         TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d skip same rect", GetSessionPersistentId());
67         return;
68     }
69     clientRect_ = rect;
70     TLOGD(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, update client rect:%{public}s",
71         GetSessionPersistentId(), rect.ToString().c_str());
72 }
73 
GetClientRect() const74 WSRect LayoutController::GetClientRect() const
75 {
76     return clientRect_;
77 }
78 
GetGlobalScaledRect(Rect & globalScaledRect)79 void LayoutController::GetGlobalScaledRect(Rect& globalScaledRect)
80 {
81     WSRect scaledRect = GetSessionGlobalRect();
82     scaledRect.width_ *= GetScaleX();
83     scaledRect.height_ *= GetScaleY();
84     globalScaledRect = { scaledRect.posX_, scaledRect.posY_, scaledRect.width_, scaledRect.height_ };
85 }
86 
87 // LCOV_EXCL_START
ConvertRelativeRectToGlobal(const WSRect & relativeRect,DisplayId currentDisplayId) const88 WSRect LayoutController::ConvertRelativeRectToGlobal(const WSRect& relativeRect, DisplayId currentDisplayId) const
89 {
90     sptr<ScreenSession> screenSession =
91         ScreenSessionManagerClient::GetInstance().GetScreenSessionById(currentDisplayId);
92     if (!screenSession) {
93         TLOGW(WmsLogTag::WMS_LAYOUT, "Screen session is null, displayId:%{public}" PRIu64, currentDisplayId);
94         screenSession =
95             ScreenSessionManagerClient::GetInstance().GetScreenSessionById(sessionProperty_->GetDisplayId());
96         if (!screenSession) {
97             TLOGW(WmsLogTag::WMS_LAYOUT, "Screen session is null, displayId:%{public}" PRIu64,
98                 sessionProperty_->GetDisplayId());
99             return relativeRect;
100         }
101     }
102     const ScreenProperty& screenProperty = screenSession->GetScreenProperty();
103     int32_t currentDisplayOffsetX = static_cast<int32_t>(screenProperty.GetStartX());
104     int32_t currentDisplayOffsetY = static_cast<int32_t>(screenProperty.GetStartY());
105     TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, relativeRect:%{public}s, offsetX:%{public}d, offsetY:%{public}d",
106         GetSessionPersistentId(), relativeRect.ToString().c_str(), currentDisplayOffsetX, currentDisplayOffsetY);
107     return {relativeRect.posX_ + currentDisplayOffsetX,
108             relativeRect.posY_ + currentDisplayOffsetY,
109             relativeRect.width_, relativeRect.height_};
110 }
111 
ConvertGlobalRectToRelative(const WSRect & globalRect,DisplayId targetDisplayId) const112 WSRect LayoutController::ConvertGlobalRectToRelative(const WSRect& globalRect, DisplayId targetDisplayId) const
113 {
114     sptr<ScreenSession> screenSession =
115         ScreenSessionManagerClient::GetInstance().GetScreenSessionById(targetDisplayId);
116     if (!screenSession) {
117         TLOGW(WmsLogTag::WMS_LAYOUT, "Screen session is null, displayId:%{public}" PRIu64, targetDisplayId);
118         screenSession =
119             ScreenSessionManagerClient::GetInstance().GetScreenSessionById(sessionProperty_->GetDisplayId());
120         if (!screenSession) {
121             TLOGW(WmsLogTag::WMS_LAYOUT, "Screen session is null, displayId:%{public}" PRIu64,
122                 sessionProperty_->GetDisplayId());
123             return globalRect;
124         }
125     }
126     const ScreenProperty& screenProperty = screenSession->GetScreenProperty();
127     int32_t targetDisplayOffsetX = static_cast<int32_t>(screenProperty.GetStartX());
128     int32_t targetDisplayOffsetY = static_cast<int32_t>(screenProperty.GetStartY());
129     TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, globalRect:%{public}s, offsetX:%{public}d, offsetY:%{public}d",
130         GetSessionPersistentId(), globalRect.ToString().c_str(), targetDisplayOffsetX, targetDisplayOffsetY);
131     return {globalRect.posX_ - targetDisplayOffsetX,
132             globalRect.posY_ - targetDisplayOffsetY,
133             globalRect.width_, globalRect.height_};
134 }
135 
GetSessionPersistentId() const136 int32_t LayoutController::GetSessionPersistentId() const
137 {
138     return sessionProperty_->GetPersistentId();
139 }
140 
AdjustRectByLimits(WindowLimits limits,float ratio,bool isDecor,float vpr,WSRect & rect)141 void LayoutController::AdjustRectByLimits(WindowLimits limits, float ratio, bool isDecor, float vpr, WSRect& rect)
142 {
143     if (isDecor) {
144         rect.width_ = SessionUtils::ToLayoutWidth(rect.width_, vpr);
145         rect.height_ = SessionUtils::ToLayoutHeight(rect.height_, vpr);
146         limits.minWidth_ = SessionUtils::ToLayoutWidth(limits.minWidth_, vpr);
147         limits.maxWidth_ = SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr);
148         limits.minHeight_ = SessionUtils::ToLayoutHeight(limits.minHeight_, vpr);
149         limits.maxHeight_ = SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr);
150     }
151     if (static_cast<uint32_t>(rect.height_) > limits.maxHeight_) {
152         rect.height_ = static_cast<int32_t>(limits.maxHeight_);
153         rect.width_ = floor(rect.height_ * ratio);
154     } else if (static_cast<uint32_t>(rect.width_) > limits.maxWidth_) {
155         rect.width_ = static_cast<int32_t>(limits.maxWidth_);
156         rect.height_ = floor(rect.width_ / ratio);
157     } else if (static_cast<uint32_t>(rect.width_) < limits.minWidth_) {
158         rect.width_ = static_cast<int32_t>(limits.minWidth_);
159         rect.height_ = ceil(rect.width_ / ratio);
160     } else if (static_cast<uint32_t>(rect.height_) < limits.minHeight_) {
161         rect.height_ = static_cast<int32_t>(limits.minHeight_);
162         rect.width_ = ceil(rect.height_ * ratio);
163     }
164     if (isDecor) {
165         rect.height_ = SessionUtils::ToWinHeight(rect.height_, vpr) ;
166         rect.width_ = SessionUtils::ToWinWidth(rect.width_, vpr);
167     }
168 }
169 
AdjustRectByAspectRatio(WSRect & rect,bool isDecorEnable)170 bool LayoutController::AdjustRectByAspectRatio(WSRect& rect, bool isDecorEnable)
171 {
172     const int tolerancePx = 2; // 2: tolerance delta pixel value, unit: px
173     WSRect originalRect = rect;
174     if (sessionProperty_->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING ||
175         !WindowHelper::IsMainWindow(sessionProperty_->GetWindowType())) {
176         return false;
177     }
178 
179     if (MathHelper::NearZero(aspectRatio_)) {
180         return false;
181     }
182     float vpr = 1.5f; // 1.5f: default virtual pixel ratio
183     auto display = DisplayManager::GetInstance().GetDefaultDisplay();
184     if (display) {
185         vpr = display->GetVirtualPixelRatio();
186     }
187     int32_t minW;
188     int32_t maxW;
189     int32_t minH;
190     int32_t maxH;
191     SessionUtils::CalcFloatWindowRectLimits(sessionProperty_->GetWindowLimits(),
192         getSystemConfigFunc_().maxFloatingWindowSize_, vpr, minW, maxW, minH, maxH);
193     rect.width_ = std::max(minW, static_cast<int32_t>(rect.width_));
194     rect.width_ = std::min(maxW, static_cast<int32_t>(rect.width_));
195     rect.height_ = std::max(minH, static_cast<int32_t>(rect.height_));
196     rect.height_ = std::min(maxH, static_cast<int32_t>(rect.height_));
197     if (isDecorEnable) {
198         if (SessionUtils::ToLayoutWidth(rect.width_, vpr) >
199                 SessionUtils::ToLayoutHeight(rect.height_, vpr) * aspectRatio_) {
200             rect.width_ = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(rect.height_, vpr)* aspectRatio_, vpr);
201         } else {
202             rect.height_ = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(rect.width_, vpr) / aspectRatio_, vpr);
203         }
204     } else {
205         if (rect.width_ > rect.height_ * aspectRatio_) {
206             rect.width_ = rect.height_ * aspectRatio_;
207         } else {
208             rect.height_ = rect.width_ / aspectRatio_;
209         }
210     }
211     AdjustRectByLimits(sessionProperty_->GetWindowLimits(), aspectRatio_, isDecorEnable, vpr, rect);
212     if (std::abs(static_cast<int32_t>(originalRect.width_) - static_cast<int32_t>(rect.width_)) <= tolerancePx &&
213         std::abs(static_cast<int32_t>(originalRect.height_) - static_cast<int32_t>(rect.height_)) <= tolerancePx) {
214         rect = originalRect;
215         return false;
216     }
217     return true;
218 }
219 
SetScale(float scaleX,float scaleY,float pivotX,float pivotY)220 void LayoutController::SetScale(float scaleX, float scaleY, float pivotX, float pivotY)
221 {
222     scaleX_ = scaleX;
223     scaleY_ = scaleY;
224     pivotX_ = pivotX;
225     pivotY_ = pivotY;
226 }
227 
SetClientScale(float scaleX,float scaleY,float pivotX,float pivotY)228 void LayoutController::SetClientScale(float scaleX, float scaleY, float pivotX, float pivotY)
229 {
230     TLOGD(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, preScaleX:%{public}f, preScaleY:%{public}f, "
231         "newScaleX:%{public}f, newScaleY:%{public}f", GetSessionPersistentId(),
232         clientScaleX_, clientScaleY_, scaleX, scaleY);
233     clientScaleX_ = scaleX;
234     clientScaleY_ = scaleY;
235     clientPivotX_ = pivotX;
236     clientPivotY_ = pivotY;
237 }
238 
IsTransformNeedUpdate(float scaleX,float scaleY,float pivotX,float pivotY)239 bool LayoutController::IsTransformNeedUpdate(float scaleX, float scaleY, float pivotX, float pivotY)
240 {
241     bool nearEqual = NearEqual(scaleX_, scaleX) && NearEqual(scaleY_, scaleY) &&
242                      NearEqual(pivotX_, pivotX) && NearEqual(pivotY_, pivotY) &&
243                      NearEqual(clientScaleX_, scaleX) && NearEqual(clientScaleY_, scaleY) &&
244                      NearEqual(clientPivotX_, pivotX) && NearEqual(clientPivotY_, pivotY);
245     return !nearEqual;
246 }
247 // LCOV_EXCL_STOP
248 
SetSystemConfigFunc(GetSystemConfigFunc && func)249 void LayoutController::SetSystemConfigFunc(GetSystemConfigFunc&& func)
250 {
251     if (!func) {
252         TLOGW(WmsLogTag::WMS_LAYOUT, "func is null");
253         return;
254     }
255     getSystemConfigFunc_ = std::move(func);
256 }
257 
258 }  // namespace OHOS::Rosen
259