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 #include "wm_common.h"
21 using namespace testing;
22 using namespace testing::ext;
23
24 namespace OHOS {
25 namespace Rosen {
26 namespace {
27 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowImmersiveTest"};
28
29 const Rect SYS_BAR_REGION_NULL = { 0, 0, 0, 0 };
30 const SystemBarProperty SYS_BAR_PROP_DEFAULT;
31 const SystemBarProperty SYS_BAR_PROP_1(true, 0xE5111111, 0xE5222222);
32 const SystemBarProperty SYS_BAR_PROP_2(false, 0xE5222222, 0xE5333333);
33 const SystemBarProperty SYS_BAR_PROP_3(false, 0xE5333333, 0xE5444444);
34 const SystemBarProperty SYS_BAR_PROP_4(true, 0xE5444444, 0x66555555);
35 const SystemBarRegionTints TEST_PROPS_DEFAULT = {
36 { WindowType::WINDOW_TYPE_STATUS_BAR, SYS_BAR_PROP_DEFAULT, SYS_BAR_REGION_NULL },
37 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SYS_BAR_PROP_DEFAULT, SYS_BAR_REGION_NULL },
38 };
39 const SystemBarRegionTints TEST_PROPS_1 = {
40 { WindowType::WINDOW_TYPE_STATUS_BAR, SYS_BAR_PROP_1, SYS_BAR_REGION_NULL },
41 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SYS_BAR_PROP_2, SYS_BAR_REGION_NULL },
42 };
43 const SystemBarRegionTints TEST_PROPS_2 = {
44 { WindowType::WINDOW_TYPE_STATUS_BAR, SYS_BAR_PROP_1, SYS_BAR_REGION_NULL },
45 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SYS_BAR_PROP_3, SYS_BAR_REGION_NULL },
46 };
47
48 const Rect EMPTY_RECT = {0, 0, 0, 0};
49 const float RATIO = 0.3;
50 }
51
52 using Utils = WindowTestUtils;
53 const int WAIT_ASYNC_US = 100000; // 100000us
54
55 class TestSystemBarChangedListener : public ISystemBarChangedListener {
56 public:
57 SystemBarRegionTints tints_ = TEST_PROPS_DEFAULT;
58 void OnSystemBarPropertyChange(DisplayId displayId, const SystemBarRegionTints& tints) override;
59 };
60
61 class TestAvoidAreaChangedListener : public IAvoidAreaChangedListener {
62 public:
63 AvoidArea avoidArea_;
64 void OnAvoidAreaChanged(const AvoidArea avoidArea, AvoidAreaType type) override;
65 };
66
67 class WindowImmersiveTest : public testing::Test {
68 public:
69 static void SetUpTestCase();
70 static void TearDownTestCase();
71 virtual void SetUp() override;
72 virtual void TearDown() override;
73 void SetWindowSystemProps(const sptr<Window>& window, const SystemBarRegionTints& props);
74 bool SystemBarPropsEqualsTo(const SystemBarRegionTints& expect);
75 void DumpFailedInfo(const SystemBarRegionTints& expect);
76 void DumpFailedInfo(bool expectStatus, bool expectNav);
77 bool SystemBarEnableState(bool expectStatus, bool expectNav);
78 DisplayId displayId_ = 0;
79 std::vector<sptr<Window>> activeWindows_;
80 static vector<Rect> fullScreenExpecteds_;
81 static sptr<TestSystemBarChangedListener> testSystemBarChangedListener_;
82 static sptr<TestAvoidAreaChangedListener> testAvoidAreaChangedListener_;
83 Utils::TestWindowInfo fullScreenAppinfo_;
84 Utils::TestWindowInfo avoidBarInfo_;
85 uint32_t leftAvoidW_;
86 uint32_t leftAvoidH_;
87 uint32_t topAvoidW_;
88 uint32_t topAvoidH_;
89 sptr<Window> backgroundWindow_;
90 };
91
92 vector<Rect> WindowImmersiveTest::fullScreenExpecteds_;
93 sptr<TestSystemBarChangedListener> WindowImmersiveTest::testSystemBarChangedListener_ =
94 new TestSystemBarChangedListener();
95 sptr<TestAvoidAreaChangedListener> WindowImmersiveTest::testAvoidAreaChangedListener_ =
96 new TestAvoidAreaChangedListener();
97
SetWindowSystemProps(const sptr<Window> & window,const SystemBarRegionTints & tints)98 void WindowImmersiveTest::SetWindowSystemProps(const sptr<Window>& window, const SystemBarRegionTints& tints)
99 {
100 for (auto tint : tints) {
101 window->SetSystemBarProperty(tint.type_, tint.prop_);
102 }
103 }
104
DumpFailedInfo(const SystemBarRegionTints & expect)105 void WindowImmersiveTest::DumpFailedInfo(const SystemBarRegionTints& expect)
106 {
107 auto act = testSystemBarChangedListener_->tints_;
108 WLOGI("WindowImmersiveTest Expected:");
109 for (auto tint : expect) {
110 WLOGI("WindowType: %{public}4d, Enable: %{public}4d, Color: %{public}x | %{public}x",
111 static_cast<uint32_t>(tint.type_), tint.prop_.enable_,
112 tint.prop_.backgroundColor_, tint.prop_.contentColor_);
113 }
114 WLOGI("WindowImmersiveTest Act: ");
115 for (auto tint : act) {
116 WLOGI("WindowType: %{public}4d, Enable: %{public}4d, Color: %{public}x | %{public}x",
117 static_cast<uint32_t>(tint.type_), tint.prop_.enable_,
118 tint.prop_.backgroundColor_, tint.prop_.contentColor_);
119 }
120 }
121
DumpFailedInfo(bool expectStatus,bool expectNav)122 void WindowImmersiveTest::DumpFailedInfo(bool expectStatus, bool expectNav)
123 {
124 auto act = testSystemBarChangedListener_->tints_;
125 WLOGI("WindowImmersiveTest Expected:");
126 WLOGI("expectStatus: %{public}4d, expectNav: %{public}4d", expectStatus, expectNav);
127 WLOGI("WindowImmersiveTest Act: ");
128 for (auto tint : act) {
129 WLOGI("WindowType: %{public}4d, Enable: %{public}4d, Color: %{public}x | %{public}x",
130 static_cast<uint32_t>(tint.type_), tint.prop_.enable_,
131 tint.prop_.backgroundColor_, tint.prop_.contentColor_);
132 }
133 }
134
SystemBarPropsEqualsTo(const SystemBarRegionTints & expect)135 bool WindowImmersiveTest::SystemBarPropsEqualsTo(const SystemBarRegionTints& expect)
136 {
137 usleep(WAIT_ASYNC_US);
138 auto act = testSystemBarChangedListener_->tints_;
139 if (act.size() != expect.size()) {
140 DumpFailedInfo(expect);
141 return false;
142 }
143 for (auto item : expect) {
144 bool check = false;
145 for (auto tint : act) {
146 if (item.prop_ == tint.prop_ && item.type_ == tint.type_) {
147 check = true;
148 break;
149 }
150 }
151 if (!check) {
152 DumpFailedInfo(expect);
153 return false;
154 }
155 check = false;
156 }
157 return true;
158 }
159
SystemBarEnableState(bool expectStatus,bool expectNav)160 bool WindowImmersiveTest::SystemBarEnableState(bool expectStatus, bool expectNav)
161 {
162 usleep(WAIT_ASYNC_US);
163 auto act = testSystemBarChangedListener_->tints_;
164 bool check = false;
165 for (auto tint : act) {
166 if ((tint.type_ == WindowType::WINDOW_TYPE_STATUS_BAR && tint.prop_.enable_ == expectStatus)
167 || (tint.type_ == WindowType::WINDOW_TYPE_NAVIGATION_BAR && tint.prop_.enable_ == expectNav)) {
168 check = true;
169 } else {
170 check = false;
171 }
172 }
173 if (!check) {
174 DumpFailedInfo(expectStatus, expectNav);
175 }
176 return check;
177 }
178
OnSystemBarPropertyChange(DisplayId displayId,const SystemBarRegionTints & tints)179 void TestSystemBarChangedListener::OnSystemBarPropertyChange(DisplayId displayId, const SystemBarRegionTints& tints)
180 {
181 WLOGI("TestSystemBarChangedListener Display ID: %{public}" PRIu64"", displayId);
182 WLOGI("TestSystemBarChangedListener tints size: %{public}zu", tints.size());
183 for (auto tint : tints) {
184 auto type = tint.type_;
185 for (uint32_t i = 0; i < tints_.size(); i++) {
186 if (tints_[i].type_ == type) {
187 tints_[i] = tint;
188 }
189 }
190 }
191 }
192
OnAvoidAreaChanged(const AvoidArea avoidArea,AvoidAreaType type)193 void TestAvoidAreaChangedListener::OnAvoidAreaChanged(const AvoidArea avoidArea, AvoidAreaType type)
194 {
195 avoidArea_ = avoidArea;
196 }
197
SetUpTestCase()198 void WindowImmersiveTest::SetUpTestCase()
199 {
200 auto display = DisplayManager::GetInstance().GetDisplayById(0);
201 ASSERT_TRUE((display != nullptr));
202 WLOGI("GetDefaultDisplay: id %{public}" PRIu64", w %{public}d, h %{public}d, fps %{public}u",
203 display->GetId(), display->GetWidth(), display->GetHeight(), display->GetRefreshRate());
204 Rect displayRect = {0, 0, display->GetWidth(), display->GetHeight()};
205 Utils::InitByDisplayRect(displayRect);
206 }
207
TearDownTestCase()208 void WindowImmersiveTest::TearDownTestCase()
209 {
210 }
211
SetUp()212 void WindowImmersiveTest::SetUp()
213 {
214 fullScreenAppinfo_ = {
215 .name = "main",
216 .rect = Utils::customAppRect_,
217 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
218 .mode = WindowMode::WINDOW_MODE_FULLSCREEN, // immersive setting
219 .needAvoid = false, // immersive setting
220 .parentLimit = false,
221 .parentId = INVALID_WINDOW_ID,
222 };
223 avoidBarInfo_ = {
224 .name = "LeftAvoidTest",
225 .rect = EMPTY_RECT,
226 .type = WindowType::WINDOW_TYPE_STATUS_BAR,
227 .mode = WindowMode::WINDOW_MODE_FLOATING,
228 };
229 // makesure left avoid win w < h
230 leftAvoidW_ = std::min(Utils::displayRect_.width_, static_cast<uint32_t>(Utils::displayRect_.height_ * RATIO));
231 leftAvoidH_ = Utils::displayRect_.height_;
232 // makesure top avoid win h < w
233 topAvoidW_ = Utils::displayRect_.width_;
234 topAvoidH_ = std::min(Utils::displayRect_.height_, static_cast<uint32_t>(Utils::displayRect_.width_ * RATIO));
235
236 WindowManager::GetInstance().RegisterSystemBarChangedListener(testSystemBarChangedListener_);
237 activeWindows_.clear();
238 sleep(1);
239 }
240
TearDown()241 void WindowImmersiveTest::TearDown()
242 {
243 while (!activeWindows_.empty()) {
244 ASSERT_EQ(WMError::WM_OK, activeWindows_.back()->Destroy());
245 activeWindows_.pop_back();
246 }
247 WindowManager::GetInstance().UnregisterSystemBarChangedListener(testSystemBarChangedListener_);
248 sleep(1);
249 }
250
251 namespace {
252 /**
253 * @tc.name: ImmersiveTest01
254 * @tc.desc: Add one immersive window and hide
255 * @tc.type: FUNC
256 */
257 HWTEST_F(WindowImmersiveTest, ImmersiveTest01, Function | MediumTest | Level3)
258 {
259 fullScreenAppinfo_.name = "immer01";
260 const sptr<Window>& window = Utils::CreateTestWindow(fullScreenAppinfo_);
261 if (window == nullptr) {
262 return;
263 }
264 activeWindows_.push_back(window);
265 SetWindowSystemProps(window, TEST_PROPS_1);
266 ASSERT_EQ(WMError::WM_OK, window->Show());
267 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_1));
268 ASSERT_EQ(WMError::WM_OK, window->Hide());
269 }
270
271 /**
272 * @tc.name: ImmersiveTest02
273 * @tc.desc: Add two immersive window and switch
274 * @tc.type: FUNC
275 */
276 HWTEST_F(WindowImmersiveTest, ImmersiveTest02, Function | MediumTest | Level3)
277 {
278 const sptr<Window>& window1 = Utils::CreateTestWindow(fullScreenAppinfo_);
279 if (window1 == nullptr) {
280 return;
281 }
282 activeWindows_.push_back(window1);
283 SetWindowSystemProps(window1, TEST_PROPS_1);
284 fullScreenAppinfo_.name = "Immer02";
285 const sptr<Window>& window2 = Utils::CreateTestWindow(fullScreenAppinfo_);
286 ASSERT_NE(nullptr, window2);
287 activeWindows_.push_back(window2);
288 SetWindowSystemProps(window2, TEST_PROPS_2);
289 ASSERT_EQ(WMError::WM_OK, window1->Show());
290 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_1));
291 ASSERT_EQ(WMError::WM_OK, window2->Show());
292
293 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_2));
294 ASSERT_EQ(WMError::WM_OK, window2->Hide());
295 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_1));
296 ASSERT_EQ(WMError::WM_OK, window1->Hide());
297 }
298
299 /**
300 * @tc.name: ImmersiveTest03
301 * @tc.desc: Add one no immersive window
302 * @tc.type: FUNC
303 */
304 HWTEST_F(WindowImmersiveTest, ImmersiveTest03, Function | MediumTest | Level3)
305 {
306 const sptr<Window>& window1 = Utils::CreateTestWindow(fullScreenAppinfo_);
307 if (window1 == nullptr) {
308 return;
309 }
310 activeWindows_.push_back(window1);
311 SetWindowSystemProps(window1, TEST_PROPS_1);
312 fullScreenAppinfo_.name = "Immer03";
313 fullScreenAppinfo_.needAvoid = true; // no immersive setting
314 const sptr<Window>& window2 = Utils::CreateTestWindow(fullScreenAppinfo_);
315 ASSERT_NE(nullptr, window2);
316 activeWindows_.push_back(window2);
317 SetWindowSystemProps(window2, TEST_PROPS_2);
318 ASSERT_EQ(WMError::WM_OK, window1->Show());
319 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_1));
320 ASSERT_EQ(WMError::WM_OK, window2->Show());
321 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_2));
322 ASSERT_EQ(WMError::WM_OK, window1->Hide());
323 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_2));
324 }
325
326 /**
327 * @tc.name: ImmersiveTest04
328 * @tc.desc: SetLayoutFullScreen
329 * @tc.type: FUNC
330 */
331 HWTEST_F(WindowImmersiveTest, ImmersiveTest04, Function | MediumTest | Level3)
332 {
333 fullScreenAppinfo_.needAvoid = true; // no immersive setting
334 const sptr<Window>& window1 = Utils::CreateTestWindow(fullScreenAppinfo_);
335 if (window1 == nullptr) {
336 return;
337 }
338 activeWindows_.push_back(window1);
339 SetWindowSystemProps(window1, TEST_PROPS_1);
340 ASSERT_EQ(WMError::WM_OK, window1->Show());
341 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_1));
342 ASSERT_EQ(WMError::WM_OK, window1->SetLayoutFullScreen(true));
343 ASSERT_EQ(true, window1->IsLayoutFullScreen());
344 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_1));
345 ASSERT_EQ(WMError::WM_OK, window1->SetLayoutFullScreen(false));
346 ASSERT_EQ(false, window1->IsLayoutFullScreen());
347 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_1));
348 ASSERT_EQ(WMError::WM_OK, window1->Hide());
349 }
350
351 /**
352 * @tc.name: ImmersiveTest05
353 * @tc.desc: SetFullScreen
354 * @tc.type: FUNC
355 */
356 HWTEST_F(WindowImmersiveTest, ImmersiveTest05, Function | MediumTest | Level3)
357 {
358 fullScreenAppinfo_.needAvoid = true; // no immersive setting
359 const sptr<Window>& window1 = Utils::CreateTestWindow(fullScreenAppinfo_);
360 if (window1 == nullptr) {
361 return;
362 }
363 activeWindows_.push_back(window1);
364 SetWindowSystemProps(window1, TEST_PROPS_1);
365 ASSERT_EQ(WMError::WM_OK, window1->Show());
366 ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_1));
367 ASSERT_EQ(WMError::WM_OK, window1->SetFullScreen(true));
368 ASSERT_EQ(true, window1->IsFullScreen());
369 ASSERT_TRUE(SystemBarEnableState(false, false));
370 ASSERT_EQ(WMError::WM_OK, window1->SetFullScreen(false));
371 ASSERT_EQ(false, window1->IsFullScreen());
372 ASSERT_EQ(WMError::WM_OK, window1->Hide());
373 }
374
375 /**
376 * @tc.name: ImmersiveNegativeTest01
377 * @tc.desc: set systembar props with wrong window type
378 * @tc.type: FUNC
379 */
380 HWTEST_F(WindowImmersiveTest, ImmersiveNegativeTest01, Function | MediumTest | Level3)
381 {
382 const SystemBarRegionTints TEST_PROPS_NEGATIVE = {
383 { WindowType::WINDOW_TYPE_KEYGUARD, SYS_BAR_PROP_1, SYS_BAR_REGION_NULL },
384 { WindowType::WINDOW_TYPE_POINTER, SYS_BAR_PROP_2, SYS_BAR_REGION_NULL },
385 };
386 const sptr<Window>& window = Utils::CreateTestWindow(fullScreenAppinfo_);
387 if (window == nullptr) {
388 return;
389 }
390 activeWindows_.push_back(window);
391 SetWindowSystemProps(window, TEST_PROPS_NEGATIVE);
392 ASSERT_EQ(WMError::WM_OK, window->Show());
393 ASSERT_FALSE(SystemBarPropsEqualsTo(TEST_PROPS_NEGATIVE));
394 ASSERT_EQ(WMError::WM_OK, window->Hide());
395 ASSERT_FALSE(SystemBarPropsEqualsTo(TEST_PROPS_NEGATIVE));
396 }
397
398 /**
399 * @tc.name: GetAvoidAreaByTypeTest01
400 * @tc.desc: Test GetAvoidArea use unsupported Type(TYPE_CUTOUT).
401 * @tc.type: FUNC
402 */
403 HWTEST_F(WindowImmersiveTest, GetAvoidAreaByTypeTest01, Function | MediumTest | Level3)
404 {
405 // Add full screenwindow for call GetAvoidArea, and push_back in activeWindows_
406 const sptr<Window>& win = Utils::CreateTestWindow(fullScreenAppinfo_);
407 if (win == nullptr) {
408 return;
409 }
410 activeWindows_.push_back(win);
411
412 // Test GetAvoidArea
413 AvoidArea avoidarea;
414 WMError ret = win->GetAvoidAreaByType(AvoidAreaType::TYPE_CUTOUT, avoidarea);
415 ASSERT_EQ(WMError::WM_OK, ret);
416 ASSERT_TRUE(Utils::RectEqualToRect(EMPTY_RECT, avoidarea.leftRect_));
417 ASSERT_TRUE(Utils::RectEqualToRect(EMPTY_RECT, avoidarea.rightRect_));
418 ASSERT_TRUE(Utils::RectEqualToRect(EMPTY_RECT, avoidarea.topRect_));
419 ASSERT_TRUE(Utils::RectEqualToRect(EMPTY_RECT, avoidarea.bottomRect_));
420 ASSERT_EQ(WMError::WM_OK, win->Hide());
421 }
422
423 /**
424 * @tc.name: DockWindowTest01
425 * @tc.desc: Add unexistavoid and remove this avoid. Test OnAvoidAreaChanged listener
426 * @tc.type: FUNC
427 */
428 HWTEST_F(WindowImmersiveTest, DockWindowTest01, Function | MediumTest | Level3)
429 {
430 const sptr<Window>& dockWindow = Utils::CreateDockWindow();
431 if (dockWindow == nullptr) {
432 return;
433 }
434
435 if (WMError::WM_ERROR_INVALID_WINDOW == dockWindow->Show()) {
436 ASSERT_EQ(WMError::WM_ERROR_INVALID_WINDOW, dockWindow->Show());
437 } else if (WMError::WM_OK == dockWindow->Show()) {
438 ASSERT_EQ(WMError::WM_OK, dockWindow->Show());
439 }
440
441 const sptr<Window>& window = Utils::CreateTestWindow(fullScreenAppinfo_);
442 if (window == nullptr) {
443 return;
444 }
445 usleep(WAIT_ASYNC_US);
446 auto act = testSystemBarChangedListener_->tints_;
447 for (SystemBarRegionTint tint : act) {
448 if (tint.type_ == WindowType::WINDOW_TYPE_LAUNCHER_DOCK) {
449 ASSERT_FALSE(tint.prop_.enable_);
450 }
451 }
452
453 ASSERT_EQ(WMError::WM_OK, window->Hide());
454
455 usleep(WAIT_ASYNC_US);
456 act = testSystemBarChangedListener_->tints_;
457 for (SystemBarRegionTint tint : act) {
458 if (tint.type_ == WindowType::WINDOW_TYPE_LAUNCHER_DOCK) {
459 ASSERT_TRUE(tint.prop_.enable_);
460 }
461 }
462 ASSERT_EQ(WMError::WM_OK, dockWindow->Destroy());
463 }
464 }
465 } // namespace Rosen
466 } // namespace OHOS
467