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 }
UpdateWindowModeSupportInfo(uint32_t modeSupportInfo)83 WMError UpdateWindowModeSupportInfo(uint32_t modeSupportInfo) 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 {}
161 };
162
SetUpTestCase()163 void AvoidAreaControllerTest::SetUpTestCase()
164 {
165 auto display = DisplayManager::GetInstance().GetDefaultDisplay();
166 ASSERT_TRUE((display != nullptr));
167 WLOGI("GetDefaultDisplay: id %{public}" PRIu64", w %{public}d, h %{public}d, fps %{public}u",
168 display->GetId(), display->GetWidth(), display->GetHeight(), display->GetRefreshRate());
169 screenRect = { 0, 0, static_cast<uint32_t>(display->GetWidth()), static_cast<uint32_t>(display->GetHeight()) };
170 auto barHeight = static_cast<uint32_t>(screenRect.height_ * BARRATIO);
171 Rect statusBarRect = { 0, 0, screenRect.width_, barHeight };
172 Rect navigationRect = { 0, static_cast<int32_t>(screenRect.height_ - barHeight), screenRect.width_, barHeight };
173
174 sptr<WindowProperty> statusbarProperty = new WindowProperty();
175 statusbarProperty->SetWindowId(100u);
176 statusbarProperty->SetWindowName("status bar");
177 statusbarProperty->SetWindowType(WindowType::WINDOW_TYPE_STATUS_BAR);
178 statusbarProperty->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
179 statusbarProperty->SetWindowRect(statusBarRect);
180 sptr<WindowListener> windowListener = new WindowListener();
181 statusbarWindowNode = new WindowNode(statusbarProperty, windowListener, nullptr);
182
183 sptr<WindowProperty> navigationBarProperty = new WindowProperty();
184 navigationBarProperty->SetWindowId(101u);
185 navigationBarProperty->SetWindowName("navigation bar");
186 navigationBarProperty->SetWindowType(WindowType::WINDOW_TYPE_NAVIGATION_BAR);
187 navigationBarProperty->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
188 navigationBarProperty->SetWindowRect(navigationRect);
189 windowListener = new WindowListener();
190 navigationBarWindowNode = new WindowNode(navigationBarProperty, windowListener, nullptr);
191
192 sptr<WindowProperty> keyboardProperty = new WindowProperty();
193 keyboardProperty->SetWindowId(101u);
194 keyboardProperty->SetWindowName("keyboard bar");
195 keyboardProperty->SetWindowType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
196 keyboardProperty->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
197 Rect keyboardRect = { 0, static_cast<int32_t>(screenRect.height_ / 2), screenRect.width_, screenRect.height_ / 2 };
198 keyboardProperty->SetWindowRect(keyboardRect);
199 windowListener = new WindowListener();
200 keyboardWindowNode = new WindowNode(keyboardProperty, windowListener, nullptr);
201 }
202
TearDownTestCase()203 void AvoidAreaControllerTest::TearDownTestCase()
204 {
205 }
206
SetUp()207 void AvoidAreaControllerTest::SetUp()
208 {
209 }
210
TearDown()211 void AvoidAreaControllerTest::TearDown()
212 {
213 }
214
CheckSameArea(AvoidArea avoidArea,Rect t,Rect l,Rect r,Rect b)215 bool CheckSameArea(AvoidArea avoidArea, Rect t, Rect l, Rect r, Rect b)
216 {
217 return avoidArea.topRect_ == t && avoidArea.bottomRect_ == b
218 && avoidArea.leftRect_ == l && avoidArea.rightRect_ == r;
219 }
220
createWindowProperty(uint32_t windowId,const std::string & windowName,WindowType type,WindowMode mode,const Rect & screenRect)221 sptr<WindowProperty> createWindowProperty(uint32_t windowId, const std::string& windowName,
222 WindowType type, WindowMode mode, const Rect& screenRect)
223 {
224 sptr<WindowProperty> property = new WindowProperty();
225 property->SetWindowId(windowId);
226 property->SetWindowName(windowName);
227 property->SetWindowType(type);
228 property->SetWindowMode(mode);
229 property->SetWindowRect(screenRect);
230 return property;
231 }
232
233 namespace {
234 /**
235 * @tc.name: AvoidArea01
236 * @tc.desc: Read and write avoidArea test
237 * @tc.type: FUNC
238 */
239 HWTEST_F(AvoidAreaControllerTest, AvoidArea01, Function | SmallTest | Level2)
240 {
241 AvoidArea avoidarea;
242 Parcel parcel;
243 AvoidArea* readArea = AvoidArea::Unmarshalling(parcel);
244 ASSERT_EQ(true, readArea == nullptr);
245 ASSERT_EQ(true, avoidarea.Marshalling(parcel));
246 }
247
248 /**
249 * @tc.name: GetSystemBarAvoidArea01
250 * @tc.desc: Get avoid areas with TYPE_SYSTEM
251 * @tc.type: FUNC
252 */
253 HWTEST_F(AvoidAreaControllerTest, GetSystemBarAvoidArea01, Function | SmallTest | Level2)
254 {
255 sptr<WindowProperty> property = createWindowProperty(110u, "test",
256 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
257 sptr<WindowListener> listener = new WindowListener();
258 sptr<WindowNode> appWindow = new WindowNode(property, listener, nullptr);
259 uint32_t focusedWindow = appWindow->GetWindowId();
260 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
261 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
262 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
263 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
264 auto avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_SYSTEM);
265 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(),
266 EMPTY_RECT, EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
267
268 // set rect
269 Rect statusBarRect = statusbarWindowNode->GetWindowRect();
270 Rect navigationBarRect = navigationBarWindowNode->GetWindowRect();
271 Rect windowRect = { 0, static_cast<int32_t>(statusBarRect.height_), statusBarRect.width_,
272 static_cast<uint32_t>(navigationBarRect.posY_ - statusBarRect.height_) };
273 property->SetWindowRect(windowRect);
274 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_SYSTEM);
275 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
276
277 // restore rect
278 property->SetWindowRect(screenRect);
279 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_SYSTEM);
280 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(),
281 EMPTY_RECT, EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
282
283 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
284 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
285 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
286 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_SYSTEM);
287 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
288 }
289
290 /**
291 * @tc.name: SystemBarAvoidArea02
292 * @tc.desc: Get avoid areas with listener, TYPE_SYSTEM.
293 * @tc.type: FUNC
294 */
295 HWTEST_F(AvoidAreaControllerTest, SystemBarAvoidArea02, Function | SmallTest | Level2)
296 {
297 sptr<WindowProperty> property = createWindowProperty(110u, "test",
298 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
299 sptr<WindowListener> windowListener = new WindowListener();
300 sptr<WindowNode> appWindow = new WindowNode(property, windowListener, nullptr);
301 uint32_t focusedWindow = appWindow->GetWindowId();
302 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
303 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
304 avoidAreaController->UpdateAvoidAreaListener(appWindow, true);
305
306 // add status bar
307 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
308 auto avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
309 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
310 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(),
311 EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
312
313 // add navigation bar
314 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
315 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
316 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
317 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(), EMPTY_RECT,
318 EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
319
320 // update appWindow rect
321 Rect statusBarRect = statusbarWindowNode->GetWindowRect();
322 Rect navigationBarRect = navigationBarWindowNode->GetWindowRect();
323 Rect windowRect = { 0, static_cast<int32_t>(statusBarRect.height_), statusBarRect.width_,
324 static_cast<uint32_t>(navigationBarRect.posY_ - statusBarRect.height_) };
325 property->SetWindowRect(windowRect);
326 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_UPDATE, nullptr);
327 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
328 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
329 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
330
331 // restore appWindow rect
332 property->SetWindowRect(screenRect);
333 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_UPDATE, nullptr);
334 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
335 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
336 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(),
337 EMPTY_RECT, EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
338
339 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
340 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
341 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
342 }
343
344 /**
345 * @tc.name: SystemBarAvoidArea03
346 * @tc.desc: Get avoid areas with listener, TYPE_SYSTEM.
347 * @tc.type: FUNC
348 */
349 HWTEST_F(AvoidAreaControllerTest, SystemBarAvoidArea03, Function | SmallTest | Level2)
350 {
351 sptr<WindowProperty> property = createWindowProperty(110u, "test",
352 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
353 sptr<WindowListener> windowListener = new WindowListener();
354 sptr<WindowNode> appWindow = new WindowNode(property, windowListener, nullptr);
355 uint32_t focusedWindow = appWindow->GetWindowId();
356 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
357 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
358 avoidAreaController->UpdateAvoidAreaListener(appWindow, true);
359
360 // add status bar
361 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
362 auto avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
363 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
364 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(), EMPTY_RECT,
365 EMPTY_RECT, EMPTY_RECT));
366
367 // add navigation bar
368 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
369 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
370 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
371 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(), EMPTY_RECT,
372 EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
373
374 // remove status bar
375 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
376 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
377 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
378 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
379 navigationBarWindowNode->GetWindowRect()));
380
381 // remove navigation bar
382 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
383 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
384 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
385 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
386 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
387 }
388
389 /**
390 * @tc.name: SystemBarAvoidArea01
391 * @tc.desc: Get avoid areas with listener, TYPE_SYSTEM.
392 * @tc.type: FUNC
393 */
394 HWTEST_F(AvoidAreaControllerTest, SystemBarAvoidArea01, Function | SmallTest | Level2)
395 {
396 sptr<WindowProperty> property = createWindowProperty(110u, "test",
397 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
398 sptr<WindowListener> windowListener = new WindowListener();
399 sptr<WindowNode> appWindow = new WindowNode(property, windowListener, nullptr);
400 uint32_t focusedWindow = appWindow->GetWindowId();
401 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
402 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
403 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
404 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
405 avoidAreaController->UpdateAvoidAreaListener(appWindow, true);
406
407 // update status bar window Rect
408 Rect statusbarWindowNodeRect = statusbarWindowNode->GetWindowRect();
409 statusbarWindowNode->SetWindowRect(EMPTY_RECT);
410 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_UPDATE,
__anonb5f8e95d0302(sptr<WindowNode> windowNode) 411 [](sptr<WindowNode> windowNode) { return true; });
412 auto avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
413 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
414 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
415 navigationBarWindowNode->GetWindowRect()));
416
417 // update navigation bar window Rect
418 Rect navigationBarWindowNodeRect = navigationBarWindowNode->GetWindowRect();
419 navigationBarWindowNode->SetWindowRect(EMPTY_RECT);
420 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_UPDATE,
__anonb5f8e95d0402(sptr<WindowNode> windowNode) 421 [](sptr<WindowNode> windowNode) { return true; });
422 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
423 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
424 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
425
426 // restore status bar window Rect
427 statusbarWindowNode->SetWindowRect(statusbarWindowNodeRect);
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, EMPTY_RECT));
433
434 // restore navigation bar window Rect
435 navigationBarWindowNode->SetWindowRect(navigationBarWindowNodeRect);
436 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_UPDATE, nullptr);
437 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
438 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
439 ASSERT_EQ(true, CheckSameArea(avoidArea, statusbarWindowNode->GetWindowRect(), EMPTY_RECT,
440 EMPTY_RECT, navigationBarWindowNode->GetWindowRect()));
441
442 // remove status bar
443 avoidAreaController->ProcessWindowChange(statusbarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
444 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
445 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
446 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
447 navigationBarWindowNode->GetWindowRect()));
448
449 // remove navigation bar
450 avoidAreaController->ProcessWindowChange(navigationBarWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
451 avoidArea = windowListener->statusBarAvoidAreaFuture_.GetResult(TIME_OUT);
452 windowListener->statusBarAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
453 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
454 }
455
456 /**
457 * @tc.name: KeyboardAvoidArea01
458 * @tc.desc: Get avoid areas with TYPE_KEYBOARD.
459 * @tc.type: FUNC
460 */
461 HWTEST_F(AvoidAreaControllerTest, KeyboardAvoidArea01, Function | SmallTest | Level2)
462 {
463 sptr<WindowProperty> property = createWindowProperty(110u, "test",
464 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
465 sptr<WindowListener> listener = new WindowListener();
466 sptr<WindowNode> appWindow = new WindowNode(property, listener, nullptr);
467 uint32_t focusedWindow = 0u;
468 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
469 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
470
471 uint32_t start = static_cast<uint32_t>(WindowMode::WINDOW_MODE_FULLSCREEN);
472 uint32_t end = static_cast<uint32_t>(WindowMode::WINDOW_MODE_FLOATING);
473 for (uint32_t i = start; i <= end; i++) {
474 focusedWindow = 0u;
475 appWindow->SetWindowMode(static_cast<WindowMode>(i));
476 avoidAreaController->ProcessWindowChange(keyboardWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
477 auto avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
478 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
479
480 keyboardWindowNode->SetCallingWindow(appWindow->GetWindowId());
481 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
482 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
483 keyboardWindowNode->GetWindowRect()));
484
485 keyboardWindowNode->SetCallingWindow(0);
486 focusedWindow = appWindow->GetWindowId();
487 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
488 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
489 keyboardWindowNode->GetWindowRect()));
490
491 avoidAreaController->ProcessWindowChange(keyboardWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
492 avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
493 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
494 }
495 }
496
497 /**
498 * @tc.name: KeyboardAvoidArea02
499 * @tc.desc: Get avoid areas with listener, TYPE_KEYBOARD.
500 * @tc.type: FUNC
501 */
502 HWTEST_F(AvoidAreaControllerTest, KeyboardAvoidArea02, Function | SmallTest | Level2)
503 {
504 sptr<WindowProperty> property = createWindowProperty(110u, "test",
505 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
506 sptr<WindowListener> listener = new WindowListener();
507 sptr<WindowNode> appWindow = new WindowNode(property, listener, nullptr);
508 uint32_t focusedWindow = appWindow->GetWindowId();
509 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
510 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_ADD, nullptr);
511 avoidAreaController->UpdateAvoidAreaListener(appWindow, true);
512 uint32_t start = static_cast<uint32_t>(WindowMode::WINDOW_MODE_FULLSCREEN);
513 uint32_t end = static_cast<uint32_t>(WindowMode::WINDOW_MODE_FLOATING);
514 for (uint32_t i = start; i <= end; i++) {
515 avoidAreaController->ProcessWindowChange(keyboardWindowNode, AvoidControlType::AVOID_NODE_ADD, nullptr);
516 auto avoidArea = listener->keyboardAvoidAreaFuture_.GetResult(TIME_OUT);
517 listener->keyboardAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
518 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT,
519 keyboardWindowNode->GetWindowRect()));
520 avoidAreaController->ProcessWindowChange(keyboardWindowNode, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
521 avoidArea = listener->keyboardAvoidAreaFuture_.GetResult(TIME_OUT);
522 listener->keyboardAvoidAreaFuture_.Reset(EMPTY_AVOID_AREA);
523 ASSERT_EQ(true, CheckSameArea(avoidArea, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT, EMPTY_RECT));
524 }
525 avoidAreaController->ProcessWindowChange(appWindow, AvoidControlType::AVOID_NODE_REMOVE, nullptr);
526 }
527 /**
528 * @tc.name: KeyboardAvoidArea02
529 * @tc.desc: Get avoid areas with listener, TYPE_KEYBOARD.
530 * @tc.type: FUNC
531 */
532 HWTEST_F(AvoidAreaControllerTest, UpdateAvoidAreaListener01, Function | SmallTest | Level2)
533 {
534 sptr<WindowProperty> property = createWindowProperty(110u, "test",
535 WindowType::APP_WINDOW_BASE, WindowMode::WINDOW_MODE_FULLSCREEN, screenRect);
536 sptr<WindowListener> listener = new WindowListener();
537 sptr<WindowNode> appWindow = new WindowNode(property, listener, nullptr);
538 uint32_t focusedWindow = appWindow->GetWindowId();
539 sptr<AvoidAreaController> avoidAreaController = new AvoidAreaController(focusedWindow);
540
541 avoidAreaController->avoidAreaListenerNodes_.clear();
542 avoidAreaController->lastUpdatedAvoidArea_.clear();
543 avoidAreaController->avoidAreaListenerNodes_.insert(appWindow);
544 auto avoidArea = avoidAreaController->GetAvoidAreaByType(appWindow, AvoidAreaType::TYPE_KEYBOARD);
545 std::map<AvoidAreaType, AvoidArea> type_area_map;
546 auto pair = std::make_pair(AvoidAreaType::TYPE_KEYBOARD, avoidArea);
547 type_area_map.insert(pair);
548 avoidAreaController->lastUpdatedAvoidArea_.insert(std::make_pair(focusedWindow, type_area_map));
549 avoidAreaController->UpdateAvoidAreaListener(appWindow, false);
550 ASSERT_EQ(0, avoidAreaController->avoidAreaListenerNodes_.size());
551 ASSERT_EQ(0, avoidAreaController->lastUpdatedAvoidArea_.size());
552
553 sptr<WindowNode> node = nullptr;
554 avoidAreaController->UpdateAvoidAreaListener(node, true);
555 ASSERT_EQ(0, avoidAreaController->avoidAreaListenerNodes_.size());
556 }
557 }
558 } // namespace Rosen
559 } // namespace OHOS
560