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