1e0dac50fSopenharmony_ci/*
2e0dac50fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License.
5e0dac50fSopenharmony_ci * You may obtain a copy of the License at
6e0dac50fSopenharmony_ci *
7e0dac50fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e0dac50fSopenharmony_ci *
9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and
13e0dac50fSopenharmony_ci * limitations under the License.
14e0dac50fSopenharmony_ci */
15e0dac50fSopenharmony_ci
16e0dac50fSopenharmony_ci#include "display_manager_proxy.h"
17e0dac50fSopenharmony_ci#include "window_test_utils.h"
18e0dac50fSopenharmony_ci#include <ability_context.h>
19e0dac50fSopenharmony_ci#include "window_helper.h"
20e0dac50fSopenharmony_ci#include "wm_common_inner.h"
21e0dac50fSopenharmony_ci#include "wm_common.h"
22e0dac50fSopenharmony_cinamespace OHOS {
23e0dac50fSopenharmony_cinamespace Rosen {
24e0dac50fSopenharmony_cinamespace {
25e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowTestUtils"};
26e0dac50fSopenharmony_ciconstexpr uint32_t EDGE_INTERVAL = 48;
27e0dac50fSopenharmony_ciconstexpr uint32_t MID_INTERVAL = 24;
28e0dac50fSopenharmony_ci}
29e0dac50fSopenharmony_ci
30e0dac50fSopenharmony_ciRect WindowTestUtils::displayRect_        = {0, 0, 0, 0};
31e0dac50fSopenharmony_ciRect WindowTestUtils::statusBarRect_      = {0, 0, 0, 0};
32e0dac50fSopenharmony_ciRect WindowTestUtils::naviBarRect_        = {0, 0, 0, 0};
33e0dac50fSopenharmony_ciRect WindowTestUtils::customAppRect_      = {0, 0, 0, 0};
34e0dac50fSopenharmony_ciRect WindowTestUtils::limitDisplayRect_   = {0, 0, 0, 0};
35e0dac50fSopenharmony_ciRect WindowTestUtils::dockWindowRect_     = {0, 0, 0, 0};
36e0dac50fSopenharmony_ciSplitRects WindowTestUtils::splitRects_   = {
37e0dac50fSopenharmony_ci    .primaryRect   = {0, 0, 0, 0},
38e0dac50fSopenharmony_ci    .secondaryRect = {0, 0, 0, 0},
39e0dac50fSopenharmony_ci    .dividerRect   = {0, 0, 0, 0},
40e0dac50fSopenharmony_ci};
41e0dac50fSopenharmony_ciRect WindowTestUtils::singleTileRect_     = {0, 0, 0, 0};
42e0dac50fSopenharmony_cistd::vector<Rect> WindowTestUtils::doubleTileRects_ = std::vector<Rect>(2);
43e0dac50fSopenharmony_cistd::vector<Rect> WindowTestUtils::tripleTileRects_ = std::vector<Rect>(3);
44e0dac50fSopenharmony_ciAvoidArea WindowTestUtils::systemAvoidArea_ = {};
45e0dac50fSopenharmony_ci
46e0dac50fSopenharmony_cibool WindowTestUtils::isVerticalDisplay_ = false;
47e0dac50fSopenharmony_ci
48e0dac50fSopenharmony_cisptr<Window> WindowTestUtils::CreateTestWindow(const TestWindowInfo& info)
49e0dac50fSopenharmony_ci{
50e0dac50fSopenharmony_ci    sptr<WindowOption> option = new WindowOption();
51e0dac50fSopenharmony_ci    option->SetWindowRect(info.rect);
52e0dac50fSopenharmony_ci    option->SetWindowType(info.type);
53e0dac50fSopenharmony_ci    option->SetWindowMode(info.mode);
54e0dac50fSopenharmony_ci    option->SetFocusable(info.focusable_);
55e0dac50fSopenharmony_ci    option->SetRequestedOrientation(info.orientation_);
56e0dac50fSopenharmony_ci    if (info.parentId != INVALID_WINDOW_ID) {
57e0dac50fSopenharmony_ci        option->SetParentId(info.parentId);
58e0dac50fSopenharmony_ci    }
59e0dac50fSopenharmony_ci    if (info.needAvoid) {
60e0dac50fSopenharmony_ci        option->AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
61e0dac50fSopenharmony_ci    } else {
62e0dac50fSopenharmony_ci        option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
63e0dac50fSopenharmony_ci    }
64e0dac50fSopenharmony_ci    if (info.parentLimit) {
65e0dac50fSopenharmony_ci        option->AddWindowFlag(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
66e0dac50fSopenharmony_ci    } else {
67e0dac50fSopenharmony_ci        option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
68e0dac50fSopenharmony_ci    }
69e0dac50fSopenharmony_ci    if (info.forbidSplitMove) {
70e0dac50fSopenharmony_ci        option->AddWindowFlag(WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE);
71e0dac50fSopenharmony_ci    } else {
72e0dac50fSopenharmony_ci        option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE);
73e0dac50fSopenharmony_ci    }
74e0dac50fSopenharmony_ci    if (info.showWhenLocked) {
75e0dac50fSopenharmony_ci        option->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
76e0dac50fSopenharmony_ci    } else {
77e0dac50fSopenharmony_ci        option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
78e0dac50fSopenharmony_ci    }
79e0dac50fSopenharmony_ci    sptr<Window> window = Window::Create(info.name, option);
80e0dac50fSopenharmony_ci    return window;
81e0dac50fSopenharmony_ci}
82e0dac50fSopenharmony_ci
83e0dac50fSopenharmony_cisptr<Window> WindowTestUtils::CreateDockWindow()
84e0dac50fSopenharmony_ci{
85e0dac50fSopenharmony_ci    TestWindowInfo info = {
86e0dac50fSopenharmony_ci        .name = "dockWindow",
87e0dac50fSopenharmony_ci        .rect = dockWindowRect_,
88e0dac50fSopenharmony_ci        .type = WindowType::WINDOW_TYPE_LAUNCHER_DOCK,
89e0dac50fSopenharmony_ci        .mode = WindowMode::WINDOW_MODE_FLOATING,
90e0dac50fSopenharmony_ci        .needAvoid = false,
91e0dac50fSopenharmony_ci        .parentLimit = false,
92e0dac50fSopenharmony_ci        .parentId = INVALID_WINDOW_ID,
93e0dac50fSopenharmony_ci    };
94e0dac50fSopenharmony_ci    return CreateTestWindow(info);
95e0dac50fSopenharmony_ci}
96e0dac50fSopenharmony_ci
97e0dac50fSopenharmony_cisptr<Window> WindowTestUtils::CreateStatusBarWindow()
98e0dac50fSopenharmony_ci{
99e0dac50fSopenharmony_ci    TestWindowInfo info = {
100e0dac50fSopenharmony_ci        .name = "statusBar",
101e0dac50fSopenharmony_ci        .rect = statusBarRect_,
102e0dac50fSopenharmony_ci        .type = WindowType::WINDOW_TYPE_STATUS_BAR,
103e0dac50fSopenharmony_ci        .mode = WindowMode::WINDOW_MODE_FLOATING,
104e0dac50fSopenharmony_ci        .needAvoid = false,
105e0dac50fSopenharmony_ci        .parentLimit = false,
106e0dac50fSopenharmony_ci        .parentId = INVALID_WINDOW_ID,
107e0dac50fSopenharmony_ci    };
108e0dac50fSopenharmony_ci    return CreateTestWindow(info);
109e0dac50fSopenharmony_ci}
110e0dac50fSopenharmony_ci
111e0dac50fSopenharmony_cisptr<Window> WindowTestUtils::CreateNavigationBarWindow()
112e0dac50fSopenharmony_ci{
113e0dac50fSopenharmony_ci    TestWindowInfo info = {
114e0dac50fSopenharmony_ci        .name = "naviBar",
115e0dac50fSopenharmony_ci        .rect = naviBarRect_,
116e0dac50fSopenharmony_ci        .type = WindowType::WINDOW_TYPE_NAVIGATION_BAR,
117e0dac50fSopenharmony_ci        .mode = WindowMode::WINDOW_MODE_FLOATING,
118e0dac50fSopenharmony_ci        .needAvoid = false,
119e0dac50fSopenharmony_ci        .parentLimit = false,
120e0dac50fSopenharmony_ci        .parentId = INVALID_WINDOW_ID,
121e0dac50fSopenharmony_ci    };
122e0dac50fSopenharmony_ci    return CreateTestWindow(info);
123e0dac50fSopenharmony_ci}
124e0dac50fSopenharmony_ci
125e0dac50fSopenharmony_cisptr<WindowScene> WindowTestUtils::CreateWindowScene()
126e0dac50fSopenharmony_ci{
127e0dac50fSopenharmony_ci    sptr<IWindowLifeCycle> listener = nullptr;
128e0dac50fSopenharmony_ci    std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext = nullptr;
129e0dac50fSopenharmony_ci
130e0dac50fSopenharmony_ci    sptr<WindowScene> scene = new WindowScene();
131e0dac50fSopenharmony_ci    scene->Init(0, abilityContext, listener);
132e0dac50fSopenharmony_ci    return scene;
133e0dac50fSopenharmony_ci}
134e0dac50fSopenharmony_ci
135e0dac50fSopenharmony_ciRect WindowTestUtils::GetDefaultFloatingRect(const sptr<Window>& window, bool avoid)
136e0dac50fSopenharmony_ci{
137e0dac50fSopenharmony_ci    limitDisplayRect_ = displayRect_;
138e0dac50fSopenharmony_ci    if (avoid) {
139e0dac50fSopenharmony_ci        UpdateSplitRects(window);
140e0dac50fSopenharmony_ci    }
141e0dac50fSopenharmony_ci    constexpr uint32_t half = 2;
142e0dac50fSopenharmony_ci    constexpr float ratio = DEFAULT_ASPECT_RATIO;  // 0.67: default height/width ratio
143e0dac50fSopenharmony_ci    float vpr = GetVirtualPixelRatio(0);
144e0dac50fSopenharmony_ci
145e0dac50fSopenharmony_ci    /*
146e0dac50fSopenharmony_ci     * Calculate default width and height, if width or height is
147e0dac50fSopenharmony_ci     * smaller than minWidth or minHeight, use the minimum limits
148e0dac50fSopenharmony_ci     */
149e0dac50fSopenharmony_ci    uint32_t defaultW = std::max(static_cast<uint32_t>(displayRect_.width_ * ratio),
150e0dac50fSopenharmony_ci                                 static_cast<uint32_t>(MIN_FLOATING_WIDTH * vpr));
151e0dac50fSopenharmony_ci    uint32_t defaultH = std::max(static_cast<uint32_t>(displayRect_.height_ * ratio),
152e0dac50fSopenharmony_ci                                 static_cast<uint32_t>(MIN_FLOATING_HEIGHT * vpr));
153e0dac50fSopenharmony_ci    // calculate default x and y
154e0dac50fSopenharmony_ci    Rect resRect = {0, 0, defaultW, defaultH};
155e0dac50fSopenharmony_ci    if (defaultW <= limitDisplayRect_.width_ && defaultH <= limitDisplayRect_.height_) {
156e0dac50fSopenharmony_ci        resRect.posX_ = limitDisplayRect_.posX_ + static_cast<int32_t>((limitDisplayRect_.width_ - defaultW) / half);
157e0dac50fSopenharmony_ci        resRect.posY_ = limitDisplayRect_.posY_ + static_cast<int32_t>((limitDisplayRect_.height_ - defaultH) / half);
158e0dac50fSopenharmony_ci    }
159e0dac50fSopenharmony_ci
160e0dac50fSopenharmony_ci    return resRect;
161e0dac50fSopenharmony_ci}
162e0dac50fSopenharmony_ci
163e0dac50fSopenharmony_ciRect WindowTestUtils::CalcLimitedRect(const Rect& rect, float virtualPixelRatio)
164e0dac50fSopenharmony_ci{
165e0dac50fSopenharmony_ci    constexpr uint32_t maxLimitLen = 2560;
166e0dac50fSopenharmony_ci    constexpr int32_t maxPosRemain = 48;
167e0dac50fSopenharmony_ci    uint32_t minFloatingW = static_cast<uint32_t>(MIN_FLOATING_WIDTH * virtualPixelRatio);
168e0dac50fSopenharmony_ci    uint32_t minFloatingH = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * virtualPixelRatio);
169e0dac50fSopenharmony_ci    Rect resRect = {
170e0dac50fSopenharmony_ci        std::min(std::max(rect.posX_, maxPosRemain - static_cast<int32_t>(rect.width_)),
171e0dac50fSopenharmony_ci            static_cast<int32_t>(displayRect_.width_) - maxPosRemain),
172e0dac50fSopenharmony_ci        std::min(std::max(rect.posY_, maxPosRemain), static_cast<int32_t>(displayRect_.height_) - maxPosRemain),
173e0dac50fSopenharmony_ci        std::min(std::max(minFloatingW, rect.width_), maxLimitLen),
174e0dac50fSopenharmony_ci        std::min(std::max(minFloatingH, rect.height_), maxLimitLen),
175e0dac50fSopenharmony_ci    };
176e0dac50fSopenharmony_ci    return resRect;
177e0dac50fSopenharmony_ci}
178e0dac50fSopenharmony_ci
179e0dac50fSopenharmony_ciRect WindowTestUtils::GetFloatingLimitedRect(const Rect& rect, float virtualPixelRatio)
180e0dac50fSopenharmony_ci{
181e0dac50fSopenharmony_ci    uint32_t minFloatingW = static_cast<uint32_t>(MIN_FLOATING_WIDTH * virtualPixelRatio);
182e0dac50fSopenharmony_ci    uint32_t minFloatingH = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * virtualPixelRatio);
183e0dac50fSopenharmony_ci    Rect resRect = {
184e0dac50fSopenharmony_ci        rect.posX_,
185e0dac50fSopenharmony_ci        rect.posY_,
186e0dac50fSopenharmony_ci        std::max(minFloatingW, rect.width_),
187e0dac50fSopenharmony_ci        std::max(minFloatingH, rect.height_),
188e0dac50fSopenharmony_ci    };
189e0dac50fSopenharmony_ci    return resRect;
190e0dac50fSopenharmony_ci}
191e0dac50fSopenharmony_ci
192e0dac50fSopenharmony_ciRect WindowTestUtils::GetDecorateRect(const Rect& rect, float virtualPixelRatio)
193e0dac50fSopenharmony_ci{
194e0dac50fSopenharmony_ci    uint32_t winFrameW = static_cast<uint32_t>(WINDOW_FRAME_WIDTH * virtualPixelRatio);
195e0dac50fSopenharmony_ci    uint32_t winTitleBarH = static_cast<uint32_t>(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio);
196e0dac50fSopenharmony_ci
197e0dac50fSopenharmony_ci    Rect resRect;
198e0dac50fSopenharmony_ci    resRect.posX_ = rect.posX_;
199e0dac50fSopenharmony_ci    resRect.posY_ = rect.posY_;
200e0dac50fSopenharmony_ci    resRect.width_ = rect.width_ + winFrameW + winFrameW;
201e0dac50fSopenharmony_ci    resRect.height_ = rect.height_ + winTitleBarH + winFrameW;
202e0dac50fSopenharmony_ci    return resRect;
203e0dac50fSopenharmony_ci}
204e0dac50fSopenharmony_ci
205e0dac50fSopenharmony_civoid WindowTestUtils::InitByDisplayRect(const Rect& displayRect)
206e0dac50fSopenharmony_ci{
207e0dac50fSopenharmony_ci    const float barRatio = 0.07;
208e0dac50fSopenharmony_ci    const float spaceRation = 0.125;
209e0dac50fSopenharmony_ci    displayRect_ = displayRect;
210e0dac50fSopenharmony_ci    limitDisplayRect_ = displayRect;
211e0dac50fSopenharmony_ci    if (displayRect_.width_ < displayRect_.height_) {
212e0dac50fSopenharmony_ci        isVerticalDisplay_ = true;
213e0dac50fSopenharmony_ci    }
214e0dac50fSopenharmony_ci    statusBarRect_ = {0, 0, displayRect_.width_, displayRect_.height_ * barRatio};
215e0dac50fSopenharmony_ci    naviBarRect_ = {0, displayRect_.height_ * (1 - barRatio), displayRect_.width_, displayRect_.height_ * barRatio};
216e0dac50fSopenharmony_ci    dockWindowRect_ = {0, displayRect_.height_ * (1 - barRatio), displayRect_.width_, displayRect_.height_ * barRatio};
217e0dac50fSopenharmony_ci    customAppRect_ = {
218e0dac50fSopenharmony_ci        displayRect_.width_ * spaceRation,
219e0dac50fSopenharmony_ci        displayRect_.height_ * spaceRation,
220e0dac50fSopenharmony_ci        displayRect_.width_ * DEFAULT_ASPECT_RATIO,
221e0dac50fSopenharmony_ci        displayRect_.height_ * DEFAULT_ASPECT_RATIO
222e0dac50fSopenharmony_ci    };
223e0dac50fSopenharmony_ci}
224e0dac50fSopenharmony_ci
225e0dac50fSopenharmony_cistd::shared_ptr<MMI::PointerEvent> WindowTestUtils::CreatePointerEvent(int32_t posX, int32_t posY, uint32_t pointerId,
226e0dac50fSopenharmony_ci    int32_t pointerAction)
227e0dac50fSopenharmony_ci{
228e0dac50fSopenharmony_ci    MMI::PointerEvent::PointerItem pointerItem;
229e0dac50fSopenharmony_ci    pointerItem.SetPointerId(pointerId);
230e0dac50fSopenharmony_ci    pointerItem.SetDisplayX(posX);
231e0dac50fSopenharmony_ci    pointerItem.SetDisplayY(posY);
232e0dac50fSopenharmony_ci
233e0dac50fSopenharmony_ci    std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
234e0dac50fSopenharmony_ci    pointerEvent->AddPointerItem(pointerItem);
235e0dac50fSopenharmony_ci    pointerEvent->SetPointerId(pointerId);
236e0dac50fSopenharmony_ci    pointerEvent->SetPointerAction(pointerAction);
237e0dac50fSopenharmony_ci    pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
238e0dac50fSopenharmony_ci    return pointerEvent;
239e0dac50fSopenharmony_ci}
240e0dac50fSopenharmony_ci
241e0dac50fSopenharmony_ciuint32_t WindowTestUtils::GetMaxTileWinNum()
242e0dac50fSopenharmony_ci{
243e0dac50fSopenharmony_ci    float virtualPixelRatio = GetVirtualPixelRatio(0);
244e0dac50fSopenharmony_ci    constexpr uint32_t half = 2;
245e0dac50fSopenharmony_ci    uint32_t edgeIntervalVp = static_cast<uint32_t>(EDGE_INTERVAL * half * virtualPixelRatio);
246e0dac50fSopenharmony_ci    uint32_t midIntervalVp = static_cast<uint32_t>(MID_INTERVAL * virtualPixelRatio);
247e0dac50fSopenharmony_ci    uint32_t minFloatingW = static_cast<uint32_t>(MIN_FLOATING_WIDTH * virtualPixelRatio);
248e0dac50fSopenharmony_ci    uint32_t drawableW = limitDisplayRect_.width_ - edgeIntervalVp + midIntervalVp;
249e0dac50fSopenharmony_ci    uint32_t maxNum = static_cast<uint32_t>(drawableW / (minFloatingW + midIntervalVp));
250e0dac50fSopenharmony_ci    WLOGI("maxNum: %{public}d", maxNum);
251e0dac50fSopenharmony_ci    return maxNum;
252e0dac50fSopenharmony_ci}
253e0dac50fSopenharmony_ci
254e0dac50fSopenharmony_civoid WindowTestUtils::InitTileWindowRects(const sptr<Window>& window, bool avoid)
255e0dac50fSopenharmony_ci{
256e0dac50fSopenharmony_ci    float virtualPixelRatio = GetVirtualPixelRatio(0);
257e0dac50fSopenharmony_ci    uint32_t edgeInterval = static_cast<uint32_t>(EDGE_INTERVAL * virtualPixelRatio); // 48 is edge interval
258e0dac50fSopenharmony_ci    uint32_t midInterval = static_cast<uint32_t>(MID_INTERVAL * virtualPixelRatio); // 24 is mid interval
259e0dac50fSopenharmony_ci    constexpr float ratio = DEFAULT_ASPECT_RATIO;
260e0dac50fSopenharmony_ci    constexpr int half = 2;
261e0dac50fSopenharmony_ci    limitDisplayRect_ = displayRect_;
262e0dac50fSopenharmony_ci    if (avoid) {
263e0dac50fSopenharmony_ci        UpdateSplitRects(window);
264e0dac50fSopenharmony_ci    }
265e0dac50fSopenharmony_ci
266e0dac50fSopenharmony_ci    uint32_t minFloatingW = static_cast<uint32_t>(MIN_FLOATING_WIDTH * virtualPixelRatio);
267e0dac50fSopenharmony_ci    uint32_t minFloatingH = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * virtualPixelRatio);
268e0dac50fSopenharmony_ci    uint32_t w = std::max(static_cast<uint32_t>(displayRect_.width_ * ratio), minFloatingW);
269e0dac50fSopenharmony_ci    uint32_t h = std::max(static_cast<uint32_t>(displayRect_.height_ * ratio), minFloatingH);
270e0dac50fSopenharmony_ci    w = w > limitDisplayRect_.width_ ? limitDisplayRect_.width_ : w;
271e0dac50fSopenharmony_ci    h = h > limitDisplayRect_.height_ ? limitDisplayRect_.height_ : h;
272e0dac50fSopenharmony_ci    int x = limitDisplayRect_.posX_ + ((limitDisplayRect_.width_ - w) / half);
273e0dac50fSopenharmony_ci    int y = limitDisplayRect_.posY_ + ((limitDisplayRect_.height_ - h) / half);
274e0dac50fSopenharmony_ci    singleTileRect_ = { x, y, w, h };
275e0dac50fSopenharmony_ci    WLOGI("singleRect_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h);
276e0dac50fSopenharmony_ci    x = edgeInterval;
277e0dac50fSopenharmony_ci    w = (limitDisplayRect_.width_ - edgeInterval * half - midInterval) / half;
278e0dac50fSopenharmony_ci    // calc doubleRect
279e0dac50fSopenharmony_ci    doubleTileRects_[0] = {x, y, w, h};
280e0dac50fSopenharmony_ci    doubleTileRects_[1] = {x + w + midInterval, y, w, h};
281e0dac50fSopenharmony_ci    WLOGI("doubleRects_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h);
282e0dac50fSopenharmony_ci    // calc tripleRect
283e0dac50fSopenharmony_ci    w = (limitDisplayRect_.width_ - edgeInterval * half - midInterval * half) / 3; // 3 is triple rects num
284e0dac50fSopenharmony_ci    tripleTileRects_[0] = {x, y, w, h};
285e0dac50fSopenharmony_ci    tripleTileRects_[1] = {x + w + midInterval, y, w, h};
286e0dac50fSopenharmony_ci    tripleTileRects_[2] = {x + w * half + midInterval * half, y, w, h}; // 2 is third index
287e0dac50fSopenharmony_ci    WLOGI("tripleRects_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h);
288e0dac50fSopenharmony_ci}
289e0dac50fSopenharmony_ci
290e0dac50fSopenharmony_cibool WindowTestUtils::RectEqualTo(const sptr<Window>& window, const Rect& r)
291e0dac50fSopenharmony_ci{
292e0dac50fSopenharmony_ci    usleep(100000); // 100000us
293e0dac50fSopenharmony_ci    Rect l = window->GetRect();
294e0dac50fSopenharmony_ci    bool res = ((l.posX_ == r.posX_) && (l.posY_ == r.posY_) && (l.width_ == r.width_) && (l.height_ == r.height_));
295e0dac50fSopenharmony_ci    if (!res) {
296e0dac50fSopenharmony_ci        WLOGFE("GetLayoutRect: %{public}d %{public}d %{public}d %{public}d, " \
297e0dac50fSopenharmony_ci            "Expect: %{public}d %{public}d %{public}d %{public}d", l.posX_, l.posY_, l.width_, l.height_,
298e0dac50fSopenharmony_ci            r.posX_, r.posY_, r.width_, r.height_);
299e0dac50fSopenharmony_ci    }
300e0dac50fSopenharmony_ci    return res;
301e0dac50fSopenharmony_ci}
302e0dac50fSopenharmony_ci
303e0dac50fSopenharmony_cibool WindowTestUtils::RectEqualToRect(const Rect& l, const Rect& r)
304e0dac50fSopenharmony_ci{
305e0dac50fSopenharmony_ci    bool res = ((l.posX_ == r.posX_) && (l.posY_ == r.posY_) && (l.width_ == r.width_) && (l.height_ == r.height_));
306e0dac50fSopenharmony_ci    if (!res) {
307e0dac50fSopenharmony_ci        WLOGFE("GetLayoutRect: %{public}d %{public}d %{public}d %{public}d, " \
308e0dac50fSopenharmony_ci            "Expect: %{public}d %{public}d %{public}d %{public}d", l.posX_, l.posY_, l.width_, l.height_,
309e0dac50fSopenharmony_ci            r.posX_, r.posY_, r.width_, r.height_);
310e0dac50fSopenharmony_ci    }
311e0dac50fSopenharmony_ci    return res;
312e0dac50fSopenharmony_ci}
313e0dac50fSopenharmony_ci
314e0dac50fSopenharmony_ciAvoidPosType WindowTestUtils::GetAvoidPosType(const Rect& rect)
315e0dac50fSopenharmony_ci{
316e0dac50fSopenharmony_ci    auto display = DisplayManager::GetInstance().GetDisplayById(0);
317e0dac50fSopenharmony_ci    if (display == nullptr) {
318e0dac50fSopenharmony_ci        WLOGFE("GetAvoidPosType fail. Get display fail. displayId: 0");
319e0dac50fSopenharmony_ci        return AvoidPosType::AVOID_POS_UNKNOWN;
320e0dac50fSopenharmony_ci    }
321e0dac50fSopenharmony_ci    auto displayInfo = display->GetDisplayInfo();
322e0dac50fSopenharmony_ci    Rect displayRect = {displayInfo->GetOffsetX(), displayInfo->GetOffsetY(), displayInfo->GetWidth(),
323e0dac50fSopenharmony_ci        displayInfo->GetHeight()};
324e0dac50fSopenharmony_ci    return WindowHelper::GetAvoidPosType(rect, displayRect);
325e0dac50fSopenharmony_ci}
326e0dac50fSopenharmony_ci
327e0dac50fSopenharmony_cibool WindowTestUtils::InitSplitRects()
328e0dac50fSopenharmony_ci{
329e0dac50fSopenharmony_ci    auto display = DisplayManager::GetInstance().GetDisplayById(0);
330e0dac50fSopenharmony_ci    if (display == nullptr) {
331e0dac50fSopenharmony_ci        WLOGFE("GetDefaultDisplay: failed!");
332e0dac50fSopenharmony_ci        return false;
333e0dac50fSopenharmony_ci    }
334e0dac50fSopenharmony_ci    WLOGI("GetDefaultDisplay: id %{public}" PRIu64", w %{public}d, h %{public}d, fps %{public}u",
335e0dac50fSopenharmony_ci        display->GetId(), display->GetWidth(), display->GetHeight(), display->GetRefreshRate());
336e0dac50fSopenharmony_ci
337e0dac50fSopenharmony_ci    Rect displayRect = {0, 0, display->GetWidth(), display->GetHeight()};
338e0dac50fSopenharmony_ci    displayRect_ = displayRect;
339e0dac50fSopenharmony_ci    limitDisplayRect_ = displayRect;
340e0dac50fSopenharmony_ci
341e0dac50fSopenharmony_ci    float virtualPixelRatio = WindowTestUtils::GetVirtualPixelRatio(0);
342e0dac50fSopenharmony_ci    uint32_t dividerWidth = static_cast<uint32_t>(DIVIDER_WIDTH * virtualPixelRatio);
343e0dac50fSopenharmony_ci
344e0dac50fSopenharmony_ci    if (displayRect_.width_ < displayRect_.height_) {
345e0dac50fSopenharmony_ci        isVerticalDisplay_ = true;
346e0dac50fSopenharmony_ci    }
347e0dac50fSopenharmony_ci    if (isVerticalDisplay_) {
348e0dac50fSopenharmony_ci        splitRects_.dividerRect = { 0,
349e0dac50fSopenharmony_ci                                    static_cast<uint32_t>((displayRect_.height_ - dividerWidth) * DEFAULT_SPLIT_RATIO),
350e0dac50fSopenharmony_ci                                    displayRect_.width_,
351e0dac50fSopenharmony_ci                                    dividerWidth, };
352e0dac50fSopenharmony_ci    } else {
353e0dac50fSopenharmony_ci        splitRects_.dividerRect = { static_cast<uint32_t>((displayRect_.width_ - dividerWidth) * DEFAULT_SPLIT_RATIO),
354e0dac50fSopenharmony_ci                                    0,
355e0dac50fSopenharmony_ci                                    dividerWidth,
356e0dac50fSopenharmony_ci                                    displayRect_.height_ };
357e0dac50fSopenharmony_ci    }
358e0dac50fSopenharmony_ci    return true;
359e0dac50fSopenharmony_ci}
360e0dac50fSopenharmony_ci
361e0dac50fSopenharmony_civoid WindowTestUtils::UpdateSplitRects(const sptr<Window>& window)
362e0dac50fSopenharmony_ci{
363e0dac50fSopenharmony_ci    std::unique_ptr<WindowTestUtils> testUtils = std::make_unique<WindowTestUtils>();
364e0dac50fSopenharmony_ci    testUtils->avoidArea_ = systemAvoidArea_;
365e0dac50fSopenharmony_ci    testUtils->UpdateLimitDisplayRect(testUtils->avoidArea_.leftRect_);
366e0dac50fSopenharmony_ci    testUtils->UpdateLimitDisplayRect(testUtils->avoidArea_.topRect_);
367e0dac50fSopenharmony_ci    testUtils->UpdateLimitDisplayRect(testUtils->avoidArea_.rightRect_);
368e0dac50fSopenharmony_ci    testUtils->UpdateLimitDisplayRect(testUtils->avoidArea_.bottomRect_);
369e0dac50fSopenharmony_ci
370e0dac50fSopenharmony_ci    if (isVerticalDisplay_) {
371e0dac50fSopenharmony_ci        splitRects_.dividerRect.posY_ = limitDisplayRect_.posY_ +
372e0dac50fSopenharmony_ci            static_cast<uint32_t>((limitDisplayRect_.height_ - splitRects_.dividerRect.height_) * DEFAULT_SPLIT_RATIO);
373e0dac50fSopenharmony_ci        testUtils->UpdateLimitSplitRects(splitRects_.dividerRect.posY_);
374e0dac50fSopenharmony_ci    } else {
375e0dac50fSopenharmony_ci        splitRects_.dividerRect.posX_ = limitDisplayRect_.posX_ +
376e0dac50fSopenharmony_ci            static_cast<uint32_t>((limitDisplayRect_.width_ - splitRects_.dividerRect.width_) * DEFAULT_SPLIT_RATIO);
377e0dac50fSopenharmony_ci        testUtils->UpdateLimitSplitRects(splitRects_.dividerRect.posX_);
378e0dac50fSopenharmony_ci    }
379e0dac50fSopenharmony_ci}
380e0dac50fSopenharmony_ci
381e0dac50fSopenharmony_civoid WindowTestUtils::UpdateLimitDisplayRect(const Rect& avoidRect)
382e0dac50fSopenharmony_ci{
383e0dac50fSopenharmony_ci    if (((avoidRect.posX_ == 0) && (avoidRect.posY_ == 0) &&
384e0dac50fSopenharmony_ci        (avoidRect.width_ == 0) && (avoidRect.height_ == 0))) {
385e0dac50fSopenharmony_ci        return;
386e0dac50fSopenharmony_ci    }
387e0dac50fSopenharmony_ci    auto avoidPosType = GetAvoidPosType(avoidRect);
388e0dac50fSopenharmony_ci    int32_t offsetH = 0;
389e0dac50fSopenharmony_ci    int32_t offsetW = 0;
390e0dac50fSopenharmony_ci    switch (avoidPosType) {
391e0dac50fSopenharmony_ci        case AvoidPosType::AVOID_POS_TOP:
392e0dac50fSopenharmony_ci            offsetH = avoidRect.posY_ + avoidRect.height_ - limitDisplayRect_.posY_;
393e0dac50fSopenharmony_ci            limitDisplayRect_.posY_ += offsetH;
394e0dac50fSopenharmony_ci            limitDisplayRect_.height_ -= offsetH;
395e0dac50fSopenharmony_ci            break;
396e0dac50fSopenharmony_ci        case AvoidPosType::AVOID_POS_BOTTOM:
397e0dac50fSopenharmony_ci            offsetH = limitDisplayRect_.posY_ + limitDisplayRect_.height_ - avoidRect.posY_;
398e0dac50fSopenharmony_ci            limitDisplayRect_.height_ -= offsetH;
399e0dac50fSopenharmony_ci            break;
400e0dac50fSopenharmony_ci        case AvoidPosType::AVOID_POS_LEFT:
401e0dac50fSopenharmony_ci            offsetW = avoidRect.posX_ + avoidRect.width_ - limitDisplayRect_.posX_;
402e0dac50fSopenharmony_ci            limitDisplayRect_.posX_ += offsetW;
403e0dac50fSopenharmony_ci            limitDisplayRect_.width_ -= offsetW;
404e0dac50fSopenharmony_ci            break;
405e0dac50fSopenharmony_ci        case AvoidPosType::AVOID_POS_RIGHT:
406e0dac50fSopenharmony_ci            offsetW = limitDisplayRect_.posX_ + limitDisplayRect_.width_ - avoidRect.posX_;
407e0dac50fSopenharmony_ci            limitDisplayRect_.width_ -= offsetW;
408e0dac50fSopenharmony_ci            break;
409e0dac50fSopenharmony_ci        default:
410e0dac50fSopenharmony_ci            WLOGFE("invalid avoidPosType: %{public}d", avoidPosType);
411e0dac50fSopenharmony_ci    }
412e0dac50fSopenharmony_ci}
413e0dac50fSopenharmony_ci
414e0dac50fSopenharmony_civoid WindowTestUtils::UpdateLimitSplitRects(int32_t divPos)
415e0dac50fSopenharmony_ci{
416e0dac50fSopenharmony_ci    std::unique_ptr<WindowTestUtils> testUtils = std::make_unique<WindowTestUtils>();
417e0dac50fSopenharmony_ci    if (isVerticalDisplay_) {
418e0dac50fSopenharmony_ci        splitRects_.dividerRect.posY_ = divPos;
419e0dac50fSopenharmony_ci
420e0dac50fSopenharmony_ci        splitRects_.primaryRect.posX_ = displayRect_.posX_;
421e0dac50fSopenharmony_ci        splitRects_.primaryRect.posY_ = displayRect_.posY_;
422e0dac50fSopenharmony_ci        splitRects_.primaryRect.height_ = divPos;
423e0dac50fSopenharmony_ci        splitRects_.primaryRect.width_ = displayRect_.width_;
424e0dac50fSopenharmony_ci
425e0dac50fSopenharmony_ci        splitRects_.secondaryRect.posX_ = displayRect_.posX_;
426e0dac50fSopenharmony_ci        splitRects_.secondaryRect.posY_ = splitRects_.dividerRect.posY_ + splitRects_.dividerRect.height_;
427e0dac50fSopenharmony_ci        splitRects_.secondaryRect.height_ = displayRect_.height_ - splitRects_.secondaryRect.posY_;
428e0dac50fSopenharmony_ci        splitRects_.secondaryRect.width_ = displayRect_.width_;
429e0dac50fSopenharmony_ci    } else {
430e0dac50fSopenharmony_ci        splitRects_.dividerRect.posX_ = divPos;
431e0dac50fSopenharmony_ci
432e0dac50fSopenharmony_ci        splitRects_.primaryRect.posX_ = displayRect_.posX_;
433e0dac50fSopenharmony_ci        splitRects_.primaryRect.posY_ = displayRect_.posY_;
434e0dac50fSopenharmony_ci        splitRects_.primaryRect.width_ = divPos;
435e0dac50fSopenharmony_ci        splitRects_.primaryRect.height_ = displayRect_.height_;
436e0dac50fSopenharmony_ci
437e0dac50fSopenharmony_ci        splitRects_.secondaryRect.posX_ = splitRects_.dividerRect.posX_ + splitRects_.dividerRect.width_;
438e0dac50fSopenharmony_ci        splitRects_.secondaryRect.posY_ = displayRect_.posY_;
439e0dac50fSopenharmony_ci        splitRects_.secondaryRect.width_ = displayRect_.width_ - splitRects_.secondaryRect.posX_;
440e0dac50fSopenharmony_ci        splitRects_.secondaryRect.height_ = displayRect_.height_;
441e0dac50fSopenharmony_ci    }
442e0dac50fSopenharmony_ci
443e0dac50fSopenharmony_ci    testUtils->UpdateLimitSplitRect(splitRects_.primaryRect);
444e0dac50fSopenharmony_ci    testUtils->UpdateLimitSplitRect(splitRects_.secondaryRect);
445e0dac50fSopenharmony_ci}
446e0dac50fSopenharmony_ci
447e0dac50fSopenharmony_civoid WindowTestUtils::UpdateLimitSplitRect(Rect& limitSplitRect)
448e0dac50fSopenharmony_ci{
449e0dac50fSopenharmony_ci    Rect curLimitRect = limitSplitRect;
450e0dac50fSopenharmony_ci    limitSplitRect.posX_ = std::max(limitDisplayRect_.posX_, curLimitRect.posX_);
451e0dac50fSopenharmony_ci    limitSplitRect.posY_ = std::max(limitDisplayRect_.posY_, curLimitRect.posY_);
452e0dac50fSopenharmony_ci    limitSplitRect.width_ = std::min(limitDisplayRect_.posX_ + limitDisplayRect_.width_,
453e0dac50fSopenharmony_ci                                     curLimitRect.posX_ + curLimitRect.width_) -
454e0dac50fSopenharmony_ci                                     limitSplitRect.posX_;
455e0dac50fSopenharmony_ci    limitSplitRect.height_ = std::min(limitDisplayRect_.posY_ + limitDisplayRect_.height_,
456e0dac50fSopenharmony_ci                                      curLimitRect.posY_ + curLimitRect.height_) -
457e0dac50fSopenharmony_ci                                      limitSplitRect.posY_;
458e0dac50fSopenharmony_ci}
459e0dac50fSopenharmony_ci
460e0dac50fSopenharmony_cifloat WindowTestUtils::GetVirtualPixelRatio(DisplayId displayId)
461e0dac50fSopenharmony_ci{
462e0dac50fSopenharmony_ci    auto display = DisplayManager::GetInstance().GetDisplayById(displayId);
463e0dac50fSopenharmony_ci    if (display == nullptr) {
464e0dac50fSopenharmony_ci        WLOGFE("GetVirtualPixel fail. Get display fail. displayId:%{public}" PRIu64", use Default vpr:1.0", displayId);
465e0dac50fSopenharmony_ci        return 1.0;  // Use DefaultVPR 1.0
466e0dac50fSopenharmony_ci    }
467e0dac50fSopenharmony_ci
468e0dac50fSopenharmony_ci    float virtualPixelRatio = display->GetVirtualPixelRatio();
469e0dac50fSopenharmony_ci    if (virtualPixelRatio == 0.0) {
470e0dac50fSopenharmony_ci        WLOGFE("GetVirtualPixel fail. vpr is 0.0. displayId:%{public}" PRIu64", use Default vpr:1.0", displayId);
471e0dac50fSopenharmony_ci        return 1.0;  // Use DefaultVPR 1.0
472e0dac50fSopenharmony_ci    }
473e0dac50fSopenharmony_ci
474e0dac50fSopenharmony_ci    WLOGI("GetVirtualPixel success. displayId:%{public}" PRIu64", vpr:%{public}f", displayId, virtualPixelRatio);
475e0dac50fSopenharmony_ci    return virtualPixelRatio;
476e0dac50fSopenharmony_ci}
477e0dac50fSopenharmony_ci} // namespace ROSEN
478e0dac50fSopenharmony_ci} // namespace OHOS
479