1 /*
2  * Copyright (c) 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 #include <gtest/gtest.h>
16 #include <transaction/rs_transaction.h>
17 #include <ui/rs_surface_node.h>
18 #include "display_test_utils.h"
19 #include "display.h"
20 #include "display_manager_proxy.h"
21 #include "screen.h"
22 #include "surface_draw.h"
23 #include "wm_common.h"
24 #include "wm_common_inner.h"
25 #include "window.h"
26 #include "window_option.h"
27 #include "window_manager_hilog.h"
28 #include "display_manager_agent_controller.h"
29 
30 using namespace testing;
31 using namespace testing::ext;
32 
33 namespace OHOS::Rosen {
34 namespace  {
35 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DisplayManagerTest"};
36 const int WAIT_FOR_SYNC_US = 1;  // 1s
37 }
38 
39 class DisplayChangeEventListener : public DisplayManager::IDisplayListener {
40 public:
OnCreate(DisplayId displayId)41     virtual void OnCreate(DisplayId displayId) {}
42 
OnDestroy(DisplayId displayId)43     virtual void OnDestroy(DisplayId displayId) {}
44 
OnChange(DisplayId displayId)45     virtual void OnChange(DisplayId displayId) {}
46 };
47 
48 class DisplayManagerTest : public testing::Test {
49 public:
50     static void SetUpTestCase();
51     static void TearDownTestCase();
52     virtual void SetUp() override;
53     virtual void TearDown() override;
54 
55     sptr<Window> CreateWindow(std::string name, WindowMode mode, Rect rect, uint32_t color = 0xff000000);
56     bool DrawWindowColor(const sptr<Window>& window, uint32_t color, int32_t width, int32_t height);
57     static inline DisplayId displayId_;
58     static inline int32_t displayWidth_;
59     static inline int32_t displayHeight_;
60 };
61 
SetUpTestCase()62 void DisplayManagerTest::SetUpTestCase()
63 {
64     displayId_ = DisplayManager::GetInstance().GetDefaultDisplayId();
65     sptr<Display> display = DisplayManager::GetInstance().GetDefaultDisplay();
66     if (display == nullptr) {
67         return;
68     }
69     displayWidth_ = display->GetWidth();
70     displayHeight_ = display->GetHeight();
71 }
72 
TearDownTestCase()73 void DisplayManagerTest::TearDownTestCase()
74 {
75 }
76 
SetUp()77 void DisplayManagerTest::SetUp()
78 {
79 }
80 
TearDown()81 void DisplayManagerTest::TearDown()
82 {
83 }
84 
CreateWindow(std::string name,WindowMode mode,Rect rect,uint32_t color)85 sptr<Window> DisplayManagerTest::CreateWindow(std::string name,
86     WindowMode mode, Rect rect, uint32_t color)
87 {
88     sptr<WindowOption> option = new WindowOption();
89     option->SetDisplayId(displayId_);
90     option->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
91     int32_t width = 0;
92     int32_t height = 0;
93     if (mode != WindowMode::WINDOW_MODE_FULLSCREEN) {
94         option->SetWindowRect(rect);
95     } else {
96         width = displayWidth_;
97         height = displayHeight_;
98     }
99     option->SetWindowMode(mode);
100     option->SetWindowName(name);
101     sptr<Window> window = Window::Create(option->GetWindowName(), option);
102     if (window == nullptr) {
103         return nullptr;
104     }
105     window->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
106     window->Show();
107     sleep(WAIT_FOR_SYNC_US); // wait for rect updated
108     width = window->GetRect().width_;
109     height = window->GetRect().height_;
110     DrawWindowColor(window, color, width, height); // 0x66000000 color_black
111     RSTransaction::FlushImplicitTransaction();
112     return window;
113 }
114 
DrawWindowColor(const sptr<Window> & window,uint32_t color,int32_t width,int32_t height)115 bool DisplayManagerTest::DrawWindowColor(const sptr<Window>& window, uint32_t color, int32_t width, int32_t height)
116 {
117     auto surfaceNode = window->GetSurfaceNode();
118     if (surfaceNode == nullptr) {
119         WLOGFE("Failed to GetSurfaceNode!");
120         return false;
121     }
122     SurfaceDraw::DrawColor(surfaceNode, width, height, color);
123     surfaceNode->SetAbilityBGAlpha(255); // 255 is alpha
124     return true;
125 }
126 
127 namespace {
128 /**
129  * @tc.name: HasPrivateWindow
130  * @tc.desc: Check whether there is a private window in the current display
131  * @tc.type: FUNC
132  * @tc.require issueI5HF6V
133  */
134 HWTEST_F(DisplayManagerTest, HasPrivateWindow, Function | SmallTest | Level2)
135 {
136     sptr<Window> window = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
137     if (window == nullptr) {
138         return;
139     }
140     ASSERT_NE(nullptr, window);
141     window->SetPrivacyMode(true);
142     sleep(WAIT_FOR_SYNC_US);
143     bool hasPrivateWindow = false;
144     DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
145     DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
146 
147     window->SetPrivacyMode(false);
148     sleep(WAIT_FOR_SYNC_US);
149     DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
150     window->Destroy();
151     ASSERT_TRUE(!hasPrivateWindow);
152 }
153 
154 /**
155  * @tc.name: HasPrivateWindowCovered
156  * @tc.desc: The private window is covered
157  * @tc.type: FUNC
158  * @tc.require issueI5HF6V
159  */
160 HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered, Function | SmallTest | Level2)
161 {
162     auto displayWidth = DisplayManagerTest::displayWidth_;
163     auto displayHeight = DisplayManagerTest::displayHeight_;
164 
165     sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
166     if (window1 == nullptr) {
167         return;
168     }
169     ASSERT_NE(nullptr, window1);
170     // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height
171     sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING,
172                                         Rect{0, 0, 300, 300}, 0xffff0000);
173     ASSERT_NE(nullptr, window2);
174     window2->SetPrivacyMode(true);
175     // The window shadows is too large to cover. so, set a special position for cover window easily.
176     sleep(WAIT_FOR_SYNC_US);
177     window2->MoveTo(displayWidth * 0.53, displayHeight * 0.66);
178     sleep(WAIT_FOR_SYNC_US);
179 
180     // 10:rect.posX_, 110:rect.posY_, 650:rect.width, 500:rect.height
181     sptr<Window> window3 = CreateWindow("covered", WindowMode::WINDOW_MODE_FLOATING,
182                                         Rect{0, 0, displayWidth, displayHeight}, 0xff00ff00);
183     ASSERT_NE(nullptr, window3);
184     sleep(WAIT_FOR_SYNC_US);
185     window3->MoveTo(45, 115);
186     sleep(WAIT_FOR_SYNC_US);
187 
188     bool hasPrivateWindow = false;
189     DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
190     DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
191     window1->Destroy();
192     window2->Destroy();
193     window3->Destroy();
194     if (!hasPrivateWindow) {
195         ASSERT_TRUE(!hasPrivateWindow);
196     }
197 }
198 
199 /**
200  * @tc.name: HasPrivateWindowCovered01
201  * @tc.desc: The private window is partially covered
202  * @tc.type: FUNC
203  * @tc.require issueI5HF6V
204  */
205 HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered01, Function | SmallTest | Level2)
206 {
207     sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect{0, 0, 0, 0});
208 
209     // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height
210     if (window1 == nullptr)
211     {
212         return;
213     }
214     ASSERT_NE(nullptr, window1);
215     sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING,
216                                         Rect{10, 120, 650, 500}, 0xffff0000);
217     ASSERT_NE(nullptr, window2);
218     window2->SetPrivacyMode(true);
219     // 5:rect.posX_, 110:rect.posY_, 650:rect.width, 500:rect.height
220     sptr<Window> window3 = CreateWindow("covered", WindowMode::WINDOW_MODE_FLOATING,
221                                         Rect{5, 110, 650, 500}, 0xff00ff00);
222     ASSERT_NE(nullptr, window3);
223 
224     sleep(WAIT_FOR_SYNC_US);
225     bool hasPrivateWindow = false;
226     DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
227     DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
228     window1->Destroy();
229     window2->Destroy();
230     window3->Destroy();
231     if (hasPrivateWindow)
232     {
233         ASSERT_TRUE(hasPrivateWindow);
234     }
235 }
236 
237 /**
238  * @tc.name: HasPrivateWindowCovered02
239  * @tc.desc: The private window is covered
240  * @tc.type: FUNC
241  * @tc.require issueI5HF6V
242  */
243 HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered02, Function | SmallTest | Level2)
244 {
245     auto displayWidth = DisplayManagerTest::displayWidth_;
246     auto displayHeight = DisplayManagerTest::displayHeight_;
247 
248     sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
249     if (window1 == nullptr) {
250         return;
251     }
252     ASSERT_NE(nullptr, window1);
253     // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height
254     sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING,
255                                         Rect {0, 0, 300, 300}, 0xffff0000);
256     ASSERT_NE(nullptr, window2);
257     window2->SetPrivacyMode(true);
258     // The window shadows is too large to cover. so, set a special position for cover window easily.
259     sleep(WAIT_FOR_SYNC_US);
260     window2->MoveTo(displayWidth * 0.53, displayHeight * 0.66);
261     sleep(WAIT_FOR_SYNC_US);
262 
263     // 5:rect.posX_, 110:rect.posY_, 655:rect.width, 500:rect.height
264     sptr<Window> window3 = CreateWindow("covered1", WindowMode::WINDOW_MODE_FLOATING,
265                                         Rect { 0, 0, displayWidth, displayHeight / 2}, 0xff00ff00);
266     ASSERT_NE(nullptr, window3);
267     sleep(WAIT_FOR_SYNC_US);
268     window3->MoveTo(45, 115);
269     sleep(WAIT_FOR_SYNC_US);
270 
271     // 5:rect.posX_, 300:rect.posY_, 655:rect.width, 500:rect.height
272     sptr<Window> window4 = CreateWindow("covered2", WindowMode::WINDOW_MODE_FLOATING,
273                                         Rect { 0, 0, displayWidth, displayHeight / 2 + 200 }, 0xff00ff00);
274     ASSERT_NE(nullptr, window4);
275     window4->MoveTo(45, displayHeight / 2 - 95);
276 
277     sleep(WAIT_FOR_SYNC_US);
278     bool hasPrivateWindow = false;
279     DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
280     DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
281     window1->Destroy();
282     window2->Destroy();
283     window3->Destroy();
284     window4->Destroy();
285     if (!hasPrivateWindow) {
286         ASSERT_TRUE(!hasPrivateWindow);
287     }
288 }
289 
290 /**
291  * @tc.name: HasPrivateWindowCovered03
292  * @tc.desc: The private window is partially covered
293  * @tc.type: FUNC
294  * @tc.require issueI5HF6V
295  */
296 HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered03, Function | SmallTest | Level2)
297 {
298     sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
299 
300     if (window1 == nullptr) {
301         return;
302     }
303     ASSERT_NE(nullptr, window1);
304     // 10:rect.posX_, 120:rect.pos_Y, rect.width_:650, rect.height_:700
305     sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING,
306                                         Rect{10, 120, 650, 700}, 0xffff0000);
307     ASSERT_NE(nullptr, window2);
308     window2->SetPrivacyMode(true);
309     // 5:rect.posX_, 110:rect.pos_Y, rect.width_:655, rect.height_:500
310     sptr<Window> window3 = CreateWindow("covered1", WindowMode::WINDOW_MODE_FLOATING,
311                                         Rect{5, 110, 655, 500}, 0xff00ff00);
312     ASSERT_NE(nullptr, window3);
313     // 5:rect.posX_, 700:rect.pos_Y, rect.width_:655, rect.height_:500
314     sptr<Window> window4 = CreateWindow("covered2", WindowMode::WINDOW_MODE_FLOATING,
315                                         Rect{5, 700, 655, 500}, 0xff00ff00);
316     ASSERT_NE(nullptr, window4);
317 
318     sleep(WAIT_FOR_SYNC_US);
319     bool hasPrivateWindow = false;
320     DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
321     DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
322     window1->Destroy();
323     window2->Destroy();
324     window3->Destroy();
325     window4->Destroy();
326     if (hasPrivateWindow) {
327         ASSERT_TRUE(hasPrivateWindow);
328     }
329 }
330 
331 /**
332  * @tc.name: HasPrivateWindowSkipSnapShot
333  * @tc.desc: set snap shot skip
334  * @tc.type: FUNC
335  * @tc.require issueI5HF6V
336  */
337 HWTEST_F(DisplayManagerTest, HasPrivateWindowSkipSnapShot, Function | SmallTest | Level2)
338 {
339     sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
340     if (window1 == nullptr) {
341         return;
342     }
343     ASSERT_NE(nullptr, window1);
344     // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height
345     sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING,
346         Rect {10, 120, 650, 500}, 0xffff0000);
347     ASSERT_NE(nullptr, window2);
348     window2->SetSnapshotSkip(true);
349     sleep(WAIT_FOR_SYNC_US);
350     bool hasPrivateWindow = false;
351     DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
352     DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
353     window1->Destroy();
354     window2->Destroy();
355     if (hasPrivateWindow) {
356         ASSERT_TRUE(hasPrivateWindow);
357     }
358 }
359 
360 /**
361  * @tc.name: AddSurfaceNodeToDisplay | RemoveSurfaceNodeFromDisplay
362  * @tc.desc: add/remove surfaceNode to/from display
363  * @tc.type: FUNC
364  */
365 HWTEST_F(DisplayManagerTest, AddAndRemoveSurfaceNode, Function | SmallTest | Level2)
366 {
367     RSSurfaceNodeConfig config;
368     config.SurfaceNodeName = "TestSurfaceNode";
369     auto surfaceNode = RSSurfaceNode::Create(config);
370     DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
371     ASSERT_EQ(DMError::DM_OK, DisplayManager::GetInstance().AddSurfaceNodeToDisplay(id, surfaceNode));
372     sleep(2);
373     ASSERT_EQ(DMError::DM_OK, DisplayManager::GetInstance().RemoveSurfaceNodeFromDisplay(id, surfaceNode));
374 }
375 
376 /**
377  * @tc.name: AddSurfaceNodeToDisplay | RemoveSurfaceNodeFromDisplay
378  * @tc.desc: add/remove surfaceNode to/from display
379  * @tc.type: FUNC
380  */
381 HWTEST_F(DisplayManagerTest, SetVirtualScreenSecurityExemption, Function | SmallTest | Level2)
382 {
383     ScreenId id = 0;
384     uint32_t pid = 0;
385     std::vector<uint64_t> windowList;
386     auto ret = DisplayManager::GetInstance().SetVirtualScreenSecurityExemption(id, pid, windowList);
387     ASSERT_NE(DMError::DM_OK, ret); // not virtual screen for id 0
388     sleep(2);
389 }
390 
391 }
392 } // namespace OHOS::Rosen
393