• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 #ifndef OHOS_WM_INCLUDE_WM_HELPER_H
17 #define OHOS_WM_INCLUDE_WM_HELPER_H
18 
19 #include <unistd.h>
20 #include <vector>
21 #include "ability_info.h"
22 #include "window_transition_info.h"
23 #include "wm_common.h"
24 #include "wm_common_inner.h"
25 #include "wm_math.h"
26 
27 namespace OHOS {
28 namespace Rosen {
29 class WindowHelper {
30 public:
IsMainWindow(WindowType type)31     static inline bool IsMainWindow(WindowType type)
32     {
33         return (type >= WindowType::APP_MAIN_WINDOW_BASE && type < WindowType::APP_MAIN_WINDOW_END);
34     }
35 
IsMainWindowAndNotShown(WindowType type,WindowState state)36     static inline bool IsMainWindowAndNotShown(WindowType type, WindowState state)
37     {
38         return (IsMainWindow(type) && state != WindowState::STATE_SHOWN);
39     }
40 
IsModalMainWindow(WindowType type,uint32_t windowFlags)41     static inline bool IsModalMainWindow(WindowType type, uint32_t windowFlags)
42     {
43         return IsMainWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_MODAL));
44     }
45 
IsSubWindow(WindowType type)46     static inline bool IsSubWindow(WindowType type)
47     {
48         return (type >= WindowType::APP_SUB_WINDOW_BASE && type < WindowType::APP_SUB_WINDOW_END);
49     }
50 
IsNormalSubWindow(WindowType type,uint32_t windowFlags)51     static inline bool IsNormalSubWindow(WindowType type, uint32_t windowFlags)
52     {
53         const uint32_t mask = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_MODAL) |
54             static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST) |
55             static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TEXT_MENU);
56         return ((windowFlags & mask) == 0 && IsSubWindow(type));
57     }
58 
IsModalSubWindow(WindowType type,uint32_t windowFlags)59     static inline bool IsModalSubWindow(WindowType type, uint32_t windowFlags)
60     {
61         return IsSubWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_MODAL));
62     }
63 
IsApplicationModalSubWindow(WindowType type,uint32_t windowFlags)64     static inline bool IsApplicationModalSubWindow(WindowType type, uint32_t windowFlags)
65     {
66         return IsModalSubWindow(type, windowFlags) &&
67             (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL));
68     }
69 
IsToastSubWindow(WindowType type,uint32_t windowFlags)70     static inline bool IsToastSubWindow(WindowType type, uint32_t windowFlags)
71     {
72         return IsSubWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST));
73     }
74 
IsModalWindow(uint32_t windowFlags)75     static inline bool IsModalWindow(uint32_t windowFlags)
76     {
77         return (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL)) ||
78             (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_MODAL));
79     }
80 
IsTextMenuSubWindow(WindowType type,uint32_t windowFlags)81     static inline bool IsTextMenuSubWindow(WindowType type, uint32_t windowFlags)
82     {
83         return IsSubWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TEXT_MENU));
84     }
85 
IsDialogWindow(WindowType type)86     static inline bool IsDialogWindow(WindowType type)
87     {
88         return type == WindowType::WINDOW_TYPE_DIALOG;
89     }
90 
IsAppWindow(WindowType type)91     static inline bool IsAppWindow(WindowType type)
92     {
93         return (IsMainWindow(type) || IsSubWindow(type));
94     }
95 
IsAppFloatingWindow(WindowType type)96     static inline bool IsAppFloatingWindow(WindowType type)
97     {
98         return (type == WindowType::WINDOW_TYPE_FLOAT) || (type == WindowType::WINDOW_TYPE_FLOAT_CAMERA);
99     }
100 
IsFloatOrSubWindow(WindowType type)101     static inline bool IsFloatOrSubWindow(WindowType type)
102     {
103         return type == WindowType::WINDOW_TYPE_FLOAT || IsSubWindow(type);
104     }
105 
IsPipWindow(WindowType type)106     static inline bool IsPipWindow(WindowType type)
107     {
108         return (type == WindowType::WINDOW_TYPE_PIP);
109     }
110 
IsFbWindow(WindowType type)111     static inline bool IsFbWindow(WindowType type)
112     {
113         return (type == WindowType::WINDOW_TYPE_FB);
114     }
115 
IsBelowSystemWindow(WindowType type)116     static inline bool IsBelowSystemWindow(WindowType type)
117     {
118         return (type >= WindowType::BELOW_APP_SYSTEM_WINDOW_BASE && type < WindowType::BELOW_APP_SYSTEM_WINDOW_END);
119     }
120 
IsAboveSystemWindow(WindowType type)121     static inline bool IsAboveSystemWindow(WindowType type)
122     {
123         return (type >= WindowType::ABOVE_APP_SYSTEM_WINDOW_BASE && type < WindowType::ABOVE_APP_SYSTEM_WINDOW_END);
124     }
125 
IsSystemSubWindow(WindowType type)126     static inline bool IsSystemSubWindow(WindowType type)
127     {
128         return (type >= WindowType::SYSTEM_SUB_WINDOW_BASE && type < WindowType::SYSTEM_SUB_WINDOW_END);
129     }
130 
IsSystemMainWindow(WindowType type)131     static inline bool IsSystemMainWindow(WindowType type)
132     {
133         return IsBelowSystemWindow(type) || IsAboveSystemWindow(type);
134     }
135 
IsSystemWindow(WindowType type)136     static inline bool IsSystemWindow(WindowType type)
137     {
138         return (IsBelowSystemWindow(type) || IsAboveSystemWindow(type) || IsSystemSubWindow(type));
139     }
140 
IsUIExtensionWindow(WindowType type)141     static inline bool IsUIExtensionWindow(WindowType type)
142     {
143         return (type == WindowType::WINDOW_TYPE_UI_EXTENSION);
144     }
145 
IsAppComponentWindow(WindowType type)146     static inline bool IsAppComponentWindow(WindowType type)
147     {
148         return (type == WindowType::WINDOW_TYPE_APP_COMPONENT);
149     }
150 
IsMainFloatingWindow(WindowType type,WindowMode mode)151     static inline bool IsMainFloatingWindow(WindowType type, WindowMode mode)
152     {
153         return ((IsMainWindow(type)) && (mode == WindowMode::WINDOW_MODE_FLOATING));
154     }
155 
IsMainFullScreenWindow(WindowType type,WindowMode mode)156     static inline bool IsMainFullScreenWindow(WindowType type, WindowMode mode)
157     {
158         return ((IsMainWindow(type)) && (mode == WindowMode::WINDOW_MODE_FULLSCREEN));
159     }
160 
IsFloatingWindow(WindowMode mode)161     static inline bool IsFloatingWindow(WindowMode mode)
162     {
163         return mode == WindowMode::WINDOW_MODE_FLOATING;
164     }
165 
IsSystemBarWindow(WindowType type)166     static inline bool IsSystemBarWindow(WindowType type)
167     {
168         return (type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_NAVIGATION_BAR);
169     }
170 
IsOverlayWindow(WindowType type)171     static inline bool IsOverlayWindow(WindowType type)
172     {
173         return (type == WindowType::WINDOW_TYPE_STATUS_BAR ||
174             type == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
175             type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
176     }
177 
IsRotatableWindow(WindowType type,WindowMode mode)178     static inline bool IsRotatableWindow(WindowType type, WindowMode mode)
179     {
180         return WindowHelper::IsMainFullScreenWindow(type, mode) || type == WindowType::WINDOW_TYPE_KEYGUARD ||
181             type == WindowType::WINDOW_TYPE_DESKTOP ||
182             ((type == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) && (mode == WindowMode::WINDOW_MODE_FULLSCREEN));
183     }
184 
IsInputWindow(WindowType type)185     static inline bool IsInputWindow(WindowType type)
186     {
187         return (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
188                 type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR);
189     }
190 
IsKeyboardWindow(WindowType type)191     static inline bool IsKeyboardWindow(WindowType type)
192     {
193         return type == WindowType::WINDOW_TYPE_KEYBOARD_PANEL || type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT;
194     }
195 
IsSystemOrSubWindow(WindowType type)196     static inline bool IsSystemOrSubWindow(WindowType type)
197     {
198         return IsSubWindow(type) || IsSystemWindow(type);
199     }
200 
IsNeedWaitAttachStateWindow(WindowType type)201     static inline bool IsNeedWaitAttachStateWindow(WindowType type)
202     {
203         return !IsKeyboardWindow(type) && IsSystemOrSubWindow(type);
204     }
205 
IsDynamicWindow(WindowType type)206     static inline bool IsDynamicWindow(WindowType type)
207     {
208         return type == WindowType::WINDOW_TYPE_DYNAMIC;
209     }
210 
IsFullScreenWindow(WindowMode mode)211     static inline bool IsFullScreenWindow(WindowMode mode)
212     {
213         return mode == WindowMode::WINDOW_MODE_FULLSCREEN;
214     }
215 
IsSplitWindowMode(WindowMode mode)216     static inline bool IsSplitWindowMode(WindowMode mode)
217     {
218         return mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY;
219     }
220 
IsPipWindowMode(WindowMode mode)221     static inline bool IsPipWindowMode(WindowMode mode)
222     {
223         return mode == WindowMode::WINDOW_MODE_PIP;
224     }
225 
IsAppFullOrSplitWindow(WindowType type,WindowMode mode)226     static inline bool IsAppFullOrSplitWindow(WindowType type, WindowMode mode)
227     {
228         if (!IsAppWindow(type)) {
229             return false;
230         }
231         return IsFullScreenWindow(mode) || IsSplitWindowMode(mode);
232     }
233 
IsValidWindowMode(WindowMode mode)234     static inline bool IsValidWindowMode(WindowMode mode)
235     {
236         return mode == WindowMode::WINDOW_MODE_FULLSCREEN || mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
237             mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY || mode == WindowMode::WINDOW_MODE_FLOATING ||
238             mode == WindowMode::WINDOW_MODE_PIP || mode == WindowMode::WINDOW_MODE_FB;
239     }
240 
IsEmptyRect(const Rect & r)241     static inline bool IsEmptyRect(const Rect& r)
242     {
243         return (r.posX_ == 0 && r.posY_ == 0 && r.width_ == 0 && r.height_ == 0);
244     }
245 
IsLandscapeRect(const Rect & r)246     static inline bool IsLandscapeRect(const Rect& r)
247     {
248         return r.width_ > r.height_;
249     }
250 
IsShowWhenLocked(uint32_t flags)251     static inline bool IsShowWhenLocked(uint32_t flags)
252     {
253         return flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
254     }
255 
GetOverlap(const Rect & rect1,const Rect & rect2,const int offsetX,const int offsetY)256     static Rect GetOverlap(const Rect& rect1, const Rect& rect2, const int offsetX, const int offsetY)
257     {
258         int32_t x_begin = std::max(rect1.posX_, rect2.posX_);
259         int32_t x_end = std::min(rect1.posX_ + static_cast<int32_t>(rect1.width_),
260             rect2.posX_ + static_cast<int32_t>(rect2.width_));
261         int32_t y_begin = std::max(rect1.posY_, rect2.posY_);
262         int32_t y_end = std::min(rect1.posY_ + static_cast<int32_t>(rect1.height_),
263             rect2.posY_ + static_cast<int32_t>(rect2.height_));
264         if (y_begin >= y_end || x_begin >= x_end) {
265             return { 0, 0, 0, 0 };
266         }
267         return { x_begin - offsetX, y_begin - offsetY,
268             static_cast<uint32_t>(x_end - x_begin), static_cast<uint32_t>(y_end - y_begin) };
269     }
270 
IsWindowModeSupported(uint32_t windowModeSupportType,WindowMode mode)271     static bool IsWindowModeSupported(uint32_t windowModeSupportType, WindowMode mode)
272     {
273         switch (mode) {
274             case WindowMode::WINDOW_MODE_FULLSCREEN:
275                 return WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN & windowModeSupportType;
276             case WindowMode::WINDOW_MODE_FLOATING:
277                 return WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING & windowModeSupportType;
278             case WindowMode::WINDOW_MODE_SPLIT_PRIMARY:
279                 return WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY & windowModeSupportType;
280             case WindowMode::WINDOW_MODE_SPLIT_SECONDARY:
281                 return WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY & windowModeSupportType;
282             case WindowMode::WINDOW_MODE_PIP:
283                 return WindowModeSupport::WINDOW_MODE_SUPPORT_PIP & windowModeSupportType;
284             case WindowMode::WINDOW_MODE_FB:
285                 return WindowModeSupport::WINDOW_MODE_SUPPORT_FB & windowModeSupportType;
286             case WindowMode::WINDOW_MODE_UNDEFINED:
287                 return false;
288             default:
289                 return true;
290         }
291     }
292 
GetWindowModeFromWindowModeSupportType(uint32_t windowModeSupportType)293     static WindowMode GetWindowModeFromWindowModeSupportType(uint32_t windowModeSupportType)
294     {
295         // get the binary number consists of the last 1 and 0 behind it
296         uint32_t windowModeSupport = windowModeSupportType & (~windowModeSupportType + 1);
297 
298         switch (windowModeSupport) {
299             case WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN:
300                 return WindowMode::WINDOW_MODE_FULLSCREEN;
301             case WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING:
302                 return WindowMode::WINDOW_MODE_FLOATING;
303             case WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY:
304                 return WindowMode::WINDOW_MODE_SPLIT_PRIMARY;
305             case WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY:
306                 return WindowMode::WINDOW_MODE_SPLIT_SECONDARY;
307             case WindowModeSupport::WINDOW_MODE_SUPPORT_PIP:
308                 return WindowMode::WINDOW_MODE_PIP;
309             case WindowModeSupport::WINDOW_MODE_SUPPORT_FB:
310                 return WindowMode::WINDOW_MODE_FB;
311             default:
312                 return WindowMode::WINDOW_MODE_UNDEFINED;
313         }
314     }
315 
ConvertSupportModesToSupportType(const std::vector<AppExecFwk::SupportWindowMode> & supportModes)316     static uint32_t ConvertSupportModesToSupportType(const std::vector<AppExecFwk::SupportWindowMode>& supportModes)
317     {
318         uint32_t windowModeSupportType = 0;
319         for (auto& mode : supportModes) {
320             if (mode == AppExecFwk::SupportWindowMode::FULLSCREEN) {
321                 windowModeSupportType |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
322             } else if (mode == AppExecFwk::SupportWindowMode::SPLIT) {
323                 windowModeSupportType |= (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
324                                     WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY);
325             } else if (mode == AppExecFwk::SupportWindowMode::FLOATING) {
326                 windowModeSupportType |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
327             }
328         }
329         return windowModeSupportType;
330     }
331 
ConvertSupportTypeToSupportModes(uint32_t windowModeSupportType)332     static std::vector<AppExecFwk::SupportWindowMode> ConvertSupportTypeToSupportModes(uint32_t windowModeSupportType)
333     {
334         std::vector<AppExecFwk::SupportWindowMode> supportModes;
335         if ((windowModeSupportType & WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN) != 0) {
336             supportModes.push_back(AppExecFwk::SupportWindowMode::FULLSCREEN);
337         }
338         if ((windowModeSupportType & (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
339             WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY)) != 0) {
340             supportModes.push_back(AppExecFwk::SupportWindowMode::SPLIT);
341         }
342         if ((windowModeSupportType & WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING) != 0) {
343             supportModes.push_back(AppExecFwk::SupportWindowMode::FLOATING);
344         }
345         return supportModes;
346     }
347 
IsPointInTargetRect(int32_t pointPosX,int32_t pointPosY,const Rect & targetRect)348     static bool IsPointInTargetRect(int32_t pointPosX, int32_t pointPosY, const Rect& targetRect)
349     {
350         if ((pointPosX > targetRect.posX_) &&
351             (pointPosX < (targetRect.posX_ + static_cast<int32_t>(targetRect.width_)) - 1) &&
352             (pointPosY > targetRect.posY_) &&
353             (pointPosY < (targetRect.posY_ + static_cast<int32_t>(targetRect.height_)) - 1)) {
354             return true;
355         }
356         return false;
357     }
358 
IsPointInTargetRectWithBound(int32_t pointPosX,int32_t pointPosY,const Rect & targetRect)359     static bool IsPointInTargetRectWithBound(int32_t pointPosX, int32_t pointPosY, const Rect& targetRect)
360     {
361         if ((pointPosX >= targetRect.posX_) &&
362             (pointPosX < (targetRect.posX_ + static_cast<int32_t>(targetRect.width_))) &&
363             (pointPosY >= targetRect.posY_) &&
364             (pointPosY < (targetRect.posY_ + static_cast<int32_t>(targetRect.height_)))) {
365             return true;
366         }
367         return false;
368     }
369 
IsPointInWindowExceptCorner(int32_t pointPosX,int32_t pointPosY,const Rect & rectExceptCorner)370     static bool IsPointInWindowExceptCorner(int32_t pointPosX, int32_t pointPosY, const Rect& rectExceptCorner)
371     {
372         if ((pointPosX > rectExceptCorner.posX_ &&
373             pointPosX < (rectExceptCorner.posX_ + static_cast<int32_t>(rectExceptCorner.width_)) - 1) ||
374             (pointPosY > rectExceptCorner.posY_ &&
375             pointPosY < (rectExceptCorner.posY_ + static_cast<int32_t>(rectExceptCorner.height_)) - 1)) {
376             return true;
377         }
378         return false;
379     }
380 
IsSwitchCascadeReason(WindowUpdateReason reason)381     static inline bool IsSwitchCascadeReason(WindowUpdateReason reason)
382     {
383         return (reason >= WindowUpdateReason::NEED_SWITCH_CASCADE_BASE) &&
384             (reason < WindowUpdateReason::NEED_SWITCH_CASCADE_END);
385     }
386 
GetAvoidPosType(const Rect & rect,const Rect & displayRect)387     static AvoidPosType GetAvoidPosType(const Rect& rect, const Rect& displayRect)
388     {
389         if (rect.width_ ==  displayRect.width_) {
390             if (rect.posY_ == displayRect.posY_) {
391                 return AvoidPosType::AVOID_POS_TOP;
392             } else {
393                 return AvoidPosType::AVOID_POS_BOTTOM;
394             }
395         } else if (rect.height_ ==  displayRect.height_) {
396             if (rect.posX_ == displayRect.posX_) {
397                 return AvoidPosType::AVOID_POS_LEFT;
398             } else {
399                 return AvoidPosType::AVOID_POS_RIGHT;
400             }
401         }
402 
403         return AvoidPosType::AVOID_POS_UNKNOWN;
404     }
405 
IsNumber(std::string str)406     static inline bool IsNumber(std::string str)
407     {
408         if (str.size() == 0) {
409             return false;
410         }
411         for (int32_t i = 0; i < static_cast<int32_t>(str.size()); i++) {
412             if (str.at(i) < '0' || str.at(i) > '9') {
413                 return false;
414             }
415         }
416         return true;
417     }
418 
419     static bool IsFloatingNumber(std::string str, bool allowNeg = false)
420     {
421         if (str.size() == 0) {
422             return false;
423         }
424 
425         int32_t i = 0;
426         if (allowNeg && str.at(i) == '-') {
427             i++;
428         }
429 
430         for (; i < static_cast<int32_t>(str.size()); i++) {
431             if ((str.at(i) < '0' || str.at(i) > '9') &&
432                 (str.at(i) != '.' || std::count(str.begin(), str.end(), '.') > 1)) {
433                 return false;
434             }
435         }
436         return true;
437     }
438 
Split(std::string str,std::string pattern)439     static std::vector<std::string> Split(std::string str, std::string pattern)
440     {
441         int32_t position;
442         std::vector<std::string> result;
443         str += pattern;
444         int32_t length = static_cast<int32_t>(str.size());
445         for (int32_t i = 0; i < length; i++) {
446             position = static_cast<int32_t>(str.find(pattern, i));
447             if (position < length) {
448                 std::string tmp = str.substr(i, position - i);
449                 result.push_back(tmp);
450                 i = position + static_cast<int32_t>(pattern.size()) - 1;
451             }
452         }
453         return result;
454     }
455 
CalculateOriginPosition(const Rect & rOrigin,const Rect & rActial,const PointInfo & pos)456     static PointInfo CalculateOriginPosition(const Rect& rOrigin, const Rect& rActial, const PointInfo& pos)
457     {
458         PointInfo ret = pos;
459         ret.x += rActial.posX_ - pos.x;
460         ret.y += rActial.posY_ - pos.y;
461         ret.x += rOrigin.posX_ - rActial.posX_;
462         ret.y += rOrigin.posY_ - rActial.posY_;
463         if (rActial.width_ && rActial.height_) {
464             ret.x += (pos.x - rActial.posX_) * rOrigin.width_ / rActial.width_;
465             ret.y += (pos.y - rActial.posY_) * rOrigin.height_ / rActial.height_;
466         }
467         return ret;
468     }
469 
470     // Transform a point at screen to its oringin position in 3D world and project to xy plane
CalculateOriginPosition(const TransformHelper::Matrix4 & transformMat,const PointInfo & pointPos)471     static PointInfo CalculateOriginPosition(const TransformHelper::Matrix4& transformMat, const PointInfo& pointPos)
472     {
473         TransformHelper::Vector2 p(static_cast<float>(pointPos.x), static_cast<float>(pointPos.y));
474         TransformHelper::Vector2 originPos = TransformHelper::GetOriginScreenPoint(p, transformMat);
475         return PointInfo { static_cast<uint32_t>(originPos.x_), static_cast<uint32_t>(originPos.y_) };
476     }
477 
478     // This method is used to update transform when rect changed, but world transform matrix should not change.
GetTransformFromWorldMat4(const TransformHelper::Matrix4 & inWorldMat,const Rect & rect,Transform & transform)479     static void GetTransformFromWorldMat4(const TransformHelper::Matrix4& inWorldMat, const Rect& rect,
480         Transform& transform)
481     {
482         TransformHelper::Vector3 pivotPos = { rect.posX_ + transform.pivotX_ * rect.width_,
483             rect.posY_ + transform.pivotY_ * rect.height_, 0 };
484         TransformHelper::Matrix4 worldMat = TransformHelper::CreateTranslation(pivotPos) * inWorldMat *
485                         TransformHelper::CreateTranslation(-pivotPos);
486         auto scale = worldMat.GetScale();
487         auto translation = worldMat.GetTranslation();
488         transform.scaleX_ = scale.x_;
489         transform.scaleY_ = scale.y_;
490         transform.scaleZ_ = scale.z_;
491         transform.translateX_ = translation.x_;
492         transform.translateY_ = translation.y_;
493         transform.translateZ_ = translation.z_;
494     }
495 
ComputeWorldTransformMat4(const Transform & transform)496     static TransformHelper::Matrix4 ComputeWorldTransformMat4(const Transform& transform)
497     {
498         TransformHelper::Matrix4 ret = TransformHelper::Matrix4::Identity;
499         // set scale
500         if (!MathHelper::NearZero(transform.scaleX_ - 1.0f) || !MathHelper::NearZero(transform.scaleY_ - 1.0f) ||
501             !MathHelper::NearZero(transform.scaleZ_ - 1.0f)) {
502             ret *= TransformHelper::CreateScale(transform.scaleX_, transform.scaleY_, transform.scaleZ_);
503         }
504         // set rotation
505         if (!MathHelper::NearZero(transform.rotationX_)) {
506             ret *= TransformHelper::CreateRotationX(MathHelper::ToRadians(transform.rotationX_));
507         }
508         if (!MathHelper::NearZero(transform.rotationY_)) {
509             ret *= TransformHelper::CreateRotationY(MathHelper::ToRadians(transform.rotationY_));
510         }
511         if (!MathHelper::NearZero(transform.rotationZ_)) {
512             ret *= TransformHelper::CreateRotationZ(MathHelper::ToRadians(transform.rotationZ_));
513         }
514         // set translation
515         if (!MathHelper::NearZero(transform.translateX_) || !MathHelper::NearZero(transform.translateY_) ||
516             !MathHelper::NearZero(transform.translateZ_)) {
517             ret *= TransformHelper::CreateTranslation(TransformHelper::Vector3(transform.translateX_,
518                 transform.translateY_, transform.translateZ_));
519         }
520         return ret;
521     }
522 
523     // Transform rect by matrix and get the circumscribed rect
TransformRect(const TransformHelper::Matrix4 & transformMat,const Rect & rect)524     static Rect TransformRect(const TransformHelper::Matrix4& transformMat, const Rect& rect)
525     {
526         TransformHelper::Vector3 a = TransformHelper::TransformWithPerspDiv(
527             TransformHelper::Vector3(rect.posX_, rect.posY_, 0), transformMat);
528         TransformHelper::Vector3 b = TransformHelper::TransformWithPerspDiv(
529             TransformHelper::Vector3(rect.posX_ + rect.width_, rect.posY_, 0), transformMat);
530         TransformHelper::Vector3 c = TransformHelper::TransformWithPerspDiv(
531             TransformHelper::Vector3(rect.posX_, rect.posY_ + rect.height_, 0), transformMat);
532         TransformHelper::Vector3 d = TransformHelper::TransformWithPerspDiv(
533             TransformHelper::Vector3(rect.posX_ + rect.width_, rect.posY_ + rect.height_, 0), transformMat);
534         // Return smallest rect involve transformed rect(abcd)
535         int32_t xmin = MathHelper::Min(a.x_, b.x_, c.x_, d.x_);
536         int32_t ymin = MathHelper::Min(a.y_, b.y_, c.y_, d.y_);
537         int32_t xmax = MathHelper::Max(a.x_, b.x_, c.x_, d.x_);
538         int32_t ymax = MathHelper::Max(a.y_, b.y_, c.y_, d.y_);
539         uint32_t w = static_cast<uint32_t>(xmax - xmin);
540         uint32_t h = static_cast<uint32_t>(ymax - ymin);
541         return Rect { xmin, ymin, w, h };
542     }
543 
CalculateHotZoneScale(const TransformHelper::Matrix4 & transformMat)544     static TransformHelper::Vector2 CalculateHotZoneScale(const TransformHelper::Matrix4& transformMat)
545     {
546         TransformHelper::Vector2 hotZoneScale;
547         TransformHelper::Vector3 a = TransformHelper::TransformWithPerspDiv(TransformHelper::Vector3(0, 0, 0),
548             transformMat);
549         TransformHelper::Vector3 b = TransformHelper::TransformWithPerspDiv(TransformHelper::Vector3(1, 0, 0),
550             transformMat);
551         TransformHelper::Vector3 c = TransformHelper::TransformWithPerspDiv(TransformHelper::Vector3(0, 1, 0),
552             transformMat);
553         TransformHelper::Vector2 axy(a.x_, a.y_);
554         TransformHelper::Vector2 bxy(b.x_, b.y_);
555         TransformHelper::Vector2 cxy(c.x_, c.y_);
556         hotZoneScale.x_ = (axy - bxy).Length();
557         hotZoneScale.y_ = (axy - cxy).Length();
558         if (std::isnan(hotZoneScale.x_) || std::isnan(hotZoneScale.y_) ||
559             MathHelper::NearZero(hotZoneScale.x_) || MathHelper::NearZero(hotZoneScale.y_)) {
560             return TransformHelper::Vector2(1, 1);
561         } else {
562             return hotZoneScale;
563         }
564     }
565 
CalculateTouchHotAreas(const Rect & windowRect,const std::vector<Rect> & requestRects,std::vector<Rect> & outRects)566     static bool CalculateTouchHotAreas(const Rect& windowRect, const std::vector<Rect>& requestRects,
567         std::vector<Rect>& outRects)
568     {
569         bool isOk = true;
570         for (const auto& rect : requestRects) {
571             if (rect.posX_ < 0 || rect.posY_ < 0 || rect.width_ == 0 || rect.height_ == 0) {
572                 return false;
573             }
574             Rect hotArea;
575             if (rect.posX_ >= static_cast<int32_t>(windowRect.width_) ||
576                 rect.posY_ >= static_cast<int32_t>(windowRect.height_)) {
577                 isOk = false;
578                 continue;
579             }
580             hotArea.posX_ = windowRect.posX_ + rect.posX_;
581             hotArea.posY_ = windowRect.posY_ + rect.posY_;
582             hotArea.width_ = static_cast<uint32_t>(std::min(hotArea.posX_ + rect.width_,
583                 windowRect.posX_ + windowRect.width_) - hotArea.posX_);
584             hotArea.height_ = static_cast<uint32_t>(std::min(hotArea.posY_ + rect.height_,
585                 windowRect.posY_ + windowRect.height_) - hotArea.posY_);
586             outRects.emplace_back(hotArea);
587         }
588         return isOk;
589     }
590 
IsRectSatisfiedWithSizeLimits(const Rect & rect,const WindowLimits & sizeLimits)591     static bool IsRectSatisfiedWithSizeLimits(const Rect& rect, const WindowLimits& sizeLimits)
592     {
593         if (rect.height_ == 0) {
594             return false;
595         }
596         auto curRatio = static_cast<float>(rect.width_) / static_cast<float>(rect.height_);
597         if (sizeLimits.minWidth_ <= rect.width_ && rect.width_ <= sizeLimits.maxWidth_ &&
598             sizeLimits.minHeight_ <= rect.height_ && rect.height_ <= sizeLimits.maxHeight_ &&
599             sizeLimits.minRatio_ <= curRatio && curRatio <= sizeLimits.maxRatio_) {
600             return true;
601         }
602         return false;
603     }
604 
IsOnlySupportSplitAndShowWhenLocked(bool isShowWhenLocked,uint32_t windowModeSupportType)605     static bool IsOnlySupportSplitAndShowWhenLocked(bool isShowWhenLocked, uint32_t windowModeSupportType)
606     {
607         uint32_t splitMode = (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
608                               WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY);
609         if (isShowWhenLocked && (splitMode == windowModeSupportType)) {
610             return true;
611         }
612         return false;
613     }
614 
IsInvalidWindowInTileLayoutMode(uint32_t supportModeInfo,WindowLayoutMode layoutMode)615     static bool IsInvalidWindowInTileLayoutMode(uint32_t supportModeInfo, WindowLayoutMode layoutMode)
616     {
617         if ((!IsWindowModeSupported(supportModeInfo, WindowMode::WINDOW_MODE_FLOATING)) &&
618             (layoutMode == WindowLayoutMode::TILE)) {
619             return true;
620         }
621         return false;
622     }
623 
CheckSupportWindowMode(WindowMode winMode,uint32_t windowModeSupportType,const sptr<WindowTransitionInfo> & info)624     static bool CheckSupportWindowMode(WindowMode winMode, uint32_t windowModeSupportType,
625         const sptr<WindowTransitionInfo>& info)
626     {
627         if (!WindowHelper::IsMainWindow(info->GetWindowType())) {
628             return true;
629         }
630 
631         if (!IsWindowModeSupported(windowModeSupportType, winMode) ||
632             IsOnlySupportSplitAndShowWhenLocked(info->GetShowFlagWhenLocked(), windowModeSupportType)) {
633             return false;
634         }
635         return true;
636     }
637 
IsAspectRatioSatisfiedWithSizeLimits(const WindowLimits & sizeLimits,float ratio,float vpr)638     static bool IsAspectRatioSatisfiedWithSizeLimits(const WindowLimits& sizeLimits, float ratio, float vpr)
639     {
640         /*
641          * 1) Usually the size limits won't be empty after show window.
642          *    In case of SetAspectRatio is called befor show (size limits may be empty at that time) or the
643          *    sizeLimits is empty, there is no need to check ratio (layout will check), return true directly.
644          * 2) ratio : 0.0 means reset aspect ratio
645          */
646         if (sizeLimits.IsEmpty() || MathHelper::NearZero(ratio)) {
647             return true;
648         }
649 
650         uint32_t winFrameW = static_cast<uint32_t>(WINDOW_FRAME_WIDTH * vpr) * 2; // 2 mean double decor width
651         uint32_t winFrameH = static_cast<uint32_t>(WINDOW_FRAME_WIDTH * vpr) +
652             static_cast<uint32_t>(WINDOW_TITLE_BAR_HEIGHT * vpr); // decor height
653         uint32_t maxWidth = sizeLimits.maxWidth_ - winFrameW;
654         uint32_t minWidth = sizeLimits.minWidth_ - winFrameW;
655         uint32_t maxHeight = sizeLimits.maxHeight_ - winFrameH;
656         uint32_t minHeight = sizeLimits.minHeight_ - winFrameH;
657         float maxRatio = static_cast<float>(maxWidth) / static_cast<float>(minHeight);
658         float minRatio = static_cast<float>(minWidth) / static_cast<float>(maxHeight);
659         if (maxRatio < ratio || ratio < minRatio) {
660             return false;
661         }
662         return true;
663     }
664 
IsWindowFollowParent(WindowType type)665     static bool IsWindowFollowParent(WindowType type)
666     {
667         if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
668             return true;
669         }
670         return false;
671     }
672 
CheckButtonStyleValid(const DecorButtonStyle & decorButtonStyle)673     static bool CheckButtonStyleValid(const DecorButtonStyle& decorButtonStyle)
674     {
675         return decorButtonStyle.buttonBackgroundSize >= MIN_BUTTON_BACKGROUND_SIZE &&
676                decorButtonStyle.buttonBackgroundSize <= MAX_BUTTON_BACKGROUND_SIZE &&
677                decorButtonStyle.closeButtonRightMargin >= MIN_CLOSE_BUTTON_RIGHT_MARGIN &&
678                decorButtonStyle.closeButtonRightMargin <= MAX_CLOSE_BUTTON_RIGHT_MARGIN &&
679                decorButtonStyle.spacingBetweenButtons >= MIN_SPACING_BETWEEN_BUTTONS &&
680                decorButtonStyle.spacingBetweenButtons <= MAX_SPACING_BETWEEN_BUTTONS &&
681                decorButtonStyle.colorMode >= MIN_COLOR_MODE &&
682                decorButtonStyle.colorMode <= MAX_COLOR_MODE &&
683                decorButtonStyle.buttonIconSize >= MIN_BUTTON_ICON_SIZE &&
684                decorButtonStyle.buttonIconSize <= MAX_BUTTON_ICON_SIZE &&
685                decorButtonStyle.buttonBackgroundCornerRadius >= MIN_BUTTON_BACKGROUND_CORNER_RADIUS &&
686                decorButtonStyle.buttonBackgroundCornerRadius <= MAX_BUTTON_BACKGROUND_CORNER_RADIUS;
687     }
688 
SplitStringByDelimiter(const std::string & inputStr,const std::string & delimiter,std::unordered_set<std::string> & container)689     static void SplitStringByDelimiter(
690         const std::string& inputStr, const std::string& delimiter, std::unordered_set<std::string>& container)
691     {
692         if (inputStr.empty()) {
693             return;
694         }
695         if (delimiter.empty()) {
696             container.insert(inputStr);
697             return;
698         }
699         std::string::size_type start = 0;
700         std::string::size_type end = 0;
701         while ((end = inputStr.find(delimiter, start)) != std::string::npos) {
702             container.insert(inputStr.substr(start, end - start));
703             start = end + delimiter.length();
704         }
705         container.insert(inputStr.substr(start));
706     }
707 
708     /**
709      * @brief Check whether the window has scaling applied.
710      *
711      * This method returns true if scaleX or scaleY is not equal to 1,
712      * meaning the window is currently scaled.
713      *
714      * @param transform The layout transform of the window.
715      * @return true if the window is scaled, false otherwise.
716      */
IsScaled(const Transform & transform)717     static bool IsScaled(const Transform& transform)
718     {
719         auto IsApproximatelyOne = [](float value) {
720             constexpr float EPSILON = 1e-6f;
721             return std::fabs(value - 1.0f) < EPSILON;
722         };
723         return !IsApproximatelyOne(transform.scaleX_) || !IsApproximatelyOne(transform.scaleY_);
724     }
725 
726 private:
727     WindowHelper() = default;
728     ~WindowHelper() = default;
729 };
730 } // namespace OHOS
731 } // namespace Rosen
732 #endif // OHOS_WM_INCLUDE_WM_HELPER_H
733