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
16 #include <gtest/gtest.h>
17
18 #include "avoid_area_controller.h"
19 #include "display_manager.h"
20 #include "display_manager_config.h"
21 #include "future.h"
22 #include "window_node.h"
23 #include "wm_common.h"
24
25 using namespace testing;
26 using namespace testing::ext;
27
28 namespace OHOS {
29 namespace Rosen {
30 namespace {
31 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "AvoidAreaControllerTest"};
32
33 const Rect EMPTY_RECT = { 0, 0, 0, 0 };
34 const float BARRATIO = 0.3;
35 const long TIME_OUT = 1000;
36 const AvoidArea EMPTY_AVOID_AREA = {};
37 }
38
39 class AvoidAreaControllerTest : public testing::Test {
40 public:
41 static void SetUpTestCase();
42 static void TearDownTestCase();
43 virtual void SetUp() override;
44 virtual void TearDown() override;
45
46 static sptr<WindowNode> statusbarWindowNode;
47 static sptr<WindowNode> navigationBarWindowNode;
48 static sptr<WindowNode> keyboardWindowNode;
49 static Rect screenRect;
50 static Rect cut_out_rect;
51 };
52
53 sptr<WindowNode> AvoidAreaControllerTest::statusbarWindowNode = nullptr;
54 sptr<WindowNode> AvoidAreaControllerTest::navigationBarWindowNode = nullptr;
55 sptr<WindowNode> AvoidAreaControllerTest::keyboardWindowNode = nullptr;
56 Rect AvoidAreaControllerTest::screenRect;
57
58 class WindowListener : public IWindow {
59 public:
UpdateWindowRect(const struct Rect & rect,bool decoStatus,WindowSizeChangeReason reason)60 WMError UpdateWindowRect(const struct Rect& rect, bool decoStatus, WindowSizeChangeReason reason) override
61 {
62 return WMError::WM_OK;
63 }
UpdateWindowMode(WindowMode mode)64 WMError UpdateWindowMode(WindowMode mode) override
65 {
66 return WMError::WM_OK;
67 }
UpdateFocusStatus(bool focused)68 WMError UpdateFocusStatus(bool focused) override
69 {
70 return WMError::WM_OK;
71 }
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)72 WMError UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type) override
73 {
74 if (type == AvoidAreaType::TYPE_SYSTEM) {
75 statusBarAvoidAreaFuture_.SetValue(*avoidArea);
76 }
77 if (type == AvoidAreaType::TYPE_KEYBOARD) {
78 keyboardAvoidAreaFuture_.SetValue(*avoidArea);
79 }
80 return WMError::WM_OK;
81 }
UpdateWindowModeSupportInfo(uint32_t modeSupportInfo)82 WMError UpdateWindowModeSupportInfo(uint32_t modeSupportInfo) override
83 {
84 return WMError::WM_OK;
85 }
UpdateWindowState(WindowState state)86 WMError UpdateWindowState(WindowState state) override
87 {
88 return WMError::WM_OK;
89 }
UpdateWindowDragInfo(const PointInfo & point,DragEvent event)90 WMError UpdateWindowDragInfo(const PointInfo& point, DragEvent event) override
91 {
92 return WMError::WM_OK;
93 }
UpdateDisplayId(DisplayId from,DisplayId to)94 WMError UpdateDisplayId(DisplayId from, DisplayId to) override
95 {
96 return WMError::WM_OK;
97 }
UpdateOccupiedAreaChangeInfo(const sptr<OccupiedAreaChangeInfo> & info)98 WMError UpdateOccupiedAreaChangeInfo(const sptr<OccupiedAreaChangeInfo>& info) override
99 {
100 return WMError::WM_OK;
101 }
UpdateActiveStatus(bool isActive)102 WMError UpdateActiveStatus(bool isActive) override
103 {
104 return WMError::WM_OK;
105 }
GetWindowProperty()106 sptr<WindowProperty> GetWindowProperty() override
107 {
108 return nullptr;
109 }
NotifyTouchOutside()110 WMError NotifyTouchOutside() override
111 {
112 return WMError::WM_OK;
113 }
NotifyScreenshot()114 WMError NotifyScreenshot() override
115 {
116 return WMError::WM_OK;
117 }
NotifyDestroy(void)118 WMError NotifyDestroy(void) override
119 {
120 return WMError::WM_OK;
121 }
NotifyForeground(void)122 WMError NotifyForeground(void) override
123 {
124 return WMError::WM_OK;
125 }
NotifyBackground(void)126 WMError NotifyBackground(void) override
127 {
128 return WMError::WM_OK;
129 }
UpdateZoomTransform(const Transform & trans,bool isDisplayZoomOn)130 WMError UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn) override
131 {
132 return WMError::WM_OK;
133 }
DumpInfo(const std::vector<std::string> & params)134 WMError DumpInfo(const std::vector<std::string>& params) override
135 {
136 return WMError::WM_OK;
137 }
NotifyWindowClientPointUp(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)138 WMError NotifyWindowClientPointUp(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) override
139 {
140 return WMError::WM_OK;
141 }
RestoreSplitWindowMode(uint32_t mode)142 WMError RestoreSplitWindowMode(uint32_t mode) override
143 {
144 return WMError::WM_OK;
145 }
146 RunnableFuture<AvoidArea> statusBarAvoidAreaFuture_;
147 RunnableFuture<AvoidArea> keyboardAvoidAreaFuture_;
148
AsObject()149 sptr<IRemoteObject> AsObject() override
150 {
151 return nullptr;
152 }
153 };
154
SetUpTestCase()155 void AvoidAreaControllerTest::SetUpTestCase()
156 {
157 auto display = DisplayManager::GetInstance().GetDefaultDisplay();
158 ASSERT_TRUE((display != nullptr));
159 WLOGFI("GetDefaultDisplay: id %{public}" PRIu64", w %{public}d, h %{public}d, fps %{public}u",
160 display->GetId(), display->GetWidth(), display->GetHeight(), display->GetRefreshRate());
161 screenRect = { 0, 0, static_cast<uint32_t>(display->GetWidth()), static_cast<uint32_t>(display->GetHeight()) };
162 auto barHeight = static_cast<uint32_t>(screenRect.height_ * BARRATIO);
163 Rect statusBarRect = { 0, 0, screenRect.width_, barHeight };
164 Rect navigationRect = { 0, static_cast<int32_t>(screenRect.height_ - barHeight), screenRect.width_, barHeight };
165
166 sptr<WindowProperty> statusbarProperty = new WindowProperty();
167 statusbarProperty->SetWindowId(100u);
168 statusbarProperty->SetWindowName("status bar");
169 statusbarProperty->SetWindowType(WindowType::WINDOW_TYPE_STATUS_BAR);
170 statusbarProperty->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
171 statusbarProperty->SetWindowRect(statusBarRect);
172 sptr<WindowListener> windowListener = new WindowListener();
173 statusbarWindowNode = new WindowNode(statusbarProperty, windowListener, nullptr);
174
175 sptr<WindowProperty> navigationBarProperty = new WindowProperty();
176 navigationBarProperty->SetWindowId(101u);
177 navigationBarProperty->SetWindowName("navigation bar");
178 navigationBarProperty->SetWindowType(WindowType::WINDOW_TYPE_NAVIGATION_BAR);
179 navigationBarProperty->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
180 navigationBarProperty->SetWindowRect(navigationRect);
181 windowListener = new WindowListener();
182 navigationBarWindowNode = new WindowNode(navigationBarProperty, windowListener, nullptr);
183
184 sptr<WindowProperty> keyboardProperty = new WindowProperty();
185 keyboardProperty->SetWindowId(101u);
186 keyboardProperty->SetWindowName("keyboard bar");
187 keyboardProperty->SetWindowType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
188 keyboardProperty->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
189 Rect keyboardRect = { 0, static_cast<int32_t>(screenRect.height_ / 2), screenRect.width_, screenRect.height_ / 2 };
190 keyboardProperty->SetWindowRect(keyboardRect);
191 windowListener = new WindowListener();
192 keyboardWindowNode = new WindowNode(keyboardProperty, windowListener, nullptr);
193 }
194
TearDownTestCase()195 void AvoidAreaControllerTest::TearDownTestCase()
196 {
197 }
198
SetUp()199 void AvoidAreaControllerTest::SetUp()
200 {
201 }
202
TearDown()203 void AvoidAreaControllerTest::TearDown()
204 {
205 }
206
CheckSameArea(AvoidArea avoidArea,Rect t,Rect l,Rect r,Rect b)207 bool CheckSameArea(AvoidArea avoidArea, Rect t, Rect l, Rect r, Rect b)
208 {
209 return avoidArea.topRect_ == t && avoidArea.bottomRect_ == b
210 && avoidArea.leftRect_ == l && avoidArea.rightRect_ == r;
211 }
212
createWindowProperty(uint32_t windowId,const std::string & windowName,WindowType type,WindowMode mode,const Rect & screenRect)213 sptr<WindowProperty> createWindowProperty(uint32_t windowId, const std::string& windowName,
214 WindowType type, WindowMode mode, const Rect& screenRect)
215 {
216 sptr<WindowProperty> property = new WindowProperty();
217 property->SetWindowId(windowId);
218 property->SetWindowName(windowName);
219 property->SetWindowType(type);
220 property->SetWindowMode(mode);
221 property->SetWindowRect(screenRect);
222 return property;
223 }
224
225 namespace {
226 /**
227 * @tc.name: AvoidArea01
228 * @tc.desc: Read and write avoidArea test
229 * @tc.type: FUNC
230 */
231 HWTEST_F(AvoidAreaControllerTest, AvoidArea01, Function | SmallTest | Level2)
232 {
233 AvoidArea avoidarea;
234 Parcel parcel;
235 AvoidArea* readArea = AvoidArea::Unmarshalling(parcel);
236 ASSERT_EQ(true, readArea == nullptr);
237 ASSERT_EQ(true, avoidarea.Marshalling(parcel));
238 }
239
240 /**
241 * @tc.name: GetSystemBarAvoidArea01
242 * @tc.desc: Get avoid areas with TYPE_SYSTEM
243 * @tc.type: FUNC
244 */
245 HWTEST_F(AvoidAreaControllerTest, GetSystemBarAvoidArea01, Function | SmallTest | Level2)
246 {
247 sptr<WindowProperty> property = createWindowProperty(110u, "test",
248 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
249 sptr<WindowListener> listener = new WindowListener();
250 sptr<WindowNode> appWindow = new WindowNode(property, listener, nullptr);
251 uint32_t focusedWindow = appWindow->GetWindowId();
252 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
253 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
254 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
255 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
256 auto avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_SYSTEM);
257 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(),
258 EMPTY_RECT, EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
259
260 // set rect
261 Rect statusBarRect = statusbarWindowNode->GetWindowRect();
262 Rect navigationBarRect = navigationBarWindowNode->GetWindowRect();
263 Rect windowRect = { 0, static_cast<int32_t>(statusBarRect.height_), statusBarRect.width_,
264 static_cast<uint32_t>(navigationBarRect.posY_ - statusBarRect.height_) };
265 property->SetWindowRect(windowRect);
266 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_SYSTEM);
267 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
268
269 // restore rect
270 property->SetWindowRect(screenRect);
271 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_SYSTEM);
272 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(),
273 EMPTY_RECT, EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
274
275 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
276 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
277 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
278 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_SYSTEM);
279 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
280 }
281
282 /**
283 * @tc.name: SystemBarAvoidArea02
284 * @tc.desc: Get avoid areas with listener, TYPE_SYSTEM.
285 * @tc.type: FUNC
286 */
287 HWTEST_F(AvoidAreaControllerTest, SystemBarAvoidArea02, Function | SmallTest | Level2)
288 {
289 sptr<WindowProperty> property = createWindowProperty(110u, "test",
290 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
291 sptr<WindowListener> windowListener = new WindowListener();
292 sptr<WindowNode> appWindow = new WindowNode(property, windowListener, nullptr);
293 uint32_t focusedWindow = appWindow->GetWindowId();
294 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
295 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
296 avoidAreaController->UpdateAvoidAreaListener(appWindow, true);
297
298 // add status bar
299 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
300 auto avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
301 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
302 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(),
303 EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
304
305 // add navigation bar
306 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
307 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
308 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
309 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(), EMPTY_RECT,
310 EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
311
312 // update appWindow rect
313 Rect statusBarRect = statusbarWindowNode->GetWindowRect();
314 Rect navigationBarRect = navigationBarWindowNode->GetWindowRect();
315 Rect windowRect = { 0, static_cast<int32_t>(statusBarRect.height_), statusBarRect.width_,
316 static_cast<uint32_t>(navigationBarRect.posY_ - statusBarRect.height_) };
317 property->SetWindowRect(windowRect);
318 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_UPDATE, nullptr);
319 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
320 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
321 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
322
323 // restore appWindow rect
324 property->SetWindowRect(screenRect);
325 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_UPDATE, nullptr);
326 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
327 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
328 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(),
329 EMPTY_RECT, EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
330
331 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
332 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
333 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
334 }
335
336 /**
337 * @tc.name: SystemBarAvoidArea03
338 * @tc.desc: Get avoid areas with listener, TYPE_SYSTEM.
339 * @tc.type: FUNC
340 */
341 HWTEST_F(AvoidAreaControllerTest, SystemBarAvoidArea03, Function | SmallTest | Level2)
342 {
343 sptr<WindowProperty> property = createWindowProperty(110u, "test",
344 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
345 sptr<WindowListener> windowListener = new WindowListener();
346 sptr<WindowNode> appWindow = new WindowNode(property, windowListener, nullptr);
347 uint32_t focusedWindow = appWindow->GetWindowId();
348 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
349 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
350 avoidAreaController->UpdateAvoidAreaListener(appWindow, true);
351
352 // add status bar
353 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
354 auto avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
355 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
356 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(), EMPTY_RECT,
357 EMPTY_RECT, EMPTY_RECT));
358
359 // add navigation bar
360 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
361 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
362 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
363 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(), EMPTY_RECT,
364 EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
365
366 // remove status bar
367 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
368 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
369 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
370 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
371 navigationBarWindowNode->GetWindowRect()));
372
373 // remove navigation bar
374 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
375 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
376 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
377 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
378 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
379 }
380
381 /**
382 * @tc.name: SystemBarAvoidArea01
383 * @tc.desc: Get avoid areas with listener, TYPE_SYSTEM.
384 * @tc.type: FUNC
385 */
386 HWTEST_F(AvoidAreaControllerTest, SystemBarAvoidArea01, Function | SmallTest | Level2)
387 {
388 sptr<WindowProperty> property = createWindowProperty(110u, "test",
389 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
390 sptr<WindowListener> windowListener = new WindowListener();
391 sptr<WindowNode> appWindow = new WindowNode(property, windowListener, nullptr);
392 uint32_t focusedWindow = appWindow->GetWindowId();
393 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
394 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
395 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
396 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
397 avoidAreaController->UpdateAvoidAreaListener(appWindow, true);
398
399 // update status bar window Rect
400 Rect statusbarWindowNodeRect = statusbarWindowNode->GetWindowRect();
401 statusbarWindowNode->SetWindowRect(EMPTY_RECT);
402 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_UPDATE,
__anon3fa4d67d0302(sptr<WindowNode> windowNode) 403 [](sptr<WindowNode> windowNode) { return true; });
404 auto avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
405 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
406 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
407 navigationBarWindowNode->GetWindowRect()));
408
409 // update navigation bar window Rect
410 Rect navigationBarWindowNodeRect = navigationBarWindowNode->GetWindowRect();
411 navigationBarWindowNode->SetWindowRect(EMPTY_RECT);
412 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_UPDATE,
__anon3fa4d67d0402(sptr<WindowNode> windowNode) 413 [](sptr<WindowNode> windowNode) { return true; });
414 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
415 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
416 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
417
418 // restore status bar window Rect
419 statusbarWindowNode->SetWindowRect(statusbarWindowNodeRect);
420 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_UPDATE, nullptr);
421 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
422 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
423 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(), EMPTY_RECT,
424 EMPTY_RECT, EMPTY_RECT));
425
426 // restore navigation bar window Rect
427 navigationBarWindowNode->SetWindowRect(navigationBarWindowNodeRect);
428 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_UPDATE, nullptr);
429 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
430 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
431 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(), EMPTY_RECT,
432 EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
433
434 // remove status bar
435 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
436 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
437 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
438 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
439 navigationBarWindowNode->GetWindowRect()));
440
441 // remove navigation bar
442 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
443 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
444 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
445 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
446 }
447
448 /**
449 * @tc.name: KeyboardAvoidArea01
450 * @tc.desc: Get avoid areas with TYPE_KEYBOARD.
451 * @tc.type: FUNC
452 */
453 HWTEST_F(AvoidAreaControllerTest, KeyboardAvoidArea01, Function | SmallTest | Level2)
454 {
455 sptr<WindowProperty> property = createWindowProperty(110u, "test",
456 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
457 sptr<WindowListener> listener = new WindowListener();
458 sptr<WindowNode> appWindow = new WindowNode(property, listener, nullptr);
459 uint32_t focusedWindow = 0u;
460 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
461 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
462
463 uint32_t start = static_cast<uint32_t>(WindowMode::WINDOW_MODE_FULLSCREEN);
464 uint32_t end = static_cast<uint32_t>(WindowMode::WINDOW_MODE_FLOATING);
465 for (uint32_t i = start; i <= end; i++) {
466 focusedWindow = 0u;
467 appWindow->SetWindowMode(static_cast<WindowMode>(i));
468 avoidAreaController->ProcessWindowChange(keyboardWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
469 auto avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
470 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
471
472 keyboardWindowNode->SetCallingWindow(appWindow->GetWindowId());
473 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
474 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
475 keyboardWindowNode->GetWindowRect()));
476
477 keyboardWindowNode->SetCallingWindow(0);
478 focusedWindow = appWindow->GetWindowId();
479 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
480 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
481 keyboardWindowNode->GetWindowRect()));
482
483 avoidAreaController->ProcessWindowChange(keyboardWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
484 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
485 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
486 }
487 }
488
489 /**
490 * @tc.name: KeyboardAvoidArea02
491 * @tc.desc: Get avoid areas with listener, TYPE_KEYBOARD.
492 * @tc.type: FUNC
493 */
494 HWTEST_F(AvoidAreaControllerTest, KeyboardAvoidArea02, Function | SmallTest | Level2)
495 {
496 sptr<WindowProperty> property = createWindowProperty(110u, "test",
497 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
498 sptr<WindowListener> listener = new WindowListener();
499 sptr<WindowNode> appWindow = new WindowNode(property, listener, nullptr);
500 uint32_t focusedWindow = appWindow->GetWindowId();
501 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
502 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
503 avoidAreaController->UpdateAvoidAreaListener(appWindow, true);
504 uint32_t start = static_cast<uint32_t>(WindowMode::WINDOW_MODE_FULLSCREEN);
505 uint32_t end = static_cast<uint32_t>(WindowMode::WINDOW_MODE_FLOATING);
506 for (uint32_t i = start; i <= end; i++) {
507 avoidAreaController->ProcessWindowChange(keyboardWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
508 auto avoidArea = listener->keyboardAvoidAreaFuture_.GetResult(TIME_OUT);
509 listener->keyboardAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
510 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
511 keyboardWindowNode->GetWindowRect()));
512 avoidAreaController->ProcessWindowChange(keyboardWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
513 avoidArea = listener->keyboardAvoidAreaFuture_.GetResult(TIME_OUT);
514 listener->keyboardAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
515 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
516 }
517 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
518 }
519 /**
520 * @tc.name: KeyboardAvoidArea02
521 * @tc.desc: Get avoid areas with listener, TYPE_KEYBOARD.
522 * @tc.type: FUNC
523 */
524 HWTEST_F(AvoidAreaControllerTest, UpdateAvoidAreaListener01, Function | SmallTest | Level2)
525 {
526 sptr<WindowProperty> property = createWindowProperty(110u, "test",
527 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
528 sptr<WindowListener> listener = new WindowListener();
529 sptr<WindowNode> appWindow = new WindowNode(property, listener, nullptr);
530 uint32_t focusedWindow = appWindow->GetWindowId();
531 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
532
533 avoidAreaController->avoidAreaListenerNodes_.clear();
534 avoidAreaController->lastUpdatedAvoidArea_.clear();
535 avoidAreaController->avoidAreaListenerNodes_.insert(appWindow);
536 auto avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
537 std::map<AvoidAreaType, AvoidArea> type_area_map;
538 auto pair = std::make_pair(AvoidAreaType::TYPE_KEYBOARD, avoidArea);
539 type_area_map.insert(pair);
540 avoidAreaController->lastUpdatedAvoidArea_.insert(std::make_pair(focusedWindow, type_area_map));
541 avoidAreaController->UpdateAvoidAreaListener(appWindow, false);
542 ASSERT_EQ(0, avoidAreaController->avoidAreaListenerNodes_.size());
543 ASSERT_EQ(0, avoidAreaController->lastUpdatedAvoidArea_.size());
544
545 sptr<WindowNode> node = nullptr;
546 avoidAreaController->UpdateAvoidAreaListener(node, true);
547 ASSERT_EQ(0, avoidAreaController->avoidAreaListenerNodes_.size());
548 }
549 }
550 } // namespace Rosen
551 } // namespace OHOS
552