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 "display_test_utils.h"
18 #include "display.h"
19 #include "screen.h"
20 #include "surface_draw.h"
21 #include "wm_common.h"
22 #include "wm_common_inner.h"
23 #include "window.h"
24 #include "window_option.h"
25 #include "window_manager_hilog.h"
26 #include "display_manager_agent_controller.h"
27
28 using namespace testing;
29 using namespace testing::ext;
30
31 namespace OHOS::Rosen {
32 namespace {
33 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DisplayManagerTest"};
34 const int WAIT_FOR_SYNC_US = 1; // 1s
35 }
36
37 class DisplayChangeEventListener : public DisplayManager::IDisplayListener {
38 public:
OnCreate(DisplayId displayId)39 virtual void OnCreate(DisplayId displayId) {}
40
OnDestroy(DisplayId displayId)41 virtual void OnDestroy(DisplayId displayId) {}
42
OnChange(DisplayId displayId)43 virtual void OnChange(DisplayId displayId) {}
44 };
45
46 class DisplayManagerTest : public testing::Test {
47 public:
48 static void SetUpTestCase();
49 static void TearDownTestCase();
50 virtual void SetUp() override;
51 virtual void TearDown() override;
52
53 sptr<Window> CreateWindow(std::string name, WindowMode mode, Rect rect);
54 bool DrawWindowColor(const sptr<Window>& window, uint32_t color, int32_t width, int32_t height);
55 static inline DisplayId displayId_;
56 static inline int32_t displayWidth_;
57 static inline int32_t displayHeight_;
58 };
59
SetUpTestCase()60 void DisplayManagerTest::SetUpTestCase()
61 {
62 displayId_ = DisplayManager::GetInstance().GetDefaultDisplayId();
63 sptr<Display> display = DisplayManager::GetInstance().GetDefaultDisplay();
64 if (display == nullptr) {
65 return;
66 }
67 displayWidth_ = display->GetWidth();
68 displayHeight_ = display->GetHeight();
69 }
70
TearDownTestCase()71 void DisplayManagerTest::TearDownTestCase()
72 {
73 }
74
SetUp()75 void DisplayManagerTest::SetUp()
76 {
77 }
78
TearDown()79 void DisplayManagerTest::TearDown()
80 {
81 }
82
CreateWindow(std::string name,WindowMode mode,Rect rect)83 sptr<Window> DisplayManagerTest::CreateWindow(std::string name, WindowMode mode, Rect rect)
84 {
85 sptr<WindowOption> option = new WindowOption();
86 option->SetDisplayId(displayId_);
87 option->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
88 int32_t width = 0;
89 int32_t height = 0;
90 if (mode != WindowMode::WINDOW_MODE_FULLSCREEN) {
91 option->SetWindowRect(rect);
92 } else {
93 width = displayWidth_;
94 height = displayHeight_;
95 }
96 option->SetWindowMode(mode);
97 option->SetWindowName(name);
98 sptr<Window> window = Window::Create(option->GetWindowName(), option);
99 if (window == nullptr) {
100 return nullptr;
101 }
102 window->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
103 window->Show();
104 sleep(WAIT_FOR_SYNC_US); // wait for rect updated
105 width = window->GetRect().width_;
106 height = window->GetRect().height_;
107 DrawWindowColor(window, 0x66000000, width, height); // 0x66000000 color_black
108 RSTransaction::FlushImplicitTransaction();
109 return window;
110 }
111
DrawWindowColor(const sptr<Window> & window,uint32_t color,int32_t width,int32_t height)112 bool DisplayManagerTest::DrawWindowColor(const sptr<Window>& window, uint32_t color, int32_t width, int32_t height)
113 {
114 auto surfaceNode = window->GetSurfaceNode();
115 if (surfaceNode == nullptr) {
116 WLOGFE("Failed to GetSurfaceNode!");
117 return false;
118 }
119 SurfaceDraw::DrawColor(surfaceNode, width, height, color);
120 surfaceNode->SetAbilityBGAlpha(255); // 255 is alpha
121 return true;
122 }
123
124 namespace {
125 /**
126 * @tc.name: HasPrivateWindow
127 * @tc.desc: Check whether there is a private window in the current display
128 * @tc.type: FUNC
129 * @tc.require issueI5HF6V
130 */
131 HWTEST_F(DisplayManagerTest, HasPrivateWindow, Function | SmallTest | Level2)
132 {
133 sptr<Window> window = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
134 ASSERT_NE(nullptr, window);
135 window->SetPrivacyMode(true);
136 sleep(WAIT_FOR_SYNC_US);
137 bool hasPrivateWindow = false;
138 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
139 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
140
141 window->SetPrivacyMode(false);
142 sleep(WAIT_FOR_SYNC_US);
143 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
144 window->Destroy();
145 ASSERT_TRUE(!hasPrivateWindow);
146 }
147
148 /**
149 * @tc.name: HasPrivateWindowCovered
150 * @tc.desc: The private window is covered
151 * @tc.type: FUNC
152 * @tc.require issueI5HF6V
153 */
154 HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered, Function | SmallTest | Level2)
155 {
156 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
157 ASSERT_NE(nullptr, window1);
158 // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height
159 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 120, 650, 500});
160 ASSERT_NE(nullptr, window2);
161 window2->SetPrivacyMode(true);
162 // 10:rect.posX_, 110:rect.posY_, 650:rect.width, 500:rect.height
163 sptr<Window> window3 = CreateWindow("covered", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 120, 650, 500});
164 ASSERT_NE(nullptr, window3);
165 sleep(WAIT_FOR_SYNC_US);
166 bool hasPrivateWindow = false;
167 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
168 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
169 window1->Destroy();
170 window2->Destroy();
171 window3->Destroy();
172 ASSERT_TRUE(!hasPrivateWindow);
173 }
174
175 /**
176 * @tc.name: HasPrivateWindowCovered01
177 * @tc.desc: The private window is partially covered
178 * @tc.type: FUNC
179 * @tc.require issueI5HF6V
180 */
181 HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered01, Function | SmallTest | Level2)
182 {
183 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
184 ASSERT_NE(nullptr, window1);
185 // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height
186 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 120, 650, 500});
187 ASSERT_NE(nullptr, window2);
188 window2->SetPrivacyMode(true);
189 // 5:rect.posX_, 110:rect.posY_, 650:rect.width, 500:rect.height
190 sptr<Window> window3 = CreateWindow("covered", WindowMode::WINDOW_MODE_FLOATING, Rect {5, 110, 650, 500});
191 ASSERT_NE(nullptr, window3);
192 sleep(WAIT_FOR_SYNC_US);
193 bool hasPrivateWindow = false;
194 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
195 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
196 window1->Destroy();
197 window2->Destroy();
198 window3->Destroy();
199 ASSERT_TRUE(hasPrivateWindow);
200 }
201
202 /**
203 * @tc.name: HasPrivateWindowCovered02
204 * @tc.desc: The private window is covered
205 * @tc.type: FUNC
206 * @tc.require issueI5HF6V
207 */
208 HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered02, Function | SmallTest | Level2)
209 {
210 sptr<Display> display = DisplayManager::GetInstance().GetDefaultDisplay();
211 ASSERT_NE(nullptr, display);
212 auto vpr = display->GetVirtualPixelRatio();
213 uint32_t baseWidth = vpr * MIN_FLOATING_WIDTH;
214
215 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
216 ASSERT_NE(nullptr, window1);
217 // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height
218 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING,
219 Rect {10, 220, baseWidth + 10, 500});
220 ASSERT_NE(nullptr, window2);
221 window2->SetPrivacyMode(true);
222 // 5:rect.posX_, 110:rect.posY_, 655:rect.width, 500:rect.height
223 sptr<Window> window3 = CreateWindow("covered1", WindowMode::WINDOW_MODE_FLOATING,
224 Rect {5, 210, baseWidth + 15, 500});
225 ASSERT_NE(nullptr, window3);
226 // 5:rect.posX_, 300:rect.posY_, 655:rect.width, 500:rect.height
227 sptr<Window> window4 = CreateWindow("covered2", WindowMode::WINDOW_MODE_FLOATING,
228 Rect {5, 400, baseWidth + 15, 500});
229 ASSERT_NE(nullptr, window4);
230
231 sleep(WAIT_FOR_SYNC_US);
232 bool hasPrivateWindow = false;
233 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
234 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
235 window1->Destroy();
236 window2->Destroy();
237 window3->Destroy();
238 window4->Destroy();
239 ASSERT_TRUE(!hasPrivateWindow);
240 }
241
242 /**
243 * @tc.name: HasPrivateWindowCovered03
244 * @tc.desc: The private window is partially covered
245 * @tc.type: FUNC
246 * @tc.require issueI5HF6V
247 */
248 HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered03, Function | SmallTest | Level2)
249 {
250 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
251 ASSERT_NE(nullptr, window1);
252 // 10:rect.posX_, 120:rect.pos_Y, rect.width_:650, rect.height_:700
253 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 120, 650, 700});
254 ASSERT_NE(nullptr, window2);
255 window2->SetPrivacyMode(true);
256 // 5:rect.posX_, 110:rect.pos_Y, rect.width_:655, rect.height_:500
257 sptr<Window> window3 = CreateWindow("covered1", WindowMode::WINDOW_MODE_FLOATING, Rect {5, 110, 655, 500});
258 ASSERT_NE(nullptr, window3);
259 // 5:rect.posX_, 700:rect.pos_Y, rect.width_:655, rect.height_:500
260 sptr<Window> window4 = CreateWindow("covered2", WindowMode::WINDOW_MODE_FLOATING, Rect {5, 700, 655, 500});
261 ASSERT_NE(nullptr, window4);
262
263 sleep(WAIT_FOR_SYNC_US);
264 bool hasPrivateWindow = false;
265 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
266 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
267 window1->Destroy();
268 window2->Destroy();
269 window3->Destroy();
270 window4->Destroy();
271 ASSERT_TRUE(hasPrivateWindow);
272 }
273
274 /**
275 * @tc.name: HasPrivateWindowSkipSnapShot
276 * @tc.desc: set snap shot skip
277 * @tc.type: FUNC
278 * @tc.require issueI5HF6V
279 */
280 HWTEST_F(DisplayManagerTest, HasPrivateWindowSkipSnapShot, Function | SmallTest | Level2)
281 {
282 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0});
283 ASSERT_NE(nullptr, window1);
284 // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height
285 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 120, 650, 500});
286 ASSERT_NE(nullptr, window2);
287
288 window2->SetSnapshotSkip(true);
289 sleep(WAIT_FOR_SYNC_US);
290 bool hasPrivateWindow = false;
291 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId();
292 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow);
293 window1->Destroy();
294 window2->Destroy();
295 ASSERT_TRUE(!hasPrivateWindow);
296 }
297 }
298 } // namespace OHOS::Rosen
299