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