• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "window_node_container.h"
17 
18 #include <ability_manager_client.h>
19 #include <algorithm>
20 #include <cinttypes>
21 #include <ctime>
22 #include <display_power_mgr_client.h>
23 #include <power_mgr_client.h>
24 
25 #include "common_event_manager.h"
26 #include "display_manager_service_inner.h"
27 #include "dm_common.h"
28 #include "window_helper.h"
29 #include "window_inner_manager.h"
30 #include "window_layout_policy_cascade.h"
31 #include "window_layout_policy_tile.h"
32 #include "window_manager_agent_controller.h"
33 #include "window_manager_hilog.h"
34 #include "wm_common.h"
35 #include "wm_common_inner.h"
36 #include "wm_trace.h"
37 
38 namespace OHOS {
39 namespace Rosen {
40 namespace {
41     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowNodeContainer"};
42     constexpr int WINDOW_NAME_MAX_LENGTH = 10;
43     const std::string SPLIT_SCREEN_EVENT_NAME = "common.event.SPLIT_SCREEN";
44     const char DISABLE_WINDOW_ANIMATION_PATH[] = "/etc/disable_window_animation";
45     constexpr uint32_t MAX_BRIGHTNESS = 255;
46 }
47 
WindowNodeContainer(DisplayId displayId,uint32_t width,uint32_t height)48 WindowNodeContainer::WindowNodeContainer(DisplayId displayId, uint32_t width, uint32_t height) : displayId_(displayId)
49 {
50     displayRect_ = {
51         .posX_ = 0,
52         .posY_ = 0,
53         .width_ = width,
54         .height_ = height
55     };
56     layoutPolicys_[WindowLayoutMode::CASCADE] =
57         new WindowLayoutPolicyCascade(displayRect_, displayId_,
58             belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_);
59     layoutPolicys_[WindowLayoutMode::TILE] =
60         new WindowLayoutPolicyTile(displayRect_, displayId_,
61             belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_);
62     layoutPolicy_ = layoutPolicys_[WindowLayoutMode::CASCADE];
63     layoutPolicy_->Launch();
64     UpdateAvoidAreaFunc func = std::bind(&WindowNodeContainer::OnAvoidAreaChange, this, std::placeholders::_1);
65     avoidController_ = new AvoidAreaController(displayId, func);
66 }
67 
~WindowNodeContainer()68 WindowNodeContainer::~WindowNodeContainer()
69 {
70     Destroy();
71 }
72 
UpdateDisplayRect(uint32_t width,uint32_t height)73 void WindowNodeContainer::UpdateDisplayRect(uint32_t width, uint32_t height)
74 {
75     WLOGFI("update display rect, w/h=%{public}u/%{public}u", width, height);
76     displayRect_ = {
77         .posX_ = 0,
78         .posY_ = 0,
79         .width_ = width,
80         .height_ = height
81     };
82     layoutPolicy_->LayoutWindowTree();
83 }
84 
MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode> & node)85 WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)
86 {
87     std::vector<uint32_t> exceptionalIds = { node->GetWindowId() };
88     std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
89     return MinimizeAppNodeExceptOptions(false, exceptionalIds, exceptionalModes);
90 }
91 
AddWindowNode(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)92 WMError WindowNodeContainer::AddWindowNode(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
93 {
94     if (!node->surfaceNode_) {
95         WLOGFE("surface node is nullptr!");
96         return WMError::WM_ERROR_NULLPTR;
97     }
98     sptr<WindowNode> root = FindRoot(node->GetWindowType());
99     if (root == nullptr) {
100         WLOGFE("root window node is nullptr!");
101         return WMError::WM_ERROR_NULLPTR;
102     }
103     node->requestedVisibility_ = true;
104     if (parentNode != nullptr) { // subwindow
105         if (parentNode->parent_ != root &&
106             !((parentNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) &&
107             (parentNode->parent_ == aboveAppWindowNode_))) {
108             WLOGFE("window type and parent window not match or try to add subwindow to subwindow, which is forbidden");
109             return WMError::WM_ERROR_INVALID_PARAM;
110         }
111         node->currentVisibility_ = parentNode->currentVisibility_;
112     } else { // mainwindow
113         parentNode = root;
114         node->currentVisibility_ = true;
115         for (auto& child : node->children_) {
116             child->currentVisibility_ = child->requestedVisibility_;
117         }
118         if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
119             sysBarNodeMap_[node->GetWindowType()] = node;
120         }
121     }
122     node->parent_ = parentNode;
123 
124     if (node->IsSplitMode()) {
125         WMError ret = EnterSplitWindowMode(node);
126         if (ret != WMError::WM_OK) {
127             WLOGFE("Add split window failed!");
128             return ret;
129         }
130     }
131     UpdateWindowTree(node);
132     if (node->IsSplitMode() || node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
133         RaiseSplitRelatedWindowToTop(node);
134     }
135     UpdateRSTree(node, true);
136     AssignZOrder();
137     layoutPolicy_->AddWindowNode(node);
138     if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
139         avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_ADD);
140         NotifyIfSystemBarRegionChanged();
141     } else {
142         NotifyIfSystemBarTintChanged();
143     }
144     std::vector<sptr<WindowVisibilityInfo>> infos;
145     UpdateWindowVisibilityInfos(infos);
146     DumpScreenWindowTree();
147     NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
148     WLOGFI("AddWindowNode windowId: %{public}d end", node->GetWindowId());
149     return WMError::WM_OK;
150 }
151 
UpdateWindowNode(sptr<WindowNode> & node,WindowUpdateReason reason)152 WMError WindowNodeContainer::UpdateWindowNode(sptr<WindowNode>& node, WindowUpdateReason reason)
153 {
154     if (!node->surfaceNode_) {
155         WLOGFE("surface node is nullptr!");
156         return WMError::WM_ERROR_NULLPTR;
157     }
158     if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) {
159         SwitchLayoutPolicy(WindowLayoutMode::CASCADE);
160     }
161     layoutPolicy_->UpdateWindowNode(node);
162     if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
163         avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_UPDATE);
164         NotifyIfSystemBarRegionChanged();
165     } else {
166         NotifyIfSystemBarTintChanged();
167     }
168     DumpScreenWindowTree();
169     WLOGFI("UpdateWindowNode windowId: %{public}d end", node->GetWindowId());
170     return WMError::WM_OK;
171 }
172 
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowSizeChangeReason reason)173 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowSizeChangeReason reason)
174 {
175     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
176         for (auto& childNode : appWindowNode_->children_) {
177             if (childNode->IsSplitMode()) {
178                 childNode->GetWindowToken()->UpdateWindowRect(childNode->GetLayoutRect(), reason);
179                 childNode->ResetWindowSizeChangeReason();
180                 WLOGFI("Notify split window that the drag action is start or end, windowId: %{public}d, "
181                     "reason: %{public}d", childNode->GetWindowId(), reason);
182             }
183         }
184     } else {
185         node->GetWindowToken()->UpdateWindowRect(node->GetLayoutRect(), reason);
186         node->ResetWindowSizeChangeReason();
187         WLOGFI("Notify window that the drag action is start or end, widnowId: %{public}d "
188             "reason: %{public}d", node->GetWindowId(), reason);
189     }
190 }
191 
UpdateWindowTree(sptr<WindowNode> & node)192 void WindowNodeContainer::UpdateWindowTree(sptr<WindowNode>& node)
193 {
194     WM_FUNCTION_TRACE();
195     node->priority_ = zorderPolicy_->GetWindowPriority(node->GetWindowType());
196     RaiseInputMethodWindowPriorityIfNeeded(node);
197     RaiseShowWhenLockedWindowIfNeeded(node);
198     auto parentNode = node->parent_;
199     auto position = parentNode->children_.end();
200     for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
201         if ((*iter)->priority_ > node->priority_) {
202             position = iter;
203             break;
204         }
205     }
206     parentNode->children_.insert(position, node);
207 }
208 
UpdateRSTree(sptr<WindowNode> & node,bool isAdd)209 bool WindowNodeContainer::UpdateRSTree(sptr<WindowNode>& node, bool isAdd)
210 {
211     WM_FUNCTION_TRACE();
212     static const bool IsWindowAnimationEnabled = ReadIsWindowAnimationEnabledProperty();
213 
214     auto updateRSTreeFunc = [&]() {
215         auto& dms = DisplayManagerServiceInner::GetInstance();
216         if (isAdd) {
217             dms.UpdateRSTree(displayId_, node->surfaceNode_, true);
218             for (auto& child : node->children_) {
219                 if (child->currentVisibility_) {
220                     dms.UpdateRSTree(displayId_, child->surfaceNode_, true);
221                 }
222             }
223         } else {
224             dms.UpdateRSTree(displayId_, node->surfaceNode_, false);
225             for (auto& child : node->children_) {
226                 dms.UpdateRSTree(displayId_, child->surfaceNode_, false);
227             }
228         }
229     };
230 
231     if (IsWindowAnimationEnabled) {
232         // default transition duration: 350ms
233         static const RSAnimationTimingProtocol timingProtocol(350);
234         // default transition curve: EASE OUT
235         static const Rosen::RSAnimationTimingCurve curve = Rosen::RSAnimationTimingCurve::EASE_OUT;
236 
237         // add or remove window with transition animation
238         RSNode::Animate(timingProtocol, curve, updateRSTreeFunc);
239     } else {
240         // add or remove window without animation
241         updateRSTreeFunc();
242     }
243 
244     return true;
245 }
246 
DestroyWindowNode(sptr<WindowNode> & node,std::vector<uint32_t> & windowIds)247 WMError WindowNodeContainer::DestroyWindowNode(sptr<WindowNode>& node, std::vector<uint32_t>& windowIds)
248 {
249     WMError ret = RemoveWindowNode(node);
250     if (ret != WMError::WM_OK) {
251         WLOGFE("RemoveWindowNode failed");
252         return ret;
253     }
254     node->surfaceNode_ = nullptr;
255     windowIds.push_back(node->GetWindowId());
256 
257     for (auto& child : node->children_) { // destroy sub window if exists
258         windowIds.push_back(child->GetWindowId());
259         child->parent_ = nullptr;
260         if (child->surfaceNode_ != nullptr) {
261             WLOGFI("child surfaceNode set nullptr");
262             child->surfaceNode_ = nullptr;
263         }
264     }
265     node->children_.clear();
266     return WMError::WM_OK;
267 }
268 
RemoveWindowNode(sptr<WindowNode> & node)269 WMError WindowNodeContainer::RemoveWindowNode(sptr<WindowNode>& node)
270 {
271     if (node == nullptr) {
272         WLOGFE("window node or surface node is nullptr, invalid");
273         return WMError::WM_ERROR_DESTROYED_OBJECT;
274     }
275     if (node->parent_ == nullptr) {
276         WLOGFW("can't find parent of this node");
277     } else {
278         // remove this node from parent
279         auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node);
280         if (iter != node->parent_->children_.end()) {
281             node->parent_->children_.erase(iter);
282         } else {
283             WLOGFE("can't find this node in parent");
284         }
285         node->parent_ = nullptr;
286     }
287     node->requestedVisibility_ = false;
288     node->currentVisibility_ = false;
289     node->hasDecorated_ = node->isDefultLayoutRect_ ? true : false;
290     node->isCovered_ = true;
291     std::vector<sptr<WindowVisibilityInfo>> infos = {new WindowVisibilityInfo(node->GetWindowId(),
292         node->GetCallingPid(), node->GetCallingUid(), false)};
293     for (auto& child : node->children_) {
294         if (child->currentVisibility_) {
295             child->currentVisibility_ = false;
296             child->isCovered_ = true;
297             infos.emplace_back(new WindowVisibilityInfo(child->GetWindowId(), child->GetCallingPid(),
298                 child->GetCallingUid(), false));
299         }
300     }
301 
302     if (node->IsSplitMode()) {
303         WMError ret = ExitSplitWindowMode(node);
304         if (ret != WMError::WM_OK) {
305             WLOGFE("Remove split window failed!");
306             return ret;
307         }
308     }
309 
310     UpdateRSTree(node, false);
311     layoutPolicy_->RemoveWindowNode(node);
312     if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
313         avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_REMOVE);
314         NotifyIfSystemBarRegionChanged();
315     } else {
316         NotifyIfSystemBarTintChanged();
317     }
318     UpdateWindowVisibilityInfos(infos);
319     DumpScreenWindowTree();
320     NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_REMOVED);
321     RcoveryScreenDefaultOrientationIfNeed();
322     WLOGFI("RemoveWindowNode windowId: %{public}u end", node->GetWindowId());
323     return WMError::WM_OK;
324 }
325 
RcoveryScreenDefaultOrientationIfNeed()326 void WindowNodeContainer::RcoveryScreenDefaultOrientationIfNeed()
327 {
328     if (appWindowNode_->children_.empty()) {
329         WLOGFI("appWindowNode_ child is empty in display  %{public}" PRIu64"", displayId_);
330         DisplayManagerServiceInner::GetInstance().
331             SetOrientationFromWindow(displayId_, Orientation::UNSPECIFIED);
332     }
333 }
334 
Destroy()335 const std::vector<uint32_t>& WindowNodeContainer::Destroy()
336 {
337     removedIds_.clear();
338     for (auto& node : belowAppWindowNode_->children_) {
339         DestroyWindowNode(node, removedIds_);
340     }
341     for (auto& node : appWindowNode_->children_) {
342         DestroyWindowNode(node, removedIds_);
343     }
344     for (auto& node : aboveAppWindowNode_->children_) {
345         DestroyWindowNode(node, removedIds_);
346     }
347     return removedIds_;
348 }
349 
FindRoot(WindowType type) const350 sptr<WindowNode> WindowNodeContainer::FindRoot(WindowType type) const
351 {
352     if (WindowHelper::IsAppWindow(type) || type == WindowType::WINDOW_TYPE_DOCK_SLICE) {
353         return appWindowNode_;
354     }
355     if (WindowHelper::IsBelowSystemWindow(type)) {
356         return belowAppWindowNode_;
357     }
358     if (WindowHelper::IsAboveSystemWindow(type)) {
359         return aboveAppWindowNode_;
360     }
361     return nullptr;
362 }
363 
FindWindowNodeById(uint32_t id) const364 sptr<WindowNode> WindowNodeContainer::FindWindowNodeById(uint32_t id) const
365 {
366     std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
367     for (auto& rootNode : rootNodes) {
368         for (auto& node : rootNode->children_) {
369             if (node->GetWindowId() == id) {
370                 return node;
371             }
372             for (auto& subNode : node->children_) {
373                 if (subNode->GetWindowId() == id) {
374                     return subNode;
375                 }
376             }
377         }
378     }
379     return nullptr;
380 }
381 
UpdateFocusStatus(uint32_t id,bool focused) const382 void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused) const
383 {
384     auto node = FindWindowNodeById(id);
385     if (node == nullptr) {
386         WLOGFW("cannot find focused window id:%{public}d", id);
387     } else {
388         node->GetWindowToken()->UpdateFocusStatus(focused);
389         if (node->abilityToken_ == nullptr) {
390             WLOGFI("abilityToken is null, window : %{public}d", id);
391         }
392         sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(node->GetWindowId(), node->GetDisplayId(),
393             node->GetCallingPid(), node->GetCallingUid(), node->GetWindowType(), node->abilityToken_);
394         WindowManagerAgentController::GetInstance().UpdateFocusChangeInfo(
395             focusChangeInfo, focused);
396     }
397 }
398 
UpdateActiveStatus(uint32_t id,bool isActive) const399 void WindowNodeContainer::UpdateActiveStatus(uint32_t id, bool isActive) const
400 {
401     auto node = FindWindowNodeById(id);
402     if (node == nullptr) {
403         WLOGFE("cannot find active window id: %{public}d", id);
404         return;
405     }
406     node->GetWindowToken()->UpdateActiveStatus(isActive);
407 }
408 
UpdateBrightness(uint32_t id,bool byRemoved)409 void WindowNodeContainer::UpdateBrightness(uint32_t id, bool byRemoved)
410 {
411     auto node = FindWindowNodeById(id);
412     if (node == nullptr) {
413         WLOGFE("cannot find active window id: %{public}d", id);
414         return;
415     }
416 
417     if (!byRemoved) {
418         if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
419             return;
420         }
421     }
422     WLOGFI("brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), node->GetBrightness());
423     if (node->GetBrightness() == UNDEFINED_BRIGHTNESS) {
424         if (GetDisplayBrightness() != node->GetBrightness()) {
425             WLOGFI("adjust brightness with default value");
426             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
427             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
428         }
429         SetBrightnessWindow(INVALID_WINDOW_ID);
430     } else {
431         if (GetDisplayBrightness() != node->GetBrightness()) {
432             WLOGFI("adjust brightness with value: %{public}u", ToOverrideBrightness(node->GetBrightness()));
433             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
434                 ToOverrideBrightness(node->GetBrightness()));
435             SetDisplayBrightness(node->GetBrightness());
436         }
437         SetBrightnessWindow(node->GetWindowId());
438     }
439 }
440 
AssignZOrder()441 void WindowNodeContainer::AssignZOrder()
442 {
443     zOrder_ = 0;
444     WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
445         if (node->surfaceNode_ == nullptr) {
446             WLOGE("AssignZOrder: surfaceNode is nullptr, window Id:%{public}u", node->GetWindowId());
447             return false;
448         }
449         node->surfaceNode_->SetPositionZ(zOrder_);
450         ++zOrder_;
451         return false;
452     };
453     TraverseWindowTree(func, false);
454 }
455 
SetFocusWindow(uint32_t windowId)456 WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
457 {
458     if (focusedWindow_ == windowId) {
459         WLOGFI("focused window do not change, id: %{public}u", windowId);
460         return WMError::WM_DO_NOTHING;
461     }
462     UpdateFocusStatus(focusedWindow_, false);
463     focusedWindow_ = windowId;
464     sptr<WindowNode> node = FindWindowNodeById(windowId);
465     NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
466     UpdateFocusStatus(focusedWindow_, true);
467     return WMError::WM_OK;
468 }
469 
GetFocusWindow() const470 uint32_t WindowNodeContainer::GetFocusWindow() const
471 {
472     return focusedWindow_;
473 }
474 
SetActiveWindow(uint32_t windowId,bool byRemoved)475 WMError WindowNodeContainer::SetActiveWindow(uint32_t windowId, bool byRemoved)
476 {
477     if (activeWindow_ == windowId) {
478         WLOGFI("active window do not change, id: %{public}u", windowId);
479         return WMError::WM_DO_NOTHING;
480     }
481     UpdateActiveStatus(activeWindow_, false);
482     activeWindow_ = windowId;
483     UpdateActiveStatus(activeWindow_, true);
484     UpdateBrightness(activeWindow_, byRemoved);
485     return WMError::WM_OK;
486 }
487 
SetDisplayBrightness(float brightness)488 void WindowNodeContainer::SetDisplayBrightness(float brightness)
489 {
490     displayBrightness_ = brightness;
491 }
492 
GetDisplayBrightness() const493 float WindowNodeContainer::GetDisplayBrightness() const
494 {
495     return displayBrightness_;
496 }
497 
SetBrightnessWindow(uint32_t windowId)498 void WindowNodeContainer::SetBrightnessWindow(uint32_t windowId)
499 {
500     brightnessWindow_ = windowId;
501 }
502 
GetBrightnessWindow() const503 uint32_t WindowNodeContainer::GetBrightnessWindow() const
504 {
505     return brightnessWindow_;
506 }
507 
ToOverrideBrightness(float brightness)508 uint32_t WindowNodeContainer::ToOverrideBrightness(float brightness)
509 {
510     return static_cast<uint32_t>(brightness * MAX_BRIGHTNESS);
511 }
512 
GetActiveWindow() const513 uint32_t WindowNodeContainer::GetActiveWindow() const
514 {
515     return activeWindow_;
516 }
517 
HandleKeepScreenOn(const sptr<WindowNode> & node,bool requireLock)518 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)
519 {
520     if (requireLock && node->keepScreenLock_ == nullptr) {
521         // reset ipc identity
522         std::string identity = IPCSkeleton::ResetCallingIdentity();
523         node->keepScreenLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(node->GetWindowName(),
524             PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
525         // set ipc identity to raw
526         IPCSkeleton::SetCallingIdentity(identity);
527     }
528     if (node->keepScreenLock_ == nullptr) {
529         return;
530     }
531     WLOGFI("handle keep screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), requireLock);
532     ErrCode res;
533     // reset ipc identity
534     std::string identity = IPCSkeleton::ResetCallingIdentity();
535     if (requireLock) {
536         res = node->keepScreenLock_->Lock();
537     } else {
538         res = node->keepScreenLock_->UnLock();
539     }
540     // set ipc identity to raw
541     IPCSkeleton::SetCallingIdentity(identity);
542     if (res != ERR_OK) {
543         WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]", requireLock, res);
544     }
545 }
546 
IsAboveSystemBarNode(sptr<WindowNode> node) const547 bool WindowNodeContainer::IsAboveSystemBarNode(sptr<WindowNode> node) const
548 {
549     int32_t curPriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
550     if ((curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_STATUS_BAR)) &&
551         (curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_NAVIGATION_BAR))) {
552         return true;
553     }
554     return false;
555 }
556 
IsFullImmersiveNode(sptr<WindowNode> node) const557 bool WindowNodeContainer::IsFullImmersiveNode(sptr<WindowNode> node) const
558 {
559     auto mode = node->GetWindowMode();
560     auto flags = node->GetWindowFlags();
561     return mode == WindowMode::WINDOW_MODE_FULLSCREEN &&
562         !(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
563 }
564 
IsSplitImmersiveNode(sptr<WindowNode> node) const565 bool WindowNodeContainer::IsSplitImmersiveNode(sptr<WindowNode> node) const
566 {
567     auto type = node->GetWindowType();
568     return node->IsSplitMode() || type == WindowType::WINDOW_TYPE_DOCK_SLICE;
569 }
570 
GetExpectImmersiveProperty() const571 std::unordered_map<WindowType, SystemBarProperty> WindowNodeContainer::GetExpectImmersiveProperty() const
572 {
573     std::unordered_map<WindowType, SystemBarProperty> sysBarPropMap {
574         { WindowType::WINDOW_TYPE_STATUS_BAR,     SystemBarProperty() },
575         { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() },
576     };
577 
578     std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
579     for (auto& node : rootNodes) {
580         for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); ++iter) {
581             auto& sysBarPropMapNode = (*iter)->GetSystemBarProperty();
582             if (IsAboveSystemBarNode(*iter)) {
583                 continue;
584             }
585             if (IsFullImmersiveNode(*iter)) {
586                 WLOGFI("Top immersive window id: %{public}d. Use full immersive prop", (*iter)->GetWindowId());
587                 for (auto it : sysBarPropMap) {
588                     sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
589                 }
590                 return sysBarPropMap;
591             } else if (IsSplitImmersiveNode(*iter)) {
592                 WLOGFI("Top split window id: %{public}d. Use split immersive prop", (*iter)->GetWindowId());
593                 for (auto it : sysBarPropMap) {
594                     sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
595                     sysBarPropMap[it.first].enable_ = false;
596                 }
597                 return sysBarPropMap;
598             }
599         }
600     }
601 
602     WLOGFI("No immersive window on top. Use default systembar Property");
603     return sysBarPropMap;
604 }
605 
NotifyIfSystemBarTintChanged()606 void WindowNodeContainer::NotifyIfSystemBarTintChanged()
607 {
608     WM_FUNCTION_TRACE();
609     auto expectSystemBarProp = GetExpectImmersiveProperty();
610     SystemBarRegionTints tints;
611     for (auto it : sysBarTintMap_) {
612         auto expectProp = expectSystemBarProp.find(it.first)->second;
613         if (it.second.prop_ == expectProp) {
614             continue;
615         }
616         WLOGFI("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x",
617             static_cast<int32_t>(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_);
618         sysBarTintMap_[it.first].prop_ = expectProp;
619         sysBarTintMap_[it.first].type_ = it.first;
620         tints.emplace_back(sysBarTintMap_[it.first]);
621     }
622     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints);
623 }
624 
NotifyIfSystemBarRegionChanged()625 void WindowNodeContainer::NotifyIfSystemBarRegionChanged()
626 {
627     WM_FUNCTION_TRACE();
628     SystemBarRegionTints tints;
629     for (auto it : sysBarTintMap_) { // split screen mode not support yet
630         auto sysNode = sysBarNodeMap_[it.first];
631         if (sysNode == nullptr || it.second.region_ == sysNode->GetLayoutRect()) {
632             continue;
633         }
634         auto& newRegion = sysNode->GetLayoutRect();
635         sysBarTintMap_[it.first].region_ = newRegion;
636         sysBarTintMap_[it.first].type_ = it.first;
637         tints.emplace_back(sysBarTintMap_[it.first]);
638         WLOGFI("system bar region update, type: %{public}d" \
639             "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
640             static_cast<int32_t>(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_);
641     }
642     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints);
643 }
644 
NotifySystemBarDismiss(sptr<WindowNode> & node)645 void WindowNodeContainer::NotifySystemBarDismiss(sptr<WindowNode>& node)
646 {
647     WM_FUNCTION_TRACE();
648     if (node == nullptr) {
649         WLOGE("could not find window");
650         return;
651     }
652     SystemBarRegionTints tints;
653     auto& sysBarPropMapNode = node->GetSystemBarProperty();
654     for (auto it : sysBarPropMapNode) {
655         it.second.enable_ = false;
656         node->SetSystemBarProperty(it.first, it.second);
657         WLOGFI("set system bar enable to false, id: %{public}u, type: %{public}d",
658             node->GetWindowId(), static_cast<int32_t>(it.first));
659         if (sysBarTintMap_[it.first].prop_.enable_) {
660             sysBarTintMap_[it.first].prop_.enable_ = false;
661             tints.emplace_back(sysBarTintMap_[it.first]);
662             WLOGFI("notify system bar dismiss, type: %{public}d", static_cast<int32_t>(it.first));
663         }
664     }
665     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints);
666 }
667 
NotifySystemBarTints()668 void WindowNodeContainer::NotifySystemBarTints()
669 {
670     WM_FUNCTION_TRACE();
671     SystemBarRegionTints tints;
672     for (auto it : sysBarTintMap_) {
673         WLOGFD("system bar cur notify, type: %{public}d, " \
674             "visible: %{public}d, color: %{public}x | %{public}x, " \
675             "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
676             static_cast<int32_t>(it.first),
677             sysBarTintMap_[it.first].region_.posX_, sysBarTintMap_[it.first].region_.posY_,
678             sysBarTintMap_[it.first].region_.width_, sysBarTintMap_[it.first].region_.height_,
679             sysBarTintMap_[it.first].prop_.enable_,
680             sysBarTintMap_[it.first].prop_.backgroundColor_, sysBarTintMap_[it.first].prop_.contentColor_);
681         tints.push_back(sysBarTintMap_[it.first]);
682     }
683     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints);
684 }
685 
IsTopWindow(uint32_t windowId,sptr<WindowNode> & rootNode) const686 bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const
687 {
688     if (rootNode->children_.empty()) {
689         WLOGFE("root does not have any node");
690         return false;
691     }
692     auto node = *(rootNode->children_.rbegin());
693     if (node == nullptr) {
694         WLOGFE("window tree does not have any node");
695         return false;
696     }
697 
698     for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); iter++) {
699         if ((*iter)->priority_ > 0) {
700             return (*iter)->GetWindowId() == windowId;
701         } else {
702             break;
703         }
704     }
705     return node->GetWindowId() == windowId;
706 }
707 
RaiseOrderedWindowToTop(std::vector<uint32_t> orderedIds,std::vector<sptr<WindowNode>> & windowNodes)708 void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<uint32_t> orderedIds,
709     std::vector<sptr<WindowNode>>& windowNodes)
710 {
711     for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
712         uint32_t wid = (*iter)->GetWindowId();
713         auto idIter = std::find_if(orderedIds.begin(), orderedIds.end(),
714             [wid] (uint32_t id) { return id == wid; });
715         if (idIter != orderedIds.end()) {
716             orderedIds.erase(idIter);
717             sptr<WindowNode> node = *iter;
718             iter = windowNodes.erase(iter);
719             UpdateWindowTree(node);
720             WLOGFI("raise group window to top %{public}d", node->GetWindowId());
721         } else {
722             iter++;
723         }
724     }
725     return;
726 }
727 
RaiseWindowToTop(uint32_t windowId,std::vector<sptr<WindowNode>> & windowNodes)728 void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)
729 {
730     auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
731                              [windowId](sptr<WindowNode> node) {
732                                  return node->GetWindowId() == windowId;
733                              });
734     // raise app node window to top
735     if (iter != windowNodes.end()) {
736         sptr<WindowNode> node = *iter;
737         windowNodes.erase(iter);
738         UpdateWindowTree(node);
739         WLOGFI("raise window to top %{public}d", node->GetWindowId());
740     }
741 }
742 
NotifyAccessibilityWindowInfo(const sptr<WindowNode> & node,WindowUpdateType type) const743 void WindowNodeContainer::NotifyAccessibilityWindowInfo(const sptr<WindowNode>& node, WindowUpdateType type) const
744 {
745     if (node == nullptr) {
746         WLOGFE("window node is null");
747         return;
748     }
749     bool isNeedNotify = false;
750     switch (type) {
751         case WindowUpdateType::WINDOW_UPDATE_ADDED:
752             if (node->currentVisibility_) {
753                 isNeedNotify = true;
754             }
755             break;
756         case WindowUpdateType::WINDOW_UPDATE_FOCUSED:
757             if (node->GetWindowId() == focusedWindow_) {
758                 isNeedNotify = true;
759             }
760             break;
761         case WindowUpdateType::WINDOW_UPDATE_REMOVED:
762             isNeedNotify = true;
763             break;
764         default:
765             break;
766     }
767     if (isNeedNotify) {
768         std::vector<sptr<WindowInfo>> windowList;
769         GetWindowList(windowList);
770         sptr<WindowInfo> windowInfo = new WindowInfo();
771         windowInfo->wid_ = static_cast<int32_t>(node->GetWindowId());
772         windowInfo->windowRect_ = node->GetLayoutRect();
773         windowInfo->focused_ = node->GetWindowId() == focusedWindow_;
774         windowInfo->mode_ = node->GetWindowMode();
775         windowInfo->type_ = node->GetWindowType();
776         sptr<AccessibilityWindowInfo> accessibilityWindowInfo = new AccessibilityWindowInfo();
777         accessibilityWindowInfo->currentWindowInfo_ = windowInfo;
778         accessibilityWindowInfo->windowList_ = windowList;
779         WindowManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityWindowInfo, type);
780     }
781 }
782 
GetWindowList(std::vector<sptr<WindowInfo>> & windowList) const783 void WindowNodeContainer::GetWindowList(std::vector<sptr<WindowInfo>>& windowList) const
784 {
785     std::vector<sptr<WindowNode>> windowNodes;
786     TraverseContainer(windowNodes);
787     for (auto node : windowNodes) {
788         sptr<WindowInfo> windowInfo = new WindowInfo();
789         windowInfo->wid_ = static_cast<int32_t>(node->GetWindowId());
790         windowInfo->windowRect_ = node->GetLayoutRect();
791         windowInfo->focused_ = node->GetWindowId() == focusedWindow_;
792         windowInfo->mode_ = node->GetWindowMode();
793         windowInfo->type_ = node->GetWindowType();
794         windowList.emplace_back(windowInfo);
795     }
796 }
797 
TraverseContainer(std::vector<sptr<WindowNode>> & windowNodes) const798 void WindowNodeContainer::TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const
799 {
800     for (auto& node : belowAppWindowNode_->children_) {
801         TraverseWindowNode(node, windowNodes);
802     }
803     for (auto& node : appWindowNode_->children_) {
804         TraverseWindowNode(node, windowNodes);
805     }
806     for (auto& node : aboveAppWindowNode_->children_) {
807         TraverseWindowNode(node, windowNodes);
808     }
809     std::reverse(windowNodes.begin(), windowNodes.end());
810 }
811 
TraverseWindowNode(sptr<WindowNode> & node,std::vector<sptr<WindowNode>> & windowNodes) const812 void WindowNodeContainer::TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const
813 {
814     if (node == nullptr) {
815         return;
816     }
817     auto iter = node->children_.begin();
818     for (; iter < node->children_.end(); ++iter) {
819         if ((*iter)->priority_ < 0) {
820             windowNodes.emplace_back(*iter);
821         } else {
822             break;
823         }
824     }
825     windowNodes.emplace_back(node);
826     for (; iter < node->children_.end(); ++iter) {
827         windowNodes.emplace_back(*iter);
828     }
829 }
830 
GetAvoidAreaByType(AvoidAreaType avoidAreaType)831 std::vector<Rect> WindowNodeContainer::GetAvoidAreaByType(AvoidAreaType avoidAreaType)
832 {
833     return avoidController_->GetAvoidAreaByType(avoidAreaType);
834 }
835 
OnAvoidAreaChange(const std::vector<Rect> & avoidArea)836 void WindowNodeContainer::OnAvoidAreaChange(const std::vector<Rect>& avoidArea)
837 {
838     layoutPolicy_->UpdateDefaultFoatingRect();
839     for (auto& node : appWindowNode_->children_) {
840         if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && node->GetWindowToken() != nullptr) {
841             // notify client
842             node->GetWindowToken()->UpdateAvoidArea(avoidArea);
843         }
844     }
845 }
846 
DumpScreenWindowTree()847 void WindowNodeContainer::DumpScreenWindowTree()
848 {
849     WLOGFI("-------- display %{public}" PRIu64" dump window info begin---------", displayId_);
850     WLOGFI("WindowName WinId Type Mode Flag ZOrd Orientation [   x    y    w    h]");
851     uint32_t zOrder = zOrder_;
852     WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
853         Rect rect = node->GetLayoutRect();
854         const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
855             node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
856         WLOGI("DumpScreenWindowTree: %{public}10s %{public}5u %{public}4u %{public}4u %{public}4u %{public}4u " \
857             "%{public}11u [%{public}4d %{public}4d %{public}4u %{public}4u]",
858             windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
859             node->GetWindowFlags(), --zOrder, static_cast<uint32_t>(node->GetRequestedOrientation()),
860             rect.posX_, rect.posY_, rect.width_, rect.height_);
861         return false;
862     };
863     TraverseWindowTree(func, true);
864     WLOGFI("-------- display %{public}" PRIu64" dump window info end  ---------", displayId_);
865 }
866 
GetScreenId() const867 uint64_t WindowNodeContainer::GetScreenId() const
868 {
869     return DisplayManagerServiceInner::GetInstance().GetRSScreenId(displayId_);
870 }
871 
GetDisplayId() const872 DisplayId WindowNodeContainer::GetDisplayId() const
873 {
874     return displayId_;
875 }
876 
GetDisplayRect() const877 Rect WindowNodeContainer::GetDisplayRect() const
878 {
879     return displayRect_;
880 }
881 
GetDisplayLimitRect() const882 Rect WindowNodeContainer::GetDisplayLimitRect() const
883 {
884     return layoutPolicy_->GetDisplayLimitRect();
885 }
886 
isVerticalDisplay() const887 bool WindowNodeContainer::isVerticalDisplay() const
888 {
889     return displayRect_.width_ < displayRect_.height_;
890 }
891 
NotifyWindowStateChange(WindowState state,WindowStateChangeReason reason)892 void WindowNodeContainer::NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason)
893 {
894     switch (reason) {
895         case WindowStateChangeReason::KEYGUARD: {
896             int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
897             TraverseAndUpdateWindowState(state, topPriority);
898             break;
899         }
900         default:
901             return;
902     }
903 }
904 
TraverseAndUpdateWindowState(WindowState state,int32_t topPriority)905 void WindowNodeContainer::TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)
906 {
907     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
908     for (auto& node : rootNodes) {
909         UpdateWindowState(node, topPriority, state);
910     }
911 }
912 
UpdateWindowState(sptr<WindowNode> node,int32_t topPriority,WindowState state)913 void WindowNodeContainer::UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)
914 {
915     if (node == nullptr) {
916         return;
917     }
918     if (node->parent_ != nullptr && node->currentVisibility_) {
919         if (node->priority_ < topPriority) {
920             node->GetWindowToken()->UpdateWindowState(state);
921             HandleKeepScreenOn(node, state);
922         }
923     }
924     for (auto& childNode : node->children_) {
925         UpdateWindowState(childNode, topPriority, state);
926     }
927 }
928 
HandleKeepScreenOn(const sptr<WindowNode> & node,WindowState state)929 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)
930 {
931     if (node == nullptr) {
932         WLOGFE("window is invalid");
933         return;
934     }
935     if (state == WindowState::STATE_FROZEN) {
936         HandleKeepScreenOn(node, false);
937     } else if (state == WindowState::STATE_UNFROZEN) {
938         HandleKeepScreenOn(node, node->IsKeepScreenOn());
939     } else {
940         // do nothing
941     }
942 }
943 
FindDividerNode() const944 sptr<WindowNode> WindowNodeContainer::FindDividerNode() const
945 {
946     for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) {
947         if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
948             return *iter;
949         }
950     }
951     return nullptr;
952 }
953 
RaiseSplitRelatedWindowToTop(sptr<WindowNode> & node)954 void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
955 {
956     sptr<WindowNode> deviderNode = nullptr;
957     sptr<WindowNode> primaryNode = nullptr;
958     sptr<WindowNode> secondaryNode = nullptr;
959     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && !pairedWindowMap_.empty()) {
960         deviderNode = node;
961         primaryNode = pairedWindowMap_.begin()->second.pairNode_;
962         secondaryNode = pairedWindowMap_[primaryNode->GetWindowId()].pairNode_;
963         std::vector<uint32_t> raiseNodeIds = {secondaryNode->GetWindowId(), primaryNode->GetWindowId()};
964         // raise primary and secondary window to top, keep raw zorder
965         RaiseOrderedWindowToTop(raiseNodeIds, appWindowNode_->children_);
966         // raise divider final, keep divider on top
967         RaiseWindowToTop(deviderNode->GetWindowId(), appWindowNode_->children_);
968     } else if (!pairedWindowMap_.empty()) {
969         deviderNode = FindDividerNode();
970         primaryNode = node;
971         secondaryNode = pairedWindowMap_.at(primaryNode->GetWindowId()).pairNode_;
972         RaiseWindowToTop(secondaryNode->GetWindowId(), appWindowNode_->children_);
973         RaiseWindowToTop(primaryNode->GetWindowId(), appWindowNode_->children_);
974         if (deviderNode != nullptr) {
975             // raise divider final, keep divider on top
976             RaiseWindowToTop(deviderNode->GetWindowId(), appWindowNode_->children_);
977         }
978     } else {
979         // raise self if not paired
980         RaiseWindowToTop(node->GetWindowId(), appWindowNode_->children_);
981     }
982     AssignZOrder();
983     return;
984 }
985 
RaiseZOrderForAppWindow(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)986 WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
987 {
988     if (node == nullptr) {
989         return WMError::WM_ERROR_NULLPTR;
990     }
991     if (IsTopWindow(node->GetWindowId(), appWindowNode_) || IsTopWindow(node->GetWindowId(), aboveAppWindowNode_)) {
992         WLOGFI("it is already top app window, id: %{public}d", node->GetWindowId());
993         return WMError::WM_ERROR_INVALID_TYPE;
994     }
995     if (WindowHelper::IsSubWindow(node->GetWindowType())) {
996         if (parentNode == nullptr) {
997             WLOGFE("window type is invalid");
998             return WMError::WM_ERROR_NULLPTR;
999         }
1000         RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself
1001         if (parentNode->IsSplitMode()) {
1002             RaiseSplitRelatedWindowToTop(parentNode);
1003         } else {
1004             RaiseWindowToTop(node->GetParentId(), parentNode->parent_->children_); // raise parent window
1005         }
1006     } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
1007         if (node->IsSplitMode()) {
1008             RaiseSplitRelatedWindowToTop(node);
1009         } else {
1010             RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
1011         }
1012     } else {
1013         // do nothing
1014     }
1015     AssignZOrder();
1016     WLOGFI("RaiseZOrderForAppWindow finished");
1017     DumpScreenWindowTree();
1018     return WMError::WM_OK;
1019 }
1020 
GetNextFocusableWindow(uint32_t windowId) const1021 sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
1022 {
1023     sptr<WindowNode> nextFocusableWindow;
1024     bool previousFocusedWindowFound = false;
1025     WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
1026         sptr<WindowNode> node) {
1027         if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable()) {
1028             nextFocusableWindow = node;
1029             return true;
1030         }
1031         if (node->GetWindowId() == windowId) {
1032             previousFocusedWindowFound = true;
1033         }
1034         return false;
1035     };
1036     TraverseWindowTree(func, true);
1037     return nextFocusableWindow;
1038 }
1039 
GetNextActiveWindow(uint32_t windowId) const1040 sptr<WindowNode> WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) const
1041 {
1042     auto currentNode = FindWindowNodeById(windowId);
1043     if (currentNode == nullptr) {
1044         WLOGFE("cannot find window id: %{public}u by tree", windowId);
1045         return nullptr;
1046     }
1047     WLOGFI("current window: [%{public}u, %{public}u]", windowId, static_cast<uint32_t>(currentNode->GetWindowType()));
1048     if (WindowHelper::IsSystemWindow(currentNode->GetWindowType())) {
1049         for (auto& node : appWindowNode_->children_) {
1050             if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1051                 continue;
1052             }
1053             return node;
1054         }
1055         for (auto& node : belowAppWindowNode_->children_) {
1056             if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1057                 return node;
1058             }
1059         }
1060     } else if (WindowHelper::IsAppWindow(currentNode->GetWindowType())) {
1061         std::vector<sptr<WindowNode>> windowNodes;
1062         TraverseContainer(windowNodes);
1063         auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), [windowId](sptr<WindowNode>& node) {
1064             return node->GetWindowId() == windowId;
1065             });
1066         if (iter == windowNodes.end()) {
1067             WLOGFE("could not find this window");
1068             return nullptr;
1069         }
1070         int index = std::distance(windowNodes.begin(), iter);
1071         for (size_t i = index + 1; i < windowNodes.size(); i++) {
1072             if (windowNodes[i]->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1073                 continue;
1074             }
1075             return windowNodes[i];
1076         }
1077     } else {
1078         // do nothing
1079     }
1080     WLOGFE("could not get next active window");
1081     return nullptr;
1082 }
1083 
MinimizeAllAppWindows()1084 void WindowNodeContainer::MinimizeAllAppWindows()
1085 {
1086     WMError ret =  MinimizeAppNodeExceptOptions(true);
1087     SwitchLayoutPolicy(WindowLayoutMode::CASCADE);
1088     if (ret != WMError::WM_OK) {
1089         WLOGFE("Minimize all app window failed");
1090     }
1091     return;
1092 }
1093 
SendSplitScreenEvent(sptr<WindowNode> & node)1094 void WindowNodeContainer::SendSplitScreenEvent(sptr<WindowNode>& node)
1095 {
1096     // reset ipc identity
1097     std::string identity = IPCSkeleton::ResetCallingIdentity();
1098     AAFwk::Want want;
1099     want.SetAction(SPLIT_SCREEN_EVENT_NAME);
1100     std::string modeData = (node->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) ? "Secondary" : "Primary";
1101     int32_t missionId = -1;
1102     AAFwk::AbilityManagerClient::GetInstance()->GetMissionIdByToken(node->abilityToken_, missionId);
1103     WLOGFI("split window missionId is: %{public}d", missionId);
1104     want.SetParam("windowMode", modeData);
1105     want.SetParam("missionId", missionId);
1106     EventFwk::CommonEventData commonEventData;
1107     commonEventData.SetWant(want);
1108     EventFwk::CommonEventManager::PublishCommonEvent(commonEventData);
1109     // set ipc identity to raw
1110     IPCSkeleton::SetCallingIdentity(identity);
1111     WLOGFI("send split sceen event finish.");
1112 }
1113 
FindSplitPairNode(sptr<WindowNode> & triggerNode) const1114 sptr<WindowNode> WindowNodeContainer::FindSplitPairNode(sptr<WindowNode>& triggerNode) const
1115 {
1116     auto triggerMode = triggerNode->GetWindowMode();
1117     for (auto iter = appWindowNode_->children_.rbegin(); iter != appWindowNode_->children_.rend(); iter++) {
1118         if ((*iter)->GetWindowId() == triggerNode->GetWindowId()) {
1119             continue;
1120         }
1121         // Find Top FullScreen main winodow or top paired split mode app main window
1122         if ((*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN ||
1123             (triggerMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY &&
1124             (*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) ||
1125             (triggerMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY &&
1126             (*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
1127             WLOGFI("Find pair node mode is: %{public}d", static_cast<uint32_t>((*iter)->GetWindowMode()));
1128             return *iter;
1129         }
1130     }
1131     return nullptr;
1132 }
1133 
MinimizeWindowFromAbility(const sptr<WindowNode> & node,bool fromUser)1134 void WindowNodeContainer::MinimizeWindowFromAbility(const sptr<WindowNode>& node, bool fromUser)
1135 {
1136     if (node->abilityToken_ == nullptr) {
1137         WLOGFW("Target abilityToken is nullptr, windowId:%{public}u", node->GetWindowId());
1138         return;
1139     }
1140     AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility(node->abilityToken_, fromUser);
1141 }
1142 
MinimizeAppNodeExceptOptions(bool fromUser,const std::vector<uint32_t> & exceptionalIds,const std::vector<WindowMode> & exceptionalModes)1143 WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(bool fromUser, const std::vector<uint32_t> &exceptionalIds,
1144                                                           const std::vector<WindowMode> &exceptionalModes)
1145 {
1146     if (appWindowNode_->children_.empty()) {
1147         return WMError::WM_OK;
1148     }
1149     for (auto& appNode : appWindowNode_->children_) {
1150         // exclude exceptional window
1151         if (std::find(exceptionalIds.begin(), exceptionalIds.end(), appNode->GetWindowId()) != exceptionalIds.end() ||
1152             std::find(exceptionalModes.begin(), exceptionalModes.end(),
1153                 appNode->GetWindowMode()) != exceptionalModes.end() ||
1154                 appNode->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1155             continue;
1156         }
1157         // minimize window
1158         WLOGFI("minimize window, windowId:%{public}u", appNode->GetWindowId());
1159         MinimizeWindowFromAbility(appNode, fromUser);
1160     }
1161     return WMError::WM_OK;
1162 }
1163 
EnterSplitWindowMode(sptr<WindowNode> & node)1164 WMError WindowNodeContainer::EnterSplitWindowMode(sptr<WindowNode>& node)
1165 {
1166     WM_FUNCTION_TRACE();
1167     WLOGFI("Enter split window mode: %{public}d", node->GetWindowId());
1168     SwitchLayoutPolicy(WindowLayoutMode::CASCADE); // window split mode is belong to cascade
1169     auto pairNode = FindSplitPairNode(node);
1170     if (pairNode != nullptr) {
1171         WLOGFI("Window %{public}d find pair %{public}d", node->GetWindowId(), pairNode->GetWindowId());
1172         WMError ret = UpdateWindowPairInfo(node, pairNode);
1173         if (ret != WMError::WM_OK) {
1174             return ret;
1175         }
1176         SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_CREATE_DIVIDER, displayId_);
1177         std::vector<uint32_t> exceptionalIds;
1178         for (auto iter = pairedWindowMap_.begin(); iter != pairedWindowMap_.end(); iter++) {
1179             exceptionalIds.emplace_back(iter->first);
1180         }
1181         std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
1182         ret = MinimizeAppNodeExceptOptions(false, exceptionalIds, exceptionalModes);
1183         if (ret != WMError::WM_OK) {
1184             return ret;
1185         }
1186     } else {
1187         SendSplitScreenEvent(node);
1188     }
1189     return WMError::WM_OK;
1190 }
1191 
ResetLayoutPolicy()1192 void WindowNodeContainer::ResetLayoutPolicy()
1193 {
1194     layoutPolicy_->Reset();
1195 }
1196 
ExitSplitWindowMode(sptr<WindowNode> & node)1197 WMError WindowNodeContainer::ExitSplitWindowMode(sptr<WindowNode>& node)
1198 {
1199     WM_FUNCTION_TRACE();
1200     WLOGFI("exit split window mode %{public}d", node->GetWindowId());
1201     node->GetWindowProperty()->ResumeLastWindowMode();
1202     node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
1203     if (pairedWindowMap_.count(node->GetWindowId()) != 0) {
1204         auto pairNode = pairedWindowMap_.at(node->GetWindowId()).pairNode_;
1205         pairNode->GetWindowProperty()->ResumeLastWindowMode();
1206         pairNode->GetWindowToken()->UpdateWindowMode(pairNode->GetWindowMode());
1207         pairedWindowMap_.erase(pairNode->GetWindowId());
1208         pairedWindowMap_.erase(node->GetWindowId());
1209         WLOGFI("resume pair node mode, Id[%{public}d, %{public}d], Mode[%{public}d, %{public}d]", node->GetWindowId(),
1210             pairNode->GetWindowId(), node->GetWindowMode(), pairNode->GetWindowMode());
1211     }
1212     if (pairedWindowMap_.empty()) {
1213         WLOGFI("send destroy msg to divider, Id: %{public}d", node->GetWindowId());
1214         SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_);
1215     }
1216     ResetLayoutPolicy();
1217     return WMError::WM_OK;
1218 }
1219 
UpdateWindowPairInfo(sptr<WindowNode> & triggerNode,sptr<WindowNode> & pairNode)1220 WMError WindowNodeContainer::UpdateWindowPairInfo(sptr<WindowNode>& triggerNode, sptr<WindowNode>& pairNode)
1221 {
1222     float splitRatio = DEFAULT_SPLIT_RATIO;
1223     WindowMode triggerMode = triggerNode->GetWindowMode();
1224     WindowMode pairSrcMode = pairNode->GetWindowMode();
1225     if (pairSrcMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
1226         WindowMode pairDstMode = (triggerMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) ?
1227             WindowMode::WINDOW_MODE_SPLIT_SECONDARY : WindowMode::WINDOW_MODE_SPLIT_PRIMARY;
1228         pairNode->SetWindowMode(pairDstMode);
1229         pairNode->GetWindowToken()->UpdateWindowMode(pairDstMode);
1230         WMError ret = UpdateWindowNode(pairNode, WindowUpdateReason::UPDATE_MODE);
1231         if (ret != WMError::WM_OK) {
1232             WLOGFE("Update window pair info failed");
1233             return ret;
1234         }
1235         WLOGFI("Pair FullScreen [%{public}d, %{public}d], Mode[%{public}d, %{public}d], splitRatio = %{public}f",
1236             triggerNode->GetWindowId(), pairNode->GetWindowId(), triggerMode, pairDstMode, splitRatio);
1237     } else {
1238         if (pairedWindowMap_.count(pairNode->GetWindowId()) != 0) {
1239             WindowPairInfo info = pairedWindowMap_.at(pairNode->GetWindowId());
1240             auto prevPairNode = info.pairNode_;
1241             WLOGFI("%{public}d node is paird , pre paired id is %{public}d,",
1242                 pairNode->GetWindowId(), prevPairNode->GetWindowId());
1243             prevPairNode->GetWindowProperty()->ResumeLastWindowMode();
1244             prevPairNode->GetWindowToken()->UpdateWindowMode(prevPairNode->GetWindowMode());
1245 
1246             pairedWindowMap_.erase(prevPairNode->GetWindowId());
1247             pairedWindowMap_.erase(pairNode->GetWindowId());
1248 
1249             splitRatio = info.splitRatio_;
1250             WLOGFI("Pair Split [%{public}d, %{public}d], Mode[%{public}d, %{public}d], splitRatio = %{public}f",
1251                 triggerNode->GetWindowId(), pairNode->GetWindowId(), triggerMode, pairSrcMode, splitRatio);
1252         } else {
1253             WLOGFI("%{public}d node is not paird", pairNode->GetWindowId());
1254         }
1255     }
1256     pairedWindowMap_.insert(std::pair<uint32_t, WindowPairInfo>(triggerNode->GetWindowId(),
1257         {pairNode, splitRatio}));
1258     pairedWindowMap_.insert(std::pair<uint32_t, WindowPairInfo>(pairNode->GetWindowId(),
1259         {triggerNode, 1 - splitRatio}));
1260     return WMError::WM_OK;
1261 }
1262 
SwitchLayoutPolicy(WindowLayoutMode dstMode,bool reorder)1263 WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, bool reorder)
1264 {
1265     WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d reorder: %{public}d",
1266         static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder));
1267     if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) {
1268         WLOGFE("invalid layout mode");
1269         return WMError::WM_ERROR_INVALID_PARAM;
1270     }
1271     if (layoutMode_ != dstMode) {
1272         if (layoutMode_ == WindowLayoutMode::CASCADE && !pairedWindowMap_.empty()) {
1273             pairedWindowMap_.clear();
1274             SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_);
1275         }
1276         layoutMode_ = dstMode;
1277         layoutPolicy_->Clean();
1278         layoutPolicy_ = layoutPolicys_[dstMode];
1279         layoutPolicy_->Launch();
1280         DumpScreenWindowTree();
1281     } else {
1282         WLOGFI("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
1283     }
1284     if (reorder) {
1285         if (!pairedWindowMap_.empty()) {
1286             // exit divider window when reorder
1287             pairedWindowMap_.clear();
1288             SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_);
1289         }
1290         layoutPolicy_->Reorder();
1291         DumpScreenWindowTree();
1292     }
1293     NotifyIfSystemBarTintChanged();
1294     return WMError::WM_OK;
1295 }
1296 
RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode> & node) const1297 void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const
1298 {
1299     if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1300         return;
1301     }
1302     auto iter = std::find_if(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(),
1303                              [](sptr<WindowNode> node) {
1304         return node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD;
1305     });
1306     if (iter != aboveAppWindowNode_->children_.end()) {
1307         WLOGFI("raise input method float window priority.");
1308         node->priority_ = zorderPolicy_->GetWindowPriority(
1309             WindowType::WINDOW_TYPE_KEYGUARD) + 2; // 2: higher than keyguard and show when locked window
1310     }
1311 }
1312 
ReZOrderShowWhenLockedWindows(const sptr<WindowNode> & node,bool up)1313 void WindowNodeContainer::ReZOrderShowWhenLockedWindows(const sptr<WindowNode>& node, bool up)
1314 {
1315     WLOGFI("Keyguard change %{public}u, re-zorder showWhenLocked window", up);
1316     std::vector<sptr<WindowNode>> needReZOrderNodes;
1317     auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_;
1318     auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_;
1319     auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 :
1320         zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
1321 
1322     for (auto iter = srcRoot->children_.begin(); iter != srcRoot->children_.end();) {
1323         if ((*iter)->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
1324             needReZOrderNodes.emplace_back(*iter);
1325             iter = srcRoot->children_.erase(iter);
1326         } else {
1327             iter++;
1328         }
1329     }
1330 
1331     for (auto& needReZOrderNode : needReZOrderNodes) {
1332         needReZOrderNode->priority_ = dstPriority;
1333         needReZOrderNode->parent_ = dstRoot;
1334         auto parentNode = needReZOrderNode->parent_;
1335         auto position = parentNode->children_.end();
1336         for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
1337             if ((*iter)->priority_ > needReZOrderNode->priority_) {
1338                 position = iter;
1339                 break;
1340             }
1341         }
1342         parentNode->children_.insert(position, needReZOrderNode);
1343         WLOGFI("ShowWhenLocked window %{public}u re-zorder when keyguard change %{public}u",
1344             needReZOrderNode->GetWindowId(), up);
1345     }
1346 }
1347 
RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1348 void WindowNodeContainer::RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1349 {
1350     // if keyguard window show, raise show when locked windows
1351     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1352         ReZOrderShowWhenLockedWindows(node, true);
1353         return;
1354     }
1355 
1356     // if show when locked window show, raise itself when exist keyguard
1357     if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
1358         return;
1359     }
1360 
1361     auto iter = std::find_if(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(),
1362                              [](sptr<WindowNode> node) {
1363         return node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD;
1364     });
1365     if (iter != aboveAppWindowNode_->children_.end()) {
1366         WLOGFI("ShowWhenLocked window %{public}u raise itself", node->GetWindowId());
1367         node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
1368         node->parent_ = aboveAppWindowNode_;
1369     }
1370 }
1371 
DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1372 void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1373 {
1374     // if keyguard window hide, drop show when locked windows
1375     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1376         ReZOrderShowWhenLockedWindows(node, false);
1377         AssignZOrder();
1378     }
1379 }
1380 
MoveWindowNode(sptr<WindowNodeContainer> & container)1381 void WindowNodeContainer::MoveWindowNode(sptr<WindowNodeContainer>& container)
1382 {
1383     DisplayId from = container->GetDisplayId();
1384     WLOGFI("disconnect expand display: %{public}" PRId64 ", move window node to display: "
1385         "%{public}" PRId64 "", from, displayId_);
1386     for (auto& node : container->aboveAppWindowNode_->children_) {
1387         WLOGFI("aboveAppWindowNode_: move windowNode: %{public}d", node->GetWindowId());
1388         aboveAppWindowNode_->children_.push_back(node);
1389         layoutPolicy_->AddWindowNode(node);
1390     }
1391     for (auto& node : container->appWindowNode_->children_) {
1392         WLOGFI("appWindowNode_: move windowNode: %{public}d", node->GetWindowId());
1393         appWindowNode_->children_.push_back(node);
1394         layoutPolicy_->AddWindowNode(node);
1395     }
1396     for (auto& node : container->belowAppWindowNode_->children_) {
1397         WLOGFI("belowAppWindowNode_: move windowNode: %{public}d", node->GetWindowId());
1398         belowAppWindowNode_->children_.push_back(node);
1399         layoutPolicy_->AddWindowNode(node);
1400     }
1401 }
1402 
TraverseWindowTree(const WindowNodeOperationFunc & func,bool isFromTopToBottom) const1403 void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
1404 {
1405     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1406     if (isFromTopToBottom) {
1407         std::reverse(rootNodes.begin(), rootNodes.end());
1408     }
1409 
1410     for (auto& node : rootNodes) {
1411         if (isFromTopToBottom) {
1412             for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
1413                 if (TraverseFromTopToBottom(*iter, func)) {
1414                     return;
1415                 }
1416             }
1417         } else {
1418             for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
1419                 if (TraverseFromBottomToTop(*iter, func)) {
1420                     return;
1421                 }
1422             }
1423         }
1424     }
1425 }
1426 
TraverseFromTopToBottom(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1427 bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1428 {
1429     if (node == nullptr) {
1430         return false;
1431     }
1432     auto iterBegin = node->children_.rbegin();
1433     for (; iterBegin != node->children_.rend(); ++iterBegin) {
1434         if ((*iterBegin)->priority_ <= 0) {
1435             break;
1436         }
1437         if (func(*iterBegin)) {
1438             return true;
1439         }
1440     }
1441     if (func(node)) {
1442         return true;
1443     }
1444     for (; iterBegin != node->children_.rend(); ++iterBegin) {
1445         if (func(*iterBegin)) {
1446             return true;
1447         }
1448     }
1449     return false;
1450 }
1451 
TraverseFromBottomToTop(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1452 bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1453 {
1454     if (node == nullptr) {
1455         return false;
1456     }
1457     auto iterBegin = node->children_.begin();
1458     for (; iterBegin != node->children_.end(); ++iterBegin) {
1459         if ((*iterBegin)->priority_ >= 0) {
1460             break;
1461         }
1462         if (func(*iterBegin)) {
1463             return true;
1464         }
1465     }
1466     if (func(node)) {
1467         return true;
1468     }
1469     for (; iterBegin != node->children_.end(); ++iterBegin) {
1470         if (func(*iterBegin)) {
1471             return true;
1472         }
1473     }
1474     return false;
1475 }
1476 
UpdateWindowVisibilityInfos(std::vector<sptr<WindowVisibilityInfo>> & infos)1477 void WindowNodeContainer::UpdateWindowVisibilityInfos(std::vector<sptr<WindowVisibilityInfo>>& infos)
1478 {
1479     currentCoveredArea_.clear();
1480     WindowNodeOperationFunc func = [this, &infos](sptr<WindowNode> node) {
1481         if (node == nullptr) {
1482             return false;
1483         }
1484         Rect layoutRect = node->GetLayoutRect();
1485         int32_t nodeX = std::max(0, layoutRect.posX_);
1486         int32_t nodeY = std::max(0, layoutRect.posY_);
1487         int32_t nodeXEnd = std::min(displayRect_.posX_ + static_cast<int32_t>(displayRect_.width_),
1488             layoutRect.posX_ + static_cast<int32_t>(layoutRect.width_));
1489         int32_t nodeYEnd = std::min(displayRect_.posY_ + static_cast<int32_t>(displayRect_.height_),
1490             layoutRect.posY_ + static_cast<int32_t>(layoutRect.height_));
1491 
1492         Rect rectInDisplay = {nodeX, nodeY,
1493                               static_cast<uint32_t>(nodeXEnd - nodeX), static_cast<uint32_t>(nodeYEnd - nodeY)};
1494         bool isCovered = false;
1495         for (auto& rect : currentCoveredArea_) {
1496             if (rectInDisplay.IsInsideOf(rect)) {
1497                 isCovered = true;
1498                 WLOGD("UpdateWindowVisibilityInfos: find covered window:%{public}u", node->GetWindowId());
1499                 break;
1500             }
1501         }
1502         if (!isCovered) {
1503             currentCoveredArea_.emplace_back(rectInDisplay);
1504         }
1505         if (isCovered != node->isCovered_) {
1506             node->isCovered_ = isCovered;
1507             infos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(),
1508                 node->GetCallingUid(), !isCovered));
1509             WLOGD("UpdateWindowVisibilityInfos: covered status changed window:%{public}u, covered:%{public}d",
1510                 node->GetWindowId(), isCovered);
1511         }
1512         return false;
1513     };
1514     TraverseWindowTree(func, true);
1515     WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(infos);
1516 }
1517 
GetVirtualPixelRatio() const1518 float WindowNodeContainer::GetVirtualPixelRatio() const
1519 {
1520     return layoutPolicy_->GetVirtualPixelRatio();
1521 }
1522 
ReadIsWindowAnimationEnabledProperty()1523 bool WindowNodeContainer::ReadIsWindowAnimationEnabledProperty()
1524 {
1525     if (access(DISABLE_WINDOW_ANIMATION_PATH, F_OK) == 0) {
1526         return false;
1527     }
1528     return true;
1529 }
1530 } // namespace Rosen
1531 } // namespace OHOS
1532