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