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
27namespace OHOS {
28namespace Rosen {
29class WindowHelper {
30public:
31    static inline bool IsMainWindow(WindowType type)
32    {
33        return (type >= WindowType::APP_MAIN_WINDOW_BASE && type < WindowType::APP_MAIN_WINDOW_END);
34    }
35
36    static inline bool IsMainWindowAndNotShown(WindowType type, WindowState state)
37    {
38        return (IsMainWindow(type) && state != WindowState::STATE_SHOWN);
39    }
40
41    static inline bool IsSubWindow(WindowType type)
42    {
43        return (type >= WindowType::APP_SUB_WINDOW_BASE && type < WindowType::APP_SUB_WINDOW_END);
44    }
45
46    static inline bool IsModalSubWindow(WindowType type, uint32_t windowFlags)
47    {
48        return IsSubWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_MODAL));
49    }
50
51    static inline bool IsApplicationModalSubWindow(WindowType type, uint32_t windowFlags)
52    {
53        return IsModalSubWindow(type, windowFlags) &&
54            (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL));
55    }
56
57    static inline bool IsToastSubWindow(WindowType type, uint32_t windowFlags)
58    {
59        return IsSubWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST));
60    }
61
62    static inline bool IsDialogWindow(WindowType type)
63    {
64        return type == WindowType::WINDOW_TYPE_DIALOG;
65    }
66
67    static inline bool IsAppWindow(WindowType type)
68    {
69        return (IsMainWindow(type) || IsSubWindow(type));
70    }
71
72    static inline bool IsAppFloatingWindow(WindowType type)
73    {
74        return (type == WindowType::WINDOW_TYPE_FLOAT) || (type == WindowType::WINDOW_TYPE_FLOAT_CAMERA);
75    }
76
77    static inline bool IsPipWindow(WindowType type)
78    {
79        return (type == WindowType::WINDOW_TYPE_PIP);
80    }
81
82    static inline bool IsBelowSystemWindow(WindowType type)
83    {
84        return (type >= WindowType::BELOW_APP_SYSTEM_WINDOW_BASE && type < WindowType::BELOW_APP_SYSTEM_WINDOW_END);
85    }
86
87    static inline bool IsAboveSystemWindow(WindowType type)
88    {
89        return (type >= WindowType::ABOVE_APP_SYSTEM_WINDOW_BASE && type < WindowType::ABOVE_APP_SYSTEM_WINDOW_END);
90    }
91
92    static inline bool IsSystemSubWindow(WindowType type)
93    {
94        return (type >= WindowType::SYSTEM_SUB_WINDOW_BASE && type < WindowType::SYSTEM_SUB_WINDOW_END);
95    }
96
97    static inline bool IsSystemMainWindow(WindowType type)
98    {
99        return IsBelowSystemWindow(type) || IsAboveSystemWindow(type);
100    }
101
102    static inline bool IsSystemWindow(WindowType type)
103    {
104        return (IsBelowSystemWindow(type) || IsAboveSystemWindow(type) || IsSystemSubWindow(type));
105    }
106
107    static inline bool IsUIExtensionWindow(WindowType type)
108    {
109        return (type == WindowType::WINDOW_TYPE_UI_EXTENSION);
110    }
111
112    static inline bool IsAppComponentWindow(WindowType type)
113    {
114        return (type == WindowType::WINDOW_TYPE_APP_COMPONENT);
115    }
116
117    static inline bool IsMainFloatingWindow(WindowType type, WindowMode mode)
118    {
119        return ((IsMainWindow(type)) && (mode == WindowMode::WINDOW_MODE_FLOATING));
120    }
121
122    static inline bool IsMainFullScreenWindow(WindowType type, WindowMode mode)
123    {
124        return ((IsMainWindow(type)) && (mode == WindowMode::WINDOW_MODE_FULLSCREEN));
125    }
126
127    static inline bool IsFloatingWindow(WindowMode mode)
128    {
129        return mode == WindowMode::WINDOW_MODE_FLOATING;
130    }
131
132    static inline bool IsSystemBarWindow(WindowType type)
133    {
134        return (type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_NAVIGATION_BAR);
135    }
136
137    static inline bool IsOverlayWindow(WindowType type)
138    {
139        return (type == WindowType::WINDOW_TYPE_STATUS_BAR ||
140            type == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
141            type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
142    }
143
144    static inline bool IsRotatableWindow(WindowType type, WindowMode mode)
145    {
146        return WindowHelper::IsMainFullScreenWindow(type, mode) || type == WindowType::WINDOW_TYPE_KEYGUARD ||
147            type == WindowType::WINDOW_TYPE_DESKTOP ||
148            ((type == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) && (mode == WindowMode::WINDOW_MODE_FULLSCREEN));
149    }
150
151    static inline bool IsFullScreenWindow(WindowMode mode)
152    {
153        return mode == WindowMode::WINDOW_MODE_FULLSCREEN;
154    }
155
156    static inline bool IsSplitWindowMode(WindowMode mode)
157    {
158        return mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY;
159    }
160
161    static inline bool IsAppFullOrSplitWindow(WindowType type, WindowMode mode)
162    {
163        if (!IsAppWindow(type)) {
164            return false;
165        }
166        return IsFullScreenWindow(mode) || IsSplitWindowMode(mode);
167    }
168
169    static inline bool IsValidWindowMode(WindowMode mode)
170    {
171        return mode == WindowMode::WINDOW_MODE_FULLSCREEN || mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
172            mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY || mode == WindowMode::WINDOW_MODE_FLOATING ||
173            mode == WindowMode::WINDOW_MODE_PIP;
174    }
175
176    static inline bool IsEmptyRect(const Rect& r)
177    {
178        return (r.posX_ == 0 && r.posY_ == 0 && r.width_ == 0 && r.height_ == 0);
179    }
180
181    static inline bool IsLandscapeRect(const Rect& r)
182    {
183        return r.width_ > r.height_;
184    }
185
186    static inline bool IsShowWhenLocked(uint32_t flags)
187    {
188        return flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
189    }
190
191    static Rect GetOverlap(const Rect& rect1, const Rect& rect2, const int offsetX, const int offsetY)
192    {
193        int32_t x_begin = std::max(rect1.posX_, rect2.posX_);
194        int32_t x_end = std::min(rect1.posX_ + static_cast<int32_t>(rect1.width_),
195            rect2.posX_ + static_cast<int32_t>(rect2.width_));
196        int32_t y_begin = std::max(rect1.posY_, rect2.posY_);
197        int32_t y_end = std::min(rect1.posY_ + static_cast<int32_t>(rect1.height_),
198            rect2.posY_ + static_cast<int32_t>(rect2.height_));
199        if (y_begin >= y_end || x_begin >= x_end) {
200            return { 0, 0, 0, 0 };
201        }
202        return { x_begin - offsetX, y_begin - offsetY,
203            static_cast<uint32_t>(x_end - x_begin), static_cast<uint32_t>(y_end - y_begin) };
204    }
205
206    static bool IsWindowModeSupported(uint32_t modeSupportInfo, WindowMode mode)
207    {
208        switch (mode) {
209            case WindowMode::WINDOW_MODE_FULLSCREEN:
210                return WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN & modeSupportInfo;
211            case WindowMode::WINDOW_MODE_FLOATING:
212                return WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING & modeSupportInfo;
213            case WindowMode::WINDOW_MODE_SPLIT_PRIMARY:
214                return WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY & modeSupportInfo;
215            case WindowMode::WINDOW_MODE_SPLIT_SECONDARY:
216                return WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY & modeSupportInfo;
217            case WindowMode::WINDOW_MODE_PIP:
218                return WindowModeSupport::WINDOW_MODE_SUPPORT_PIP & modeSupportInfo;
219            case WindowMode::WINDOW_MODE_UNDEFINED:
220                return false;
221            default:
222                return true;
223        }
224    }
225
226    static WindowMode GetWindowModeFromModeSupportInfo(uint32_t modeSupportInfo)
227    {
228        // get the binary number consists of the last 1 and 0 behind it
229        uint32_t windowModeSupport = modeSupportInfo & (~modeSupportInfo + 1);
230
231        switch (windowModeSupport) {
232            case WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN:
233                return WindowMode::WINDOW_MODE_FULLSCREEN;
234            case WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING:
235                return WindowMode::WINDOW_MODE_FLOATING;
236            case WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY:
237                return WindowMode::WINDOW_MODE_SPLIT_PRIMARY;
238            case WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY:
239                return WindowMode::WINDOW_MODE_SPLIT_SECONDARY;
240            case WindowModeSupport::WINDOW_MODE_SUPPORT_PIP:
241                return WindowMode::WINDOW_MODE_PIP;
242            default:
243                return WindowMode::WINDOW_MODE_UNDEFINED;
244        }
245    }
246
247    static uint32_t ConvertSupportModesToSupportInfo(const std::vector<AppExecFwk::SupportWindowMode>& supportModes)
248    {
249        uint32_t modeSupportInfo = 0;
250        for (auto& mode : supportModes) {
251            if (mode == AppExecFwk::SupportWindowMode::FULLSCREEN) {
252                modeSupportInfo |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
253            } else if (mode == AppExecFwk::SupportWindowMode::SPLIT) {
254                modeSupportInfo |= (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
255                                    WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY);
256            } else if (mode == AppExecFwk::SupportWindowMode::FLOATING) {
257                modeSupportInfo |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
258            }
259        }
260        return modeSupportInfo;
261    }
262
263    static bool IsPointInTargetRect(int32_t pointPosX, int32_t pointPosY, const Rect& targetRect)
264    {
265        if ((pointPosX > targetRect.posX_) &&
266            (pointPosX < (targetRect.posX_ + static_cast<int32_t>(targetRect.width_)) - 1) &&
267            (pointPosY > targetRect.posY_) &&
268            (pointPosY < (targetRect.posY_ + static_cast<int32_t>(targetRect.height_)) - 1)) {
269            return true;
270        }
271        return false;
272    }
273
274    static bool IsPointInTargetRectWithBound(int32_t pointPosX, int32_t pointPosY, const Rect& targetRect)
275    {
276        if ((pointPosX >= targetRect.posX_) &&
277            (pointPosX < (targetRect.posX_ + static_cast<int32_t>(targetRect.width_))) &&
278            (pointPosY >= targetRect.posY_) &&
279            (pointPosY < (targetRect.posY_ + static_cast<int32_t>(targetRect.height_)))) {
280            return true;
281        }
282        return false;
283    }
284
285    static bool IsPointInWindowExceptCorner(int32_t pointPosX, int32_t pointPosY, const Rect& rectExceptCorner)
286    {
287        if ((pointPosX > rectExceptCorner.posX_ &&
288            pointPosX < (rectExceptCorner.posX_ + static_cast<int32_t>(rectExceptCorner.width_)) - 1) ||
289            (pointPosY > rectExceptCorner.posY_ &&
290            pointPosY < (rectExceptCorner.posY_ + static_cast<int32_t>(rectExceptCorner.height_)) - 1)) {
291            return true;
292        }
293        return false;
294    }
295
296    static inline bool IsSwitchCascadeReason(WindowUpdateReason reason)
297    {
298        return (reason >= WindowUpdateReason::NEED_SWITCH_CASCADE_BASE) &&
299            (reason < WindowUpdateReason::NEED_SWITCH_CASCADE_END);
300    }
301
302    static AvoidPosType GetAvoidPosType(const Rect& rect, const Rect& displayRect)
303    {
304        if (rect.width_ ==  displayRect.width_) {
305            if (rect.posY_ == displayRect.posY_) {
306                return AvoidPosType::AVOID_POS_TOP;
307            } else {
308                return AvoidPosType::AVOID_POS_BOTTOM;
309            }
310        } else if (rect.height_ ==  displayRect.height_) {
311            if (rect.posX_ == displayRect.posX_) {
312                return AvoidPosType::AVOID_POS_LEFT;
313            } else {
314                return AvoidPosType::AVOID_POS_RIGHT;
315            }
316        }
317
318        return AvoidPosType::AVOID_POS_UNKNOWN;
319    }
320
321    static inline bool IsNumber(std::string str)
322    {
323        if (str.size() == 0) {
324            return false;
325        }
326        for (int32_t i = 0; i < static_cast<int32_t>(str.size()); i++) {
327            if (str.at(i) < '0' || str.at(i) > '9') {
328                return false;
329            }
330        }
331        return true;
332    }
333
334    static bool IsFloatingNumber(std::string str, bool allowNeg = false)
335    {
336        if (str.size() == 0) {
337            return false;
338        }
339
340        int32_t i = 0;
341        if (allowNeg && str.at(i) == '-') {
342            i++;
343        }
344
345        for (; i < static_cast<int32_t>(str.size()); i++) {
346            if ((str.at(i) < '0' || str.at(i) > '9') &&
347                (str.at(i) != '.' || std::count(str.begin(), str.end(), '.') > 1)) {
348                return false;
349            }
350        }
351        return true;
352    }
353
354    static std::vector<std::string> Split(std::string str, std::string pattern)
355    {
356        int32_t position;
357        std::vector<std::string> result;
358        str += pattern;
359        int32_t length = static_cast<int32_t>(str.size());
360        for (int32_t i = 0; i < length; i++) {
361            position = static_cast<int32_t>(str.find(pattern, i));
362            if (position < length) {
363                std::string tmp = str.substr(i, position - i);
364                result.push_back(tmp);
365                i = position + static_cast<int32_t>(pattern.size()) - 1;
366            }
367        }
368        return result;
369    }
370
371    static PointInfo CalculateOriginPosition(const Rect& rOrigin, const Rect& rActial, const PointInfo& pos)
372    {
373        PointInfo ret = pos;
374        ret.x += rActial.posX_ - pos.x;
375        ret.y += rActial.posY_ - pos.y;
376        ret.x += rOrigin.posX_ - rActial.posX_;
377        ret.y += rOrigin.posY_ - rActial.posY_;
378        if (rActial.width_ && rActial.height_) {
379            ret.x += (pos.x - rActial.posX_) * rOrigin.width_ / rActial.width_;
380            ret.y += (pos.y - rActial.posY_) * rOrigin.height_ / rActial.height_;
381        }
382        return ret;
383    }
384
385    // Transform a point at screen to its oringin position in 3D world and project to xy plane
386    static PointInfo CalculateOriginPosition(const TransformHelper::Matrix4& transformMat, const PointInfo& pointPos)
387    {
388        TransformHelper::Vector2 p(static_cast<float>(pointPos.x), static_cast<float>(pointPos.y));
389        TransformHelper::Vector2 originPos = TransformHelper::GetOriginScreenPoint(p, transformMat);
390        return PointInfo { static_cast<uint32_t>(originPos.x_), static_cast<uint32_t>(originPos.y_) };
391    }
392
393    // This method is used to update transform when rect changed, but world transform matrix should not change.
394    static void GetTransformFromWorldMat4(const TransformHelper::Matrix4& inWorldMat, const Rect& rect,
395        Transform& transform)
396    {
397        TransformHelper::Vector3 pivotPos = { rect.posX_ + transform.pivotX_ * rect.width_,
398            rect.posY_ + transform.pivotY_ * rect.height_, 0 };
399        TransformHelper::Matrix4 worldMat = TransformHelper::CreateTranslation(pivotPos) * inWorldMat *
400                        TransformHelper::CreateTranslation(-pivotPos);
401        auto scale = worldMat.GetScale();
402        auto translation = worldMat.GetTranslation();
403        transform.scaleX_ = scale.x_;
404        transform.scaleY_ = scale.y_;
405        transform.scaleZ_ = scale.z_;
406        transform.translateX_ = translation.x_;
407        transform.translateY_ = translation.y_;
408        transform.translateZ_ = translation.z_;
409    }
410
411    static TransformHelper::Matrix4 ComputeWorldTransformMat4(const Transform& transform)
412    {
413        TransformHelper::Matrix4 ret = TransformHelper::Matrix4::Identity;
414        // set scale
415        if (!MathHelper::NearZero(transform.scaleX_ - 1.0f) || !MathHelper::NearZero(transform.scaleY_ - 1.0f) ||
416            !MathHelper::NearZero(transform.scaleZ_ - 1.0f)) {
417            ret *= TransformHelper::CreateScale(transform.scaleX_, transform.scaleY_, transform.scaleZ_);
418        }
419        // set rotation
420        if (!MathHelper::NearZero(transform.rotationX_)) {
421            ret *= TransformHelper::CreateRotationX(MathHelper::ToRadians(transform.rotationX_));
422        }
423        if (!MathHelper::NearZero(transform.rotationY_)) {
424            ret *= TransformHelper::CreateRotationY(MathHelper::ToRadians(transform.rotationY_));
425        }
426        if (!MathHelper::NearZero(transform.rotationZ_)) {
427            ret *= TransformHelper::CreateRotationZ(MathHelper::ToRadians(transform.rotationZ_));
428        }
429        // set translation
430        if (!MathHelper::NearZero(transform.translateX_) || !MathHelper::NearZero(transform.translateY_) ||
431            !MathHelper::NearZero(transform.translateZ_)) {
432            ret *= TransformHelper::CreateTranslation(TransformHelper::Vector3(transform.translateX_,
433                transform.translateY_, transform.translateZ_));
434        }
435        return ret;
436    }
437
438    // Transform rect by matrix and get the circumscribed rect
439    static Rect TransformRect(const TransformHelper::Matrix4& transformMat, const Rect& rect)
440    {
441        TransformHelper::Vector3 a = TransformHelper::TransformWithPerspDiv(
442            TransformHelper::Vector3(rect.posX_, rect.posY_, 0), transformMat);
443        TransformHelper::Vector3 b = TransformHelper::TransformWithPerspDiv(
444            TransformHelper::Vector3(rect.posX_ + rect.width_, rect.posY_, 0), transformMat);
445        TransformHelper::Vector3 c = TransformHelper::TransformWithPerspDiv(
446            TransformHelper::Vector3(rect.posX_, rect.posY_ + rect.height_, 0), transformMat);
447        TransformHelper::Vector3 d = TransformHelper::TransformWithPerspDiv(
448            TransformHelper::Vector3(rect.posX_ + rect.width_, rect.posY_ + rect.height_, 0), transformMat);
449        // Return smallest rect involve transformed rect(abcd)
450        int32_t xmin = MathHelper::Min(a.x_, b.x_, c.x_, d.x_);
451        int32_t ymin = MathHelper::Min(a.y_, b.y_, c.y_, d.y_);
452        int32_t xmax = MathHelper::Max(a.x_, b.x_, c.x_, d.x_);
453        int32_t ymax = MathHelper::Max(a.y_, b.y_, c.y_, d.y_);
454        uint32_t w = static_cast<uint32_t>(xmax - xmin);
455        uint32_t h = static_cast<uint32_t>(ymax - ymin);
456        return Rect { xmin, ymin, w, h };
457    }
458
459    static TransformHelper::Vector2 CalculateHotZoneScale(const TransformHelper::Matrix4& transformMat)
460    {
461        TransformHelper::Vector2 hotZoneScale;
462        TransformHelper::Vector3 a = TransformHelper::TransformWithPerspDiv(TransformHelper::Vector3(0, 0, 0),
463            transformMat);
464        TransformHelper::Vector3 b = TransformHelper::TransformWithPerspDiv(TransformHelper::Vector3(1, 0, 0),
465            transformMat);
466        TransformHelper::Vector3 c = TransformHelper::TransformWithPerspDiv(TransformHelper::Vector3(0, 1, 0),
467            transformMat);
468        TransformHelper::Vector2 axy(a.x_, a.y_);
469        TransformHelper::Vector2 bxy(b.x_, b.y_);
470        TransformHelper::Vector2 cxy(c.x_, c.y_);
471        hotZoneScale.x_ = (axy - bxy).Length();
472        hotZoneScale.y_ = (axy - cxy).Length();
473        if (std::isnan(hotZoneScale.x_) || std::isnan(hotZoneScale.y_) ||
474            MathHelper::NearZero(hotZoneScale.x_) || MathHelper::NearZero(hotZoneScale.y_)) {
475            return TransformHelper::Vector2(1, 1);
476        } else {
477            return hotZoneScale;
478        }
479    }
480
481    static bool CalculateTouchHotAreas(const Rect& windowRect, const std::vector<Rect>& requestRects,
482        std::vector<Rect>& outRects)
483    {
484        bool isOk = true;
485        for (const auto& rect : requestRects) {
486            if (rect.posX_ < 0 || rect.posY_ < 0 || rect.width_ == 0 || rect.height_ == 0) {
487                return false;
488            }
489            Rect hotArea;
490            if (rect.posX_ >= static_cast<int32_t>(windowRect.width_) ||
491                rect.posY_ >= static_cast<int32_t>(windowRect.height_)) {
492                isOk = false;
493                continue;
494            }
495            hotArea.posX_ = windowRect.posX_ + rect.posX_;
496            hotArea.posY_ = windowRect.posY_ + rect.posY_;
497            hotArea.width_ = static_cast<uint32_t>(std::min(hotArea.posX_ + rect.width_,
498                windowRect.posX_ + windowRect.width_) - hotArea.posX_);
499            hotArea.height_ = static_cast<uint32_t>(std::min(hotArea.posY_ + rect.height_,
500                windowRect.posY_ + windowRect.height_) - hotArea.posY_);
501            outRects.emplace_back(hotArea);
502        }
503        return isOk;
504    }
505
506    static bool IsRectSatisfiedWithSizeLimits(const Rect& rect, const WindowLimits& sizeLimits)
507    {
508        if (rect.height_ == 0) {
509            return false;
510        }
511        auto curRatio = static_cast<float>(rect.width_) / static_cast<float>(rect.height_);
512        if (sizeLimits.minWidth_ <= rect.width_ && rect.width_ <= sizeLimits.maxWidth_ &&
513            sizeLimits.minHeight_ <= rect.height_ && rect.height_ <= sizeLimits.maxHeight_ &&
514            sizeLimits.minRatio_ <= curRatio && curRatio <= sizeLimits.maxRatio_) {
515            return true;
516        }
517        return false;
518    }
519
520    static bool IsOnlySupportSplitAndShowWhenLocked(bool isShowWhenLocked, uint32_t modeSupportInfo)
521    {
522        uint32_t splitModeInfo = (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
523                                  WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY);
524        if (isShowWhenLocked && (splitModeInfo == modeSupportInfo)) {
525            return true;
526        }
527        return false;
528    }
529
530    static bool IsInvalidWindowInTileLayoutMode(uint32_t supportModeInfo, WindowLayoutMode layoutMode)
531    {
532        if ((!IsWindowModeSupported(supportModeInfo, WindowMode::WINDOW_MODE_FLOATING)) &&
533            (layoutMode == WindowLayoutMode::TILE)) {
534            return true;
535        }
536        return false;
537    }
538
539    static bool CheckSupportWindowMode(WindowMode winMode, uint32_t modeSupportInfo,
540        const sptr<WindowTransitionInfo>& info)
541    {
542        if (!WindowHelper::IsMainWindow(info->GetWindowType())) {
543            return true;
544        }
545
546        if ((!IsWindowModeSupported(modeSupportInfo, winMode)) ||
547            (IsOnlySupportSplitAndShowWhenLocked(info->GetShowFlagWhenLocked(), modeSupportInfo))) {
548            return false;
549        }
550        return true;
551    }
552
553    static bool IsAspectRatioSatisfiedWithSizeLimits(const WindowLimits& sizeLimits, float ratio, float vpr)
554    {
555        /*
556         * 1) Usually the size limits won't be empty after show window.
557         *    In case of SetAspectRatio is called befor show (size limits may be empty at that time) or the
558         *    sizeLimits is empty, there is no need to check ratio (layout will check), return true directly.
559         * 2) ratio : 0.0 means reset aspect ratio
560         */
561        if (sizeLimits.IsEmpty() || MathHelper::NearZero(ratio)) {
562            return true;
563        }
564
565        uint32_t winFrameW = static_cast<uint32_t>(WINDOW_FRAME_WIDTH * vpr) * 2; // 2 mean double decor width
566        uint32_t winFrameH = static_cast<uint32_t>(WINDOW_FRAME_WIDTH * vpr) +
567            static_cast<uint32_t>(WINDOW_TITLE_BAR_HEIGHT * vpr); // decor height
568        uint32_t maxWidth = sizeLimits.maxWidth_ - winFrameW;
569        uint32_t minWidth = sizeLimits.minWidth_ - winFrameW;
570        uint32_t maxHeight = sizeLimits.maxHeight_ - winFrameH;
571        uint32_t minHeight = sizeLimits.minHeight_ - winFrameH;
572        float maxRatio = static_cast<float>(maxWidth) / static_cast<float>(minHeight);
573        float minRatio = static_cast<float>(minWidth) / static_cast<float>(maxHeight);
574        if (maxRatio < ratio || ratio < minRatio) {
575            return false;
576        }
577        return true;
578    }
579
580    static bool IsWindowFollowParent(WindowType type)
581    {
582        if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
583            return true;
584        }
585        return false;
586    }
587
588private:
589    WindowHelper() = default;
590    ~WindowHelper() = default;
591};
592} // namespace OHOS
593} // namespace Rosen
594#endif // OHOS_WM_INCLUDE_WM_HELPER_H
595