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