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