1 /*
2 * Copyright (c) 2021-2022 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 // gtest
17 #include <gtest/gtest.h>
18 #include "window_manager.h"
19 #include "window_test_utils.h"
20 using namespace testing;
21 using namespace testing::ext;
22
23 namespace OHOS {
24 namespace Rosen {
25 using utils = WindowTestUtils;
26 class WindowLayoutTest : public testing::Test {
27 public:
28 static void SetUpTestCase();
29 static void TearDownTestCase();
30 virtual void SetUp() override;
31 virtual void TearDown() override;
32 DisplayId displayId_ = 0;
33 std::vector<sptr<Window>> activeWindows_;
34 static vector<Rect> fullScreenExpecteds_;
35 static inline float virtualPixelRatio_ = 0.0;
36 };
37
38 vector<Rect> WindowLayoutTest::fullScreenExpecteds_;
39
SetUpTestCase()40 void WindowLayoutTest::SetUpTestCase()
41 {
42 auto display = DisplayManager::GetInstance().GetDisplayById(0);
43 ASSERT_TRUE((display != nullptr));
44 printf("GetDefaultDisplay: id %llu, w %d, h %d, fps %u\n", display->GetId(), display->GetWidth(),
45 display->GetHeight(), display->GetRefreshRate());
46 Rect displayRect = {0, 0, display->GetWidth(), display->GetHeight()};
47 utils::InitByDisplayRect(displayRect);
48
49 virtualPixelRatio_ = WindowTestUtils::GetVirtualPixelRatio(0);
50
51 // calc expected rects
52 Rect expected = { // 0. only statusBar
53 0,
54 utils::statusBarRect_.height_,
55 utils::displayRect_.width_,
56 utils::displayRect_.height_ - utils::statusBarRect_.height_,
57 };
58 fullScreenExpecteds_.push_back(expected);
59 expected = { // 1. both statusBar and naviBar
60 0,
61 utils::statusBarRect_.height_,
62 utils::displayRect_.width_,
63 utils::displayRect_.height_ - utils::statusBarRect_.height_ - utils::naviBarRect_.height_,
64 };
65 fullScreenExpecteds_.push_back(expected);
66 expected = { // 2. only naviBar
67 0,
68 0,
69 utils::displayRect_.width_,
70 utils::displayRect_.height_ - utils::naviBarRect_.height_,
71 };
72 fullScreenExpecteds_.push_back(expected);
73 }
74
TearDownTestCase()75 void WindowLayoutTest::TearDownTestCase()
76 {
77 }
78
SetUp()79 void WindowLayoutTest::SetUp()
80 {
81 activeWindows_.clear();
82 }
83
TearDown()84 void WindowLayoutTest::TearDown()
85 {
86 while (!activeWindows_.empty()) {
87 ASSERT_EQ(WMError::WM_OK, activeWindows_.back()->Destroy());
88 activeWindows_.pop_back();
89 }
90 }
91
92 namespace {
93 /**
94 * @tc.name: LayoutWindow01
95 * @tc.desc: One FLOATING APP Window with on custom rect
96 * @tc.type: FUNC
97 */
98 HWTEST_F(WindowLayoutTest, LayoutWindow01, Function | MediumTest | Level3)
99 {
100 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::TILE, displayId_);
101 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_);
102 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::TILE, displayId_);
103 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_);
104
105 utils::TestWindowInfo info = {
106 .name = "main",
107 .rect = {0, 0, 0, 0},
108 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
109 .mode = WindowMode::WINDOW_MODE_FLOATING,
110 .needAvoid = true,
111 .parentLimit = false,
112 .parentName = "",
113 };
114 const sptr<Window>& window = utils::CreateTestWindow(info);
115 activeWindows_.push_back(window);
116 Rect expect = utils::GetDefaultFoatingRect(window);
117 ASSERT_EQ(WMError::WM_OK, window->Show());
118 ASSERT_TRUE(utils::RectEqualTo(window, expect));
119 ASSERT_EQ(WMError::WM_OK, window->Hide());
120 }
121
122 /**
123 * @tc.name: LayoutWindow02
124 * @tc.desc: One FLOATING APP Window
125 * @tc.type: FUNC
126 */
127 HWTEST_F(WindowLayoutTest, LayoutWindow02, Function | MediumTest | Level3)
128 {
129 utils::TestWindowInfo info = {
130 .name = "main",
131 .rect = utils::customAppRect_,
132 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
133 .mode = WindowMode::WINDOW_MODE_FLOATING,
134 .needAvoid = true,
135 .parentLimit = false,
136 .parentName = "",
137 };
138 const sptr<Window>& window = utils::CreateTestWindow(info);
139 activeWindows_.push_back(window);
140
141 ASSERT_EQ(WMError::WM_OK, window->Show());
142 ASSERT_TRUE(utils::RectEqualTo(window, utils::GetFloatingLimitedRect(utils::customAppRect_, virtualPixelRatio_)));
143 ASSERT_EQ(WMError::WM_OK, window->Hide());
144 }
145
146 /**
147 * @tc.name: LayoutWindow04
148 * @tc.desc: One FLOATING APP Window & One StatusBar Window
149 * @tc.type: FUNC
150 */
151 HWTEST_F(WindowLayoutTest, LayoutWindow04, Function | MediumTest | Level3)
152 {
153 // app window
154 utils::TestWindowInfo info = {
155 .name = "main",
156 .rect = utils::customAppRect_,
157 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
158 .mode = WindowMode::WINDOW_MODE_FLOATING,
159 .needAvoid = true,
160 .parentLimit = false,
161 .parentName = "",
162 };
163 sptr<Window> appWin = utils::CreateTestWindow(info);
164 activeWindows_.push_back(appWin);
165
166 // statusBar window
167 sptr<Window> statBar = utils::CreateStatusBarWindow();
168 activeWindows_.push_back(statBar);
169
170 ASSERT_EQ(WMError::WM_OK, appWin->Show());
171 ASSERT_TRUE(utils::RectEqualTo(appWin, utils::GetFloatingLimitedRect(utils::customAppRect_, virtualPixelRatio_)));
172 ASSERT_EQ(WMError::WM_OK, statBar->Show());
173 ASSERT_TRUE(utils::RectEqualTo(appWin, utils::GetFloatingLimitedRect(utils::customAppRect_, virtualPixelRatio_)));
174 ASSERT_TRUE(utils::RectEqualTo(statBar, utils::statusBarRect_));
175 ASSERT_EQ(WMError::WM_OK, statBar->Hide());
176 ASSERT_TRUE(utils::RectEqualTo(appWin, utils::GetFloatingLimitedRect(utils::customAppRect_, virtualPixelRatio_)));
177 }
178
179 /**
180 * @tc.name: LayoutWindow06
181 * @tc.desc: StatusBar Window and NaviBar & Sys Window FULLSCRENN,NOT NEEDVOID,PARENTLIMIT
182 * @tc.type: FUNC
183 */
184 HWTEST_F(WindowLayoutTest, LayoutWindow06, Function | MediumTest | Level3)
185 {
186 // statusBar window
187 sptr<Window> statBar = utils::CreateStatusBarWindow();
188 activeWindows_.push_back(statBar);
189
190 // naviBar window
191 sptr<Window> naviBar = utils::CreateNavigationBarWindow();
192 activeWindows_.push_back(naviBar);
193
194 // sys window
195 utils::TestWindowInfo info = {
196 .name = "main",
197 .rect = utils::customAppRect_,
198 .type = WindowType::WINDOW_TYPE_PANEL,
199 .mode = WindowMode::WINDOW_MODE_FULLSCREEN,
200 .needAvoid = false,
201 .parentLimit = true,
202 .parentName = "",
203 };
204 sptr<Window> sysWin = utils::CreateTestWindow(info);
205 activeWindows_.push_back(sysWin);
206
207 ASSERT_EQ(WMError::WM_OK, statBar->Show());
208 ASSERT_TRUE(utils::RectEqualTo(statBar, utils::statusBarRect_));
209 ASSERT_EQ(WMError::WM_OK, sysWin->Show());
210 ASSERT_TRUE(utils::RectEqualTo(sysWin, utils::displayRect_));
211 ASSERT_EQ(WMError::WM_OK, naviBar->Show());
212 ASSERT_TRUE(utils::RectEqualTo(sysWin, utils::displayRect_));
213 ASSERT_EQ(WMError::WM_OK, statBar->Hide());
214 ASSERT_TRUE(utils::RectEqualTo(sysWin, utils::displayRect_));
215 }
216
217 /**
218 * @tc.name: LayoutWindow07
219 * @tc.desc: StatusBar Window and NaviBar & One Floating Sys Window
220 * @tc.type: FUNC
221 */
222 HWTEST_F(WindowLayoutTest, LayoutWindow07, Function | MediumTest | Level3)
223 {
224 // statusBar window
225 sptr<Window> statBar = utils::CreateStatusBarWindow();
226 activeWindows_.push_back(statBar);
227
228 // naviBar window
229 sptr<Window> naviBar = utils::CreateNavigationBarWindow();
230 activeWindows_.push_back(naviBar);
231
232 // sys window
233 utils::TestWindowInfo info = {
234 .name = "main",
235 .rect = utils::customAppRect_,
236 .type = WindowType::WINDOW_TYPE_PANEL,
237 .mode = WindowMode::WINDOW_MODE_FLOATING,
238 .needAvoid = false,
239 .parentLimit = true,
240 .parentName = "",
241 };
242 sptr<Window> sysWin = utils::CreateTestWindow(info);
243 activeWindows_.push_back(sysWin);
244
245 ASSERT_EQ(WMError::WM_OK, statBar->Show());
246 ASSERT_TRUE(utils::RectEqualTo(statBar, utils::statusBarRect_));
247 ASSERT_EQ(WMError::WM_OK, sysWin->Show());
248 ASSERT_TRUE(utils::RectEqualTo(sysWin, utils::customAppRect_));
249 ASSERT_EQ(WMError::WM_OK, naviBar->Show());
250 ASSERT_TRUE(utils::RectEqualTo(sysWin, utils::customAppRect_));
251 ASSERT_EQ(WMError::WM_OK, statBar->Hide());
252 ASSERT_TRUE(utils::RectEqualTo(sysWin, utils::customAppRect_));
253 }
254
255 /**
256 * @tc.name: LayoutWindow08
257 * @tc.desc: One FLOATING APP Window with on custom rect
258 * @tc.type: FUNC
259 */
260 HWTEST_F(WindowLayoutTest, LayoutWindow08, Function | MediumTest | Level3)
261 {
262 utils::TestWindowInfo info = {
263 .name = "main",
264 .rect = {0, 0, 0, 0},
265 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
266 .mode = WindowMode::WINDOW_MODE_FLOATING,
267 .needAvoid = true,
268 .parentLimit = false,
269 .parentName = "",
270 };
271 const sptr<Window>& window = utils::CreateTestWindow(info);
272 activeWindows_.push_back(window);
273 Rect expect = utils::GetDefaultFoatingRect(window);
274 ASSERT_EQ(WMError::WM_OK, window->Show());
275 ASSERT_TRUE(utils::RectEqualTo(window, expect));
276 ASSERT_EQ(WMError::WM_OK, window->Hide());
277 }
278
279 /**
280 * @tc.name: LayoutWindow09
281 * @tc.desc: Add a floating and resize(2, 2)
282 * @tc.type: FUNC
283 */
284 HWTEST_F(WindowLayoutTest, LayoutWindow09, Function | MediumTest | Level3)
285 {
286 utils::TestWindowInfo info = {
287 .name = "main",
288 .rect = {0, 0, 0, 0},
289 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
290 .mode = WindowMode::WINDOW_MODE_FLOATING,
291 .needAvoid = true,
292 .parentLimit = false,
293 .parentName = "",
294 };
295 const sptr<Window>& window = utils::CreateTestWindow(info);
296 activeWindows_.push_back(window);
297 Rect expect = utils::GetDefaultFoatingRect(window);
298
299 ASSERT_EQ(WMError::WM_OK, window->Show());
300 ASSERT_TRUE(utils::RectEqualTo(window, expect));
301
302 ASSERT_EQ(WMError::WM_OK, window->Resize(2u, 2u)); // 2: custom min size
303 Rect finalExcept = { expect.posX_, expect.posY_, 2u, 2u}; // 2: custom min size
304 finalExcept = utils::GetFloatingLimitedRect(finalExcept, virtualPixelRatio_);
305 ASSERT_TRUE(utils::RectEqualTo(window, finalExcept));
306 ASSERT_EQ(WMError::WM_OK, window->Hide());
307 }
308
309 /**
310 * @tc.name: LayoutWindow10
311 * @tc.desc: One FLOATING APP Window do max and recovery
312 * @tc.type: FUNC
313 */
314 HWTEST_F(WindowLayoutTest, LayoutWindow10, Function | MediumTest | Level3)
315 {
316 utils::TestWindowInfo info = {
317 .name = "main",
318 .rect = {0, 0, 0, 0},
319 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
320 .mode = WindowMode::WINDOW_MODE_FLOATING,
321 .needAvoid = true,
322 .parentLimit = false,
323 .parentName = "",
324 };
325 const sptr<Window>& window = utils::CreateTestWindow(info);
326 activeWindows_.push_back(window);
327 Rect expect = utils::GetDefaultFoatingRect(window);
328 ASSERT_EQ(WMError::WM_OK, window->Show());
329 ASSERT_TRUE(utils::RectEqualTo(window, expect));
330 ASSERT_EQ(WMError::WM_OK, window->Maximize());
331 ASSERT_TRUE(utils::RectEqualTo(window, utils::displayRect_));
332 ASSERT_EQ(WMError::WM_OK, window->Recover());
333 ASSERT_TRUE(utils::RectEqualTo(window, expect));
334 ASSERT_EQ(WMError::WM_OK, window->Minimize());
335 ASSERT_EQ(WMError::WM_OK, window->Close());
336 }
337
338 /**
339 * @tc.name: LayoutTile01
340 * @tc.desc: One FLOATING APP Window into tile mode, show 4 new window
341 * @tc.type: FUNC
342 */
343 HWTEST_F(WindowLayoutTest, LayoutTile01, Function | MediumTest | Level3)
344 {
345 utils::TestWindowInfo info = {
346 .name = "main",
347 .rect = {0, 0, 0, 0},
348 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
349 .mode = WindowMode::WINDOW_MODE_FLOATING,
350 .needAvoid = true,
351 .parentLimit = false,
352 .parentName = "",
353 };
354 const sptr<Window>& window = utils::CreateTestWindow(info);
355 activeWindows_.push_back(window);
356 Rect expect = utils::GetDefaultFoatingRect(window);
357 ASSERT_EQ(WMError::WM_OK, window->Show());
358 utils::InitTileWindowRects(window);
359 ASSERT_TRUE(utils::RectEqualTo(window, expect));
360 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::TILE, displayId_);
361 ASSERT_TRUE(utils::RectEqualTo(window, utils::singleTileRect_));
362 info.name = "test1";
363 const sptr<Window>& test1 = utils::CreateTestWindow(info);
364 activeWindows_.push_back(test1);
365 ASSERT_EQ(WMError::WM_OK, test1->Show());
366 ASSERT_TRUE(utils::RectEqualTo(window, utils::doubleTileRects_[0]));
367 ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[1]));
368 info.name = "test2";
369 const sptr<Window>& test2 = utils::CreateTestWindow(info);
370 activeWindows_.push_back(test2);
371 ASSERT_EQ(WMError::WM_OK, test2->Show());
372 if (utils::isVerticalDisplay_) {
373 ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[0]));
374 ASSERT_TRUE(utils::RectEqualTo(test2, utils::doubleTileRects_[1]));
375 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_);
376 return;
377 } else {
378 ASSERT_TRUE(utils::RectEqualTo(window, utils::tripleTileRects_[0]));
379 ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[1]));
380 ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[2])); // 2 is second rect idx
381 }
382 info.name = "test3";
383 const sptr<Window>& test3 = utils::CreateTestWindow(info);
384 activeWindows_.push_back(test3);
385 ASSERT_EQ(WMError::WM_OK, test3->Show());
386 ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[0]));
387 ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[1]));
388 ASSERT_TRUE(utils::RectEqualTo(test3, utils::tripleTileRects_[2])); // 2 is second rect idx
389 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_);
390 }
391
392 /**
393 * @tc.name: LayoutTileNegative01
394 * @tc.desc: negative test for tile window
395 * @tc.type: FUNC
396 */
397 HWTEST_F(WindowLayoutTest, LayoutTileNegative01, Function | MediumTest | Level3)
398 {
399 utils::TestWindowInfo info = {
400 .name = "main",
401 .rect = {-1, -100, -1, -100}, // -1, -100, -1, -100 is typical negative case nums
402 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
403 .mode = WindowMode::WINDOW_MODE_FLOATING,
404 .needAvoid = true,
405 .parentLimit = false,
406 .parentName = "",
407 };
408 const sptr<Window>& window = utils::CreateTestWindow(info);
409 activeWindows_.push_back(window);
410 ASSERT_EQ(WMError::WM_OK, window->Show());
411 utils::InitTileWindowRects(window);
412 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::TILE, displayId_);
413 ASSERT_TRUE(utils::RectEqualTo(window, utils::singleTileRect_));
414 info.name = "test1";
415 const sptr<Window>& test1 = utils::CreateTestWindow(info);
416 activeWindows_.push_back(test1);
417 ASSERT_EQ(WMError::WM_OK, test1->Show());
418 ASSERT_TRUE(utils::RectEqualTo(window, utils::doubleTileRects_[0]));
419 ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[1]));
420 info.name = "test2";
421 const sptr<Window>& test2 = utils::CreateTestWindow(info);
422 activeWindows_.push_back(test2);
423 ASSERT_EQ(WMError::WM_OK, test2->Show());
424 if (utils::isVerticalDisplay_) {
425 ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[0]));
426 ASSERT_TRUE(utils::RectEqualTo(test2, utils::doubleTileRects_[1]));
427 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_);
428 return;
429 } else {
430 ASSERT_TRUE(utils::RectEqualTo(window, utils::tripleTileRects_[0]));
431 ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[1]));
432 ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[2])); // 2 is second rect idx
433 }
434 info.name = "test3";
435 const sptr<Window>& test3 = utils::CreateTestWindow(info);
436 activeWindows_.push_back(test3);
437 ASSERT_EQ(WMError::WM_OK, test3->Show());
438 ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[0]));
439 ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[1]));
440 ASSERT_TRUE(utils::RectEqualTo(test3, utils::tripleTileRects_[2])); // 2 is second rect idx
441 WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_);
442 }
443
444 /**
445 * @tc.name: LayoutTileNegative01
446 * @tc.desc: move window out of the display
447 * @tc.type: FUNC
448 */
449 HWTEST_F(WindowLayoutTest, LayoutNegative01, Function | MediumTest | Level3)
450 {
451 utils::TestWindowInfo info = {
452 .name = "main",
453 .rect = {0, 0, 0, 0},
454 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
455 .mode = WindowMode::WINDOW_MODE_FLOATING,
456 .needAvoid = true,
457 .parentLimit = false,
458 .parentName = "",
459 };
460 const sptr<Window>& window = utils::CreateTestWindow(info);
461 activeWindows_.push_back(window);
462 Rect expect = utils::GetDefaultFoatingRect(window);
463 ASSERT_EQ(WMError::WM_OK, window->Show());
464 ASSERT_TRUE(utils::RectEqualTo(window, expect));
465 }
466
467 /**
468 * @tc.name: LayoutNegative02
469 * @tc.desc: resize window to negative size
470 * @tc.type: FUNC
471 */
472 HWTEST_F(WindowLayoutTest, LayoutNegative02, Function | MediumTest | Level3)
473 {
474 const uint32_t negativeW = 0;
475 const uint32_t negativeH = 0;
476 utils::TestWindowInfo info = {
477 .name = "main",
478 .rect = {0, 0, 0, 0},
479 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
480 .mode = WindowMode::WINDOW_MODE_FLOATING,
481 .needAvoid = true,
482 .parentLimit = false,
483 .parentName = "",
484 };
485 const sptr<Window>& window = utils::CreateTestWindow(info);
486 activeWindows_.push_back(window);
487 Rect expect = utils::GetDefaultFoatingRect(window);
488 ASSERT_EQ(WMError::WM_OK, window->Show());
489 ASSERT_TRUE(utils::RectEqualTo(window, expect));
490 window->Resize(negativeW, negativeH);
491 Rect expect2 = {expect.posX_, expect.posY_, negativeW, negativeH};
492 expect2 = utils::CalcLimitedRect(expect2, virtualPixelRatio_);
493 ASSERT_TRUE(utils::RectEqualTo(window, expect2));
494 }
495 }
496 } // namespace Rosen
497 } // namespace OHOS
498