• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "window_node_container.h"
17 
18 #include <ability_manager_client.h>
19 #include <algorithm>
20 #include <cinttypes>
21 #include <cmath>
22 #include <ctime>
23 #include <display_power_mgr_client.h>
24 #include <hitrace_meter.h>
25 #include <limits>
26 #include <power_mgr_client.h>
27 #include <transaction/rs_interfaces.h>
28 #include <transaction/rs_transaction.h>
29 
30 #include "common_event_manager.h"
31 #include "dm_common.h"
32 #include "remote_animation.h"
33 #include "starting_window.h"
34 #include "window_helper.h"
35 #include "window_inner_manager.h"
36 #include "window_layout_policy_cascade.h"
37 #include "window_layout_policy_tile.h"
38 #include "window_manager_agent_controller.h"
39 #include "window_manager_hilog.h"
40 #include "window_manager_service.h"
41 #include "wm_common.h"
42 #include "wm_common_inner.h"
43 
44 namespace OHOS {
45 namespace Rosen {
46 namespace {
47     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowNodeContainer"};
48     constexpr int WINDOW_NAME_MAX_LENGTH = 10;
49     constexpr uint32_t MAX_BRIGHTNESS = 255;
50     constexpr uint32_t SPLIT_WINDOWS_CNT = 2;
51     constexpr uint32_t EXIT_SPLIT_POINTS_NUMBER = 2;
52     constexpr int UID_TRANSFROM_DIVISOR = 200000;
53     constexpr int UID_MIN = 100;
54 }
55 AnimationConfig WindowNodeContainer::animationConfig_;
56 
WindowNodeContainer(const sptr<DisplayInfo> & displayInfo,ScreenId displayGroupId)57 WindowNodeContainer::WindowNodeContainer(const sptr<DisplayInfo>& displayInfo, ScreenId displayGroupId)
58 {
59     DisplayId displayId = displayInfo->GetDisplayId();
60 
61     // create and displayGroupInfo and displayGroupController
62     displayGroupInfo_ = new DisplayGroupInfo(displayGroupId, displayInfo);
63     displayGroupController_ = new DisplayGroupController(this, displayGroupInfo_);
64     displayGroupController_->InitNewDisplay(displayId);
65 
66     // init layout policy
67     layoutPolicies_[WindowLayoutMode::CASCADE] = new WindowLayoutPolicyCascade(displayGroupInfo_,
68         displayGroupController_->displayGroupWindowTree_);
69     layoutPolicies_[WindowLayoutMode::TILE] = new WindowLayoutPolicyTile(displayGroupInfo_,
70         displayGroupController_->displayGroupWindowTree_);
71     layoutPolicy_ = layoutPolicies_[WindowLayoutMode::CASCADE];
72     layoutPolicy_->Launch();
73 
74     Rect initalDividerRect = layoutPolicies_[WindowLayoutMode::CASCADE]->GetDividerRect(displayId);
75     displayGroupController_->SetDividerRect(displayId, initalDividerRect);
76     // init avoidAreaController
77     avoidController_ = new AvoidAreaController(focusedWindow_);
78 }
79 
~WindowNodeContainer()80 WindowNodeContainer::~WindowNodeContainer()
81 {
82     Destroy();
83 }
84 
GetWindowCountByType(WindowType windowType)85 uint32_t WindowNodeContainer::GetWindowCountByType(WindowType windowType)
86 {
87     uint32_t windowNumber = 0;
88     auto counter = [&windowNumber, &windowType](sptr<WindowNode>& windowNode) {
89         if (windowNode->GetWindowType() == windowType && !windowNode->startingWindowShown_) ++windowNumber;
90     };
91     std::for_each(belowAppWindowNode_->children_.begin(), belowAppWindowNode_->children_.end(), counter);
92     std::for_each(appWindowNode_->children_.begin(), appWindowNode_->children_.end(), counter);
93     std::for_each(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(), counter);
94     return windowNumber;
95 }
96 
AddWindowNodeOnWindowTree(sptr<WindowNode> & node,const sptr<WindowNode> & parentNode)97 WMError WindowNodeContainer::AddWindowNodeOnWindowTree(sptr<WindowNode>& node, const sptr<WindowNode>& parentNode)
98 {
99     sptr<WindowNode> root = FindRoot(node->GetWindowType());
100     if (root == nullptr && !(WindowHelper::IsSystemSubWindow(node->GetWindowType()) &&
101         parentNode != nullptr)) {
102         WLOGFE("root is nullptr!");
103         return WMError::WM_ERROR_NULLPTR;
104     }
105     node->requestedVisibility_ = true;
106     if (parentNode != nullptr) { // subwindow
107         if (WindowHelper::IsSystemSubWindow(node->GetWindowType()) ||
108             node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
109             if (WindowHelper::IsSubWindow(parentNode->GetWindowType()) ||
110                 WindowHelper::IsSystemSubWindow(parentNode->GetWindowType()) ||
111                 parentNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT ||
112                 parentNode->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
113                 // some times, dialog is a child window, so exclude
114                 WLOGFE("the parent of window cannot be any sub window");
115                 return WMError::WM_ERROR_INVALID_PARAM;
116             }
117         } else {
118             if (parentNode->parent_ != root &&
119                 !((parentNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) &&
120                 (parentNode->parent_ == aboveAppWindowNode_))) {
121                 WLOGFE("window type and parent window not match \
122                     or try to add subwindow to subwindow, which is forbidden");
123                 return WMError::WM_ERROR_INVALID_PARAM;
124             }
125         }
126         node->currentVisibility_ = parentNode->currentVisibility_;
127         node->parent_ = parentNode;
128     } else { // mainwindow
129         node->parent_ = root;
130         node->currentVisibility_ = true;
131         for (auto& child : node->children_) {
132             child->currentVisibility_ = child->requestedVisibility_;
133         }
134         if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
135             displayGroupController_->sysBarNodeMaps_[node->GetDisplayId()][node->GetWindowType()] = node;
136         }
137     }
138     return WMError::WM_OK;
139 }
140 
ShowStartingWindow(sptr<WindowNode> & node)141 WMError WindowNodeContainer::ShowStartingWindow(sptr<WindowNode>& node)
142 {
143     if (node->currentVisibility_) {
144         WLOGFE("current window is visible, windowId: %{public}u", node->GetWindowId());
145         return WMError::WM_ERROR_INVALID_OPERATION;
146     }
147 
148     WMError res = AddWindowNodeOnWindowTree(node, nullptr);
149     if (res != WMError::WM_OK) {
150         return res;
151     }
152     UpdateWindowTree(node);
153     displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
154     StartingWindow::AddNodeOnRSTree(node, animationConfig_, layoutPolicy_->IsMultiDisplay());
155     AssignZOrder();
156     layoutPolicy_->AddWindowNode(node);
157     WLOGFI("ShowStartingWindow windowId: %{public}u end", node->GetWindowId());
158     return WMError::WM_OK;
159 }
160 
IsTileRectSatisfiedWithSizeLimits(sptr<WindowNode> & node)161 WMError WindowNodeContainer::IsTileRectSatisfiedWithSizeLimits(sptr<WindowNode>& node)
162 {
163     if (layoutMode_ == WindowLayoutMode::TILE &&
164         !layoutPolicy_->IsTileRectSatisfiedWithSizeLimits(node)) {
165         WLOGFE("layoutMode is tile, default rect is not satisfied with size limits of window, windowId: %{public}u",
166             node->GetWindowId());
167         return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
168     }
169     return WMError::WM_OK;
170 }
171 
GetAnimationConfigRef()172 AnimationConfig& WindowNodeContainer::GetAnimationConfigRef()
173 {
174     return animationConfig_;
175 }
176 
LayoutWhenAddWindowNode(sptr<WindowNode> & node,bool afterAnimation)177 void WindowNodeContainer::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool afterAnimation)
178 {
179     if (afterAnimation) {
180         layoutPolicy_->AddWindowNode(node);
181         return;
182     }
183     WLOGFI("AddWindowNode windowId:%{public}u, name:%{public}s currState:%{public}u",
184         node->GetWindowId(), node->GetWindowName().c_str(),
185         static_cast<uint32_t>(node->stateMachine_.GetCurrentState()));
186     if (WindowHelper::IsMainWindow(node->GetWindowType()) &&
187         RemoteAnimation::IsRemoteAnimationEnabledAndFirst(node->GetDisplayId()) &&
188         node->stateMachine_.IsShowAnimationPlaying()) {
189         // for first frame callback
190         auto winRect = node->GetWindowRect();
191         if (node->surfaceNode_) {
192             node->surfaceNode_->SetBounds(0, 0, winRect.width_, winRect.height_);
193             WLOGFI("notify client and SetBounds id:%{public}u, rect:[%{public}d, %{public}d, %{public}u, %{public}u]",
194                 node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
195             layoutPolicy_->UpdateClientRect(node->GetWindowRect(), node, WindowSizeChangeReason::UNDEFINED);
196         }
197     } else {
198         if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) &&
199             WindowHelper::IsSystemWindow(node->GetWindowType())) {
200                 node->SetWindowSizeChangeReason(WindowSizeChangeReason::CUSTOM_ANIMATION_SHOW);
201         }
202         layoutPolicy_->AddWindowNode(node);
203     }
204 }
205 
AddWindowNode(sptr<WindowNode> & node,sptr<WindowNode> & parentNode,bool afterAnimation)206 WMError WindowNodeContainer::AddWindowNode(sptr<WindowNode>& node, sptr<WindowNode>& parentNode, bool afterAnimation)
207 {
208     if (!node->startingWindowShown_) { // window except main Window
209         WMError res = AddWindowNodeOnWindowTree(node, parentNode);
210         if (res != WMError::WM_OK) {
211             return res;
212         }
213         UpdateWindowTree(node);
214         displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
215         // add node on RSTree
216         for (auto& displayId : node->GetShowingDisplays()) {
217             AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ADDED,
218                 node->isPlayAnimationShow_);
219         }
220     } else { // only main app window has starting window
221         node->isPlayAnimationShow_ = false;
222         node->startingWindowShown_ = false;
223         AddAppSurfaceNodeOnRSTree(node);
224         ReZOrderShowWhenLockedWindowIfNeeded(node);
225         RaiseZOrderForAppWindow(node, parentNode);
226     }
227     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
228     if (windowPair == nullptr) {
229         WLOGFE("Window pair is nullptr");
230         return WMError::WM_ERROR_NULLPTR;
231     }
232     windowPair->UpdateIfSplitRelated(node);
233     if (node->IsSplitMode()) {
234         // raise the z-order of window pair
235         RaiseSplitRelatedWindowToTop(node);
236     }
237     AssignZOrder();
238     LayoutWhenAddWindowNode(node, afterAnimation);
239     NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_ADD);
240     DumpScreenWindowTree();
241     UpdateCameraFloatWindowStatus(node, true);
242     if (WindowHelper::IsMainWindow(node->GetWindowType())) {
243         backupWindowIds_.clear();
244     }
245 
246     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
247         isScreenLocked_ = true;
248         SetBelowScreenlockVisible(node, false);
249     }
250     if (node->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) {
251         RemoteAnimation::NotifyAnimationUpdateWallpaper(node);
252     }
253     WLOGFI("AddWindowNode windowId: %{public}u end", node->GetWindowId());
254     RSInterfaces::GetInstance().SetAppWindowNum(GetAppWindowNum());
255     return WMError::WM_OK;
256 }
257 
UpdateRSTreeWhenShowingDisplaysChange(sptr<WindowNode> & node,const std::vector<DisplayId> & lastShowingDisplays)258 void WindowNodeContainer::UpdateRSTreeWhenShowingDisplaysChange(sptr<WindowNode>& node,
259     const std::vector<DisplayId>& lastShowingDisplays)
260 {
261     if (!layoutPolicy_->IsMultiDisplay()) {
262         return;
263     }
264 
265     // Update RSTree
266     auto curShowingDisplays = node->GetShowingDisplays();
267     for (auto& displayId : lastShowingDisplays) {
268         if (std::find(curShowingDisplays.begin(), curShowingDisplays.end(), displayId) == curShowingDisplays.end()) {
269             RemoveNodeFromRSTree(node, displayId, *(curShowingDisplays.begin()),
270                 WindowUpdateType::WINDOW_UPDATE_ACTIVE);
271             WLOGFI("remove from RSTree : %{public}" PRIu64"", displayId);
272         }
273     }
274 
275     for (auto& displayId : curShowingDisplays) {
276         if (std::find(lastShowingDisplays.begin(), lastShowingDisplays.end(), displayId) == lastShowingDisplays.end()) {
277             AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
278             WLOGFI("add on RSTree : %{public}" PRIu64"", displayId);
279         }
280     }
281 }
282 
UpdateWindowNode(sptr<WindowNode> & node,WindowUpdateReason reason)283 WMError WindowNodeContainer::UpdateWindowNode(sptr<WindowNode>& node, WindowUpdateReason reason)
284 {
285     // Get last displayId and last showing displays before layout
286     auto lastShowingDisplays = node->GetShowingDisplays();
287 
288     // PreProcess window node and layout node
289     displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
290     if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) {
291         SwitchLayoutPolicy(WindowLayoutMode::CASCADE, node->GetDisplayId());
292     }
293     layoutPolicy_->UpdateWindowNode(node);
294     displayGroupController_->PostProcessWindowNode(node);
295     // Get current displayId and showing displays, update RSTree and displayGroupWindowTree
296     UpdateRSTreeWhenShowingDisplaysChange(node, lastShowingDisplays);
297     NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_UPDATE);
298     DumpScreenWindowTree();
299     WLOGFI("UpdateWindowNode windowId: %{public}u end", node->GetWindowId());
300     return WMError::WM_OK;
301 }
302 
RemoveWindowNodeFromWindowTree(sptr<WindowNode> & node)303 void WindowNodeContainer::RemoveWindowNodeFromWindowTree(sptr<WindowNode>& node)
304 {
305     // remove this node from parent
306     auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node);
307     if (iter != node->parent_->children_.end()) {
308         node->parent_->children_.erase(iter);
309     } else {
310         WLOGFE("can't find this node in parent");
311     }
312     node->parent_ = nullptr;
313 }
314 
RemoveFromRsTreeWhenRemoveWindowNode(sptr<WindowNode> & node,bool fromAnimation)315 void WindowNodeContainer::RemoveFromRsTreeWhenRemoveWindowNode(sptr<WindowNode>& node, bool fromAnimation)
316 {
317     if (fromAnimation || (RemoteAnimation::IsRemoteAnimationEnabledAndFirst(node->GetDisplayId()) &&
318         node->stateMachine_.IsHideAnimationPlaying())) {
319             WLOGFD("not remove from rs tree id:%{public}u", node->GetWindowId());
320             return;
321     }
322     // When RemoteAnimation exists, remove node from rs tree after animation
323     WLOGFD("remove from rs tree id:%{public}u, node->isPlayAnimationHide_:%{public}u", node->GetWindowId(),
324         static_cast<uint32_t>(node->isPlayAnimationHide_));
325     // subwindow or no remote animation also exit with animation
326     for (auto& displayId : node->GetShowingDisplays()) {
327         RemoveNodeFromRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_REMOVED,
328             node->isPlayAnimationHide_);
329     }
330 }
331 
SetSurfaceNodeVisible(sptr<WindowNode> & node,int32_t topPriority,bool visible)332 void WindowNodeContainer::SetSurfaceNodeVisible(sptr<WindowNode>& node, int32_t topPriority, bool visible)
333 {
334     if (node == nullptr) {
335         return;
336     }
337     if (node->parent_ != nullptr && node->currentVisibility_) {
338         if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
339             !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
340             auto surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
341             if (surfaceNode) {
342                 surfaceNode->SetVisible(visible);
343             }
344         }
345     }
346     for (auto& childNode : node->children_) {
347         SetSurfaceNodeVisible(childNode, topPriority, visible);
348     }
349 }
350 
SetBelowScreenlockVisible(sptr<WindowNode> & node,bool visible)351 void WindowNodeContainer::SetBelowScreenlockVisible(sptr<WindowNode>& node, bool visible)
352 {
353     int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
354     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
355     for (auto& node : rootNodes) {
356         SetSurfaceNodeVisible(node, topPriority, visible);
357     }
358 }
359 
RemoveWindowNode(sptr<WindowNode> & node,bool fromAnimation)360 WMError WindowNodeContainer::RemoveWindowNode(sptr<WindowNode>& node, bool fromAnimation)
361 {
362     if (node == nullptr) {
363         WLOGFE("window node or surface node is nullptr, invalid");
364         return WMError::WM_ERROR_DESTROYED_OBJECT;
365     }
366     if (node->parent_ == nullptr) {
367         WLOGFW("can't find parent of this node");
368     } else {
369         RemoveWindowNodeFromWindowTree(node);
370     }
371 
372     node->requestedVisibility_ = false;
373     node->currentVisibility_ = false;
374     RemoveFromRsTreeWhenRemoveWindowNode(node, fromAnimation);
375     node->isPlayAnimationHide_ = false;
376     displayGroupController_->UpdateDisplayGroupWindowTree();
377 
378     layoutPolicy_->RemoveWindowNode(node);
379     WindowMode lastMode = node->GetWindowMode();
380     if (HandleRemoveWindow(node) != WMError::WM_OK) {
381         return WMError::WM_ERROR_NULLPTR;
382     }
383     if (!WindowHelper::IsFloatingWindow(lastMode)) {
384         NotifyDockWindowStateChanged(node, true);
385     }
386     NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_REMOVE);
387     DumpScreenWindowTree();
388     UpdateCameraFloatWindowStatus(node, false);
389     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
390         isScreenLocked_ = false;
391         SetBelowScreenlockVisible(node, true);
392     }
393     if (node->GetWindowType() == WindowType::WINDOW_TYPE_BOOT_ANIMATION) {
394         DisplayManagerServiceInner::GetInstance().SetGravitySensorSubscriptionEnabled();
395     }
396     WLOGFI("RemoveWindowNode windowId: %{public}u end", node->GetWindowId());
397     RSInterfaces::GetInstance().SetAppWindowNum(GetAppWindowNum());
398     return WMError::WM_OK;
399 }
400 
GetAppWindowNum()401 uint32_t WindowNodeContainer::GetAppWindowNum()
402 {
403     uint32_t num = 0;
404     for (auto& child : appWindowNode_->children_) {
405         if (WindowHelper::IsAppWindow(child->GetWindowType())) {
406             num++;
407         }
408     }
409     return num;
410 }
411 
HandleRemoveWindow(sptr<WindowNode> & node)412 WMError WindowNodeContainer::HandleRemoveWindow(sptr<WindowNode>& node)
413 {
414     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
415     if (windowPair == nullptr) {
416         WLOGFE("Window pair is nullptr");
417         return WMError::WM_ERROR_NULLPTR;
418     }
419     windowPair->HandleRemoveWindow(node);
420     auto dividerWindow = windowPair->GetDividerWindow();
421     auto type = node->GetWindowType();
422     if ((type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) &&
423         dividerWindow != nullptr) {
424         UpdateWindowNode(dividerWindow, WindowUpdateReason::UPDATE_RECT);
425     }
426     return WMError::WM_OK;
427 }
428 
DestroyWindowNode(sptr<WindowNode> & node,std::vector<uint32_t> & windowIds)429 WMError WindowNodeContainer::DestroyWindowNode(sptr<WindowNode>& node, std::vector<uint32_t>& windowIds)
430 {
431     WMError ret = RemoveWindowNode(node);
432     if (ret != WMError::WM_OK) {
433         WLOGFE("RemoveWindowNode failed");
434         return ret;
435     }
436     StartingWindow::ReleaseStartWinSurfaceNode(node);
437     node->surfaceNode_ = nullptr;
438     windowIds.push_back(node->GetWindowId());
439     for (auto& child : node->children_) { // destroy sub window if exists
440         windowIds.push_back(child->GetWindowId());
441         child->parent_ = nullptr;
442         if (child->surfaceNode_ != nullptr) {
443             WLOGFI("child surfaceNode set nullptr");
444             child->surfaceNode_ = nullptr;
445         }
446     }
447 
448     // clear vector cache completely, swap with empty vector
449     auto emptyVector = std::vector<sptr<WindowNode>>();
450     node->children_.swap(emptyVector);
451     if (node->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) {
452         RemoteAnimation::NotifyAnimationUpdateWallpaper(nullptr);
453     }
454     WLOGFI("DestroyWindowNode windowId: %{public}u end", node->GetWindowId());
455     return WMError::WM_OK;
456 }
457 
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowSizeChangeReason reason)458 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowSizeChangeReason reason)
459 {
460     if (!node->GetWindowToken()) {
461         WLOGFE("windowToken is null");
462         return;
463     }
464     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
465         for (auto& childNode : appWindowNode_->children_) {
466             if (childNode->IsSplitMode()) {
467                 layoutPolicy_->UpdateClientRect(childNode->GetWindowRect(), childNode, reason);
468                 childNode->ResetWindowSizeChangeReason();
469                 WLOGFI("Notify split window that the drag action is start or end, windowId: %{public}d, "
470                     "reason: %{public}u", childNode->GetWindowId(), reason);
471             }
472         }
473     } else {
474         layoutPolicy_->UpdateClientRect(node->GetWindowRect(), node, reason);
475         node->ResetWindowSizeChangeReason();
476         WLOGFI("Notify window that the drag action is start or end, windowId: %{public}d, "
477             "reason: %{public}u", node->GetWindowId(), reason);
478     }
479 }
480 
UpdateWindowTree(sptr<WindowNode> & node)481 void WindowNodeContainer::UpdateWindowTree(sptr<WindowNode>& node)
482 {
483     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
484     node->priority_ = zorderPolicy_->GetWindowPriority(node->GetWindowType());
485     RaiseInputMethodWindowPriorityIfNeeded(node);
486     RaiseShowWhenLockedWindowIfNeeded(node);
487     auto parentNode = node->parent_;
488     if (parentNode == nullptr) {
489         WLOGFI("Current window node has no parent: %{public}u", node->GetWindowId());
490         return;
491     }
492     auto iter = std::find(parentNode->children_.begin(), parentNode->children_.end(), node);
493     if (iter != parentNode->children_.end()) {
494         WLOGFI("node %{public}u is already on window tree, no need to update!", node->GetWindowId());
495         return;
496     }
497     auto position = parentNode->children_.end();
498     int splitWindowCnt = 0;
499     for (auto child = parentNode->children_.begin(); child < parentNode->children_.end(); ++child) {
500         if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && splitWindowCnt == SPLIT_WINDOWS_CNT) {
501             position = child;
502             break;
503         }
504         if (WindowHelper::IsSplitWindowMode((*child)->GetWindowMode())) {
505             splitWindowCnt++;
506         }
507         if ((*child)->priority_ > node->priority_) {
508             position = child;
509             break;
510         }
511     }
512     parentNode->children_.insert(position, node);
513 }
514 
AddAppSurfaceNodeOnRSTree(sptr<WindowNode> & node)515 bool WindowNodeContainer::AddAppSurfaceNodeOnRSTree(sptr<WindowNode>& node)
516 {
517     /*
518      * App main window must has starting window, and show after starting window
519      * Starting Window has already update leashWindowSurfaceNode and starting window surfaceNode on RSTree
520      * Just need add appSurface Node as child of leashWindowSurfaceNode
521      */
522     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AddAppSurfaceNodeOnRSTree");
523     if (!WindowHelper::IsMainWindow(node->GetWindowType())) {
524         WLOGFE("id:%{public}u not main app window but has start window", node->GetWindowId());
525         return false;
526     }
527     if (!node->leashWinSurfaceNode_ || !node->surfaceNode_) {
528         WLOGFE("id:%{public}u leashWinSurfaceNode or surfaceNode is null but has start window!", node->GetWindowId());
529         return false;
530     }
531     WLOGFI("AddAppSurfaceNodeOnRSTree windowId: %{public}d", node->GetWindowId());
532     if (!node->currentVisibility_) {
533         WLOGFI("window: %{public}d is invisible, do not need update RS tree", node->GetWindowId());
534         return false;
535     }
536     node->leashWinSurfaceNode_->AddChild(node->surfaceNode_, -1);
537     return true;
538 }
539 
AddNodeOnRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)540 bool WindowNodeContainer::AddNodeOnRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
541     WindowUpdateType type, bool animationPlayed)
542 {
543     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
544     if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
545         node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
546         WLOGFI("not need to update RSTree");
547         return true;
548     }
549     bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
550     WLOGFI("AddNodeOnRSTree windowId: %{public}d, displayId: %{public}" PRIu64", parentDisplayId: %{public}" PRIu64", "
551         "isMultiDisplay: %{public}d, animationPlayed: %{public}d",
552         node->GetWindowId(), displayId, parentDisplayId, isMultiDisplay, animationPlayed);
553     auto updateRSTreeFunc = [&]() {
554         auto& dms = DisplayManagerServiceInner::GetInstance();
555         if (!node->currentVisibility_) {
556             WLOGFI("window: %{public}d is invisible, do not need update RS tree", node->GetWindowId());
557             return;
558         }
559         auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
560         dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, true, isMultiDisplay);
561         for (auto& child : node->children_) {
562             if (child->currentVisibility_) {
563                 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, true, isMultiDisplay);
564             }
565         }
566     };
567 
568     if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
569         updateRSTreeFunc();
570         return true;
571     }
572 
573     if (node->EnableDefaultAnimation(animationPlayed)) {
574         WLOGFI("add window with animation");
575         StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
576         RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
577             animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc);
578         FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
579     } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
580         !animationPlayed) { // add keyboard with animation
581         ProcessInputMethodWindowAddAnimation(node, updateRSTreeFunc);
582     } else {
583         WLOGFI("add window without animation");
584         updateRSTreeFunc();
585     }
586     return true;
587 }
588 
ProcessInputMethodWindowAddAnimation(sptr<WindowNode> & node,std::function<void ()> updateRSTreeFunc)589 void WindowNodeContainer::ProcessInputMethodWindowAddAnimation(sptr<WindowNode>& node,
590     std::function<void()> updateRSTreeFunc)
591 {
592     static sptr<WindowNode> imeNode = nullptr;
593     if (imeNode == node && imeNode != nullptr && imeNode->surfaceNode_ != nullptr) {
594         WLOGFI("imeNode SetAppFreeze(true)");
595         imeNode->surfaceNode_->SetAppFreeze(true);
596     }
597     sptr<WindowNode> launcherNode = nullptr;
598     for (auto& windowNode : belowAppWindowNode_->children_) {
599         if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
600             launcherNode = windowNode;
601             break;
602         }
603     }
604     if (launcherNode != nullptr && launcherNode->surfaceNode_ != nullptr) {
605         WLOGFI("launcherNode SetAppFreeze(true)");
606         launcherNode->surfaceNode_->SetAppFreeze(true);
607     }
608     auto timingProtocol = animationConfig_.keyboardAnimationConfig_.durationIn_;
609     RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationConfig_.curve_, updateRSTreeFunc,
610         [ime = imeNode, node, launcherNode]() {
611         if (ime == node && ime != nullptr && ime->surfaceNode_ != nullptr) {
612             WLOGFI("imeNode SetAppFreeze(false)");
613             ime->surfaceNode_->SetAppFreeze(false);
614         }
615         if (launcherNode != nullptr && launcherNode->surfaceNode_ != nullptr) {
616             WLOGFI("launcherNode SetAppFreeze(false)");
617             launcherNode->surfaceNode_->SetAppFreeze(false);
618         }
619         auto transactionProxy = RSTransactionProxy::GetInstance();
620         if (transactionProxy != nullptr) {
621             transactionProxy->FlushImplicitTransaction();
622         }
623     });
624     imeNode = node;
625 }
626 
RemoveNodeFromRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)627 bool WindowNodeContainer::RemoveNodeFromRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
628     WindowUpdateType type, bool animationPlayed)
629 {
630     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
631     if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
632         node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
633         WLOGFI("not need to update RSTree");
634         return true;
635     }
636     bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
637     WLOGFI("RemoveNodeFromRSTree  windowId: %{public}d, displayId: %{public}" PRIu64", isMultiDisplay: %{public}d, "
638         "parentDisplayId: %{public}" PRIu64", animationPlayed: %{public}d",
639         node->GetWindowId(), displayId, isMultiDisplay, parentDisplayId, animationPlayed);
640     auto updateRSTreeFunc = [&]() {
641         auto& dms = DisplayManagerServiceInner::GetInstance();
642         auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
643         dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, false, isMultiDisplay);
644         for (auto& child : node->children_) {
645             if (child->currentVisibility_) {
646                 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, false, isMultiDisplay);
647             }
648         }
649     };
650 
651     if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
652         updateRSTreeFunc();
653         return true;
654     }
655 
656     if (node->EnableDefaultAnimation(animationPlayed)) {
657         WLOGFI("remove window with animation");
658         StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
659         if (node->surfaceNode_) {
660             node->surfaceNode_->SetAppFreeze(true);
661         }
662 	wptr<WindowNode> weakNode(node);
663         RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
664             animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc, [weakNode]() {
665 	    auto weakWindow = weakNode.promote();
666             if (weakWindow && weakWindow->surfaceNode_) {
667                 weakWindow->surfaceNode_->SetAppFreeze(false);
668             }
669         });
670         FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
671     } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
672         !animationPlayed) { // remove keyboard with animation
673         auto timingProtocol = animationConfig_.keyboardAnimationConfig_.durationOut_;
674         RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationConfig_.curve_, updateRSTreeFunc);
675     } else {
676         WLOGFI("remove window without animation");
677         updateRSTreeFunc();
678     }
679     return true;
680 }
681 
Destroy()682 const std::vector<uint32_t>& WindowNodeContainer::Destroy()
683 {
684     // clear vector cache completely, swap with empty vector
685     auto emptyVector = std::vector<uint32_t>();
686     removedIds_.swap(emptyVector);
687     for (auto& node : belowAppWindowNode_->children_) {
688         DestroyWindowNode(node, removedIds_);
689     }
690     for (auto& node : appWindowNode_->children_) {
691         DestroyWindowNode(node, removedIds_);
692     }
693     for (auto& node : aboveAppWindowNode_->children_) {
694         DestroyWindowNode(node, removedIds_);
695     }
696     return removedIds_;
697 }
698 
FindRoot(WindowType type) const699 sptr<WindowNode> WindowNodeContainer::FindRoot(WindowType type) const
700 {
701     if (WindowHelper::IsAppWindow(type) || type == WindowType::WINDOW_TYPE_DOCK_SLICE ||
702         type == WindowType::WINDOW_TYPE_APP_COMPONENT || type == WindowType::WINDOW_TYPE_PLACEHOLDER ||
703         type == WindowType::WINDOW_TYPE_DIALOG) {
704         return appWindowNode_;
705     }
706     if (WindowHelper::IsBelowSystemWindow(type)) {
707         return belowAppWindowNode_;
708     }
709     if (WindowHelper::IsAboveSystemWindow(type)) {
710         return aboveAppWindowNode_;
711     }
712     return nullptr;
713 }
714 
FindWindowNodeById(uint32_t id) const715 sptr<WindowNode> WindowNodeContainer::FindWindowNodeById(uint32_t id) const
716 {
717     std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
718     for (const auto& rootNode : rootNodes) {
719         for (auto& node : rootNode->children_) {
720             if (node->GetWindowId() == id) {
721                 return node;
722             }
723             for (auto& subNode : node->children_) {
724                 if (subNode->GetWindowId() == id) {
725                     return subNode;
726                 }
727             }
728         }
729     }
730     return nullptr;
731 }
732 
UpdateFocusStatus(uint32_t id,bool focused)733 void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused)
734 {
735     auto node = FindWindowNodeById(id);
736     if (node == nullptr) {
737         WLOGFW("cannot find focused window id:%{public}d", id);
738         return;
739     }
740     if (focused) {
741         focusedPid_ = node->GetCallingPid();
742     }
743 
744     if (node->GetCallingPid() == 0) {
745         WLOGFW("focused window is starting window, no need notify");
746         return;
747     }
748 
749     if (focused && node->GetWindowProperty() != nullptr) {
750         AbilityInfo info = node->GetWindowProperty()->GetAbilityInfo();
751         WLOGFW("current focus window: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
752             " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", id,
753             node->GetWindowProperty()->GetWindowName().c_str(), info.bundleName_.c_str(), info.abilityName_.c_str(),
754             node->GetCallingPid(), node->GetCallingUid());
755         FocusAppInfo appInfo = { node->GetCallingPid(), node->GetCallingUid(), info.bundleName_, info.abilityName_ };
756         RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
757     }
758     if (node->GetWindowToken()) {
759         node->GetWindowToken()->UpdateFocusStatus(focused);
760     }
761     if (node->abilityToken_ == nullptr) {
762         WLOGFI("abilityToken is null, window : %{public}d", id);
763     }
764     sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(node->GetWindowId(), node->GetDisplayId(),
765         node->GetCallingPid(), node->GetCallingUid(), node->GetWindowType(), node->abilityToken_);
766     WindowManagerAgentController::GetInstance().UpdateFocusChangeInfo(
767         focusChangeInfo, focused);
768 }
769 
UpdateActiveStatus(uint32_t id,bool isActive)770 void WindowNodeContainer::UpdateActiveStatus(uint32_t id, bool isActive)
771 {
772     auto node = FindWindowNodeById(id);
773     if (node == nullptr) {
774         WLOGFE("cannot find active window id: %{public}d", id);
775         return;
776     }
777     if (isActive) {
778         activePid_ = node->GetCallingPid();
779     }
780     if (node->GetWindowToken()) {
781         node->GetWindowToken()->UpdateActiveStatus(isActive);
782     }
783 }
784 
UpdateBrightness(uint32_t id,bool byRemoved)785 void WindowNodeContainer::UpdateBrightness(uint32_t id, bool byRemoved)
786 {
787     auto node = FindWindowNodeById(id);
788     if (node == nullptr) {
789         WLOGFE("cannot find active window id: %{public}d", id);
790         return;
791     }
792 
793     if (!byRemoved) {
794         if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
795             return;
796         }
797     }
798     WLOGFI("brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), node->GetBrightness());
799     if (std::fabs(node->GetBrightness() - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
800         if (GetDisplayBrightness() != node->GetBrightness()) {
801             WLOGFI("adjust brightness with default value");
802             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
803             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
804         }
805         SetBrightnessWindow(INVALID_WINDOW_ID);
806     } else {
807         if (GetDisplayBrightness() != node->GetBrightness()) {
808             WLOGFI("adjust brightness with value: %{public}u", ToOverrideBrightness(node->GetBrightness()));
809             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
810                 ToOverrideBrightness(node->GetBrightness()));
811             SetDisplayBrightness(node->GetBrightness());
812         }
813         SetBrightnessWindow(node->GetWindowId());
814     }
815 }
816 
AssignZOrder()817 void WindowNodeContainer::AssignZOrder()
818 {
819     zOrder_ = 0;
820     WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
821         if (!node->leashWinSurfaceNode_ && !node->surfaceNode_ && !node->startingWinSurfaceNode_) {
822             ++zOrder_;
823             WLOGFE("Id: %{public}u has no surface nodes", node->GetWindowId());
824             return false;
825         }
826         if (node->leashWinSurfaceNode_ != nullptr) {
827             ++zOrder_;
828             node->leashWinSurfaceNode_->SetPositionZ(zOrder_);
829         }
830 
831         if (node->surfaceNode_ != nullptr) {
832             ++zOrder_;
833             node->surfaceNode_->SetPositionZ(zOrder_);
834             node->zOrder_ = zOrder_;
835         }
836         // make sure starting window above app
837         if (node->startingWinSurfaceNode_ != nullptr) {
838             ++zOrder_;
839             node->startingWinSurfaceNode_->SetPositionZ(zOrder_);
840         }
841         return false;
842     };
843     TraverseWindowTree(func, false);
844     displayGroupController_->UpdateDisplayGroupWindowTree();
845 }
846 
SetFocusWindow(uint32_t windowId)847 WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
848 {
849     if (focusedWindow_ == windowId) {
850         WLOGFI("focused window no change, id: %{public}u, %{public}d", windowId, focusedPid_);
851         // StartingWindow can be focused and this pid is 0, then notify info in UpdateFocusStatus.
852         // This info is invalid, so we must notify again when first frame callback.
853         if (focusedPid_ == 0) {
854             UpdateFocusStatus(windowId, true);
855         }
856         return WMError::WM_DO_NOTHING;
857     }
858     UpdateFocusStatus(focusedWindow_, false);
859     focusedWindow_ = windowId;
860     UpdateFocusStatus(focusedWindow_, true);
861     return WMError::WM_OK;
862 }
863 
GetFocusWindow() const864 uint32_t WindowNodeContainer::GetFocusWindow() const
865 {
866     return focusedWindow_;
867 }
868 
SetActiveWindow(uint32_t windowId,bool byRemoved)869 WMError WindowNodeContainer::SetActiveWindow(uint32_t windowId, bool byRemoved)
870 {
871     if (activeWindow_ == windowId) {
872         WLOGI("active window not change, id: %{public}u, %{public}d", windowId, activePid_);
873         if (activePid_ == 0) {
874             UpdateActiveStatus(windowId, true);
875         }
876         return WMError::WM_DO_NOTHING;
877     }
878     UpdateActiveStatus(activeWindow_, false);
879     activeWindow_ = windowId;
880     UpdateActiveStatus(activeWindow_, true);
881     UpdateBrightness(activeWindow_, byRemoved);
882     return WMError::WM_OK;
883 }
884 
SetDisplayBrightness(float brightness)885 void WindowNodeContainer::SetDisplayBrightness(float brightness)
886 {
887     displayBrightness_ = brightness;
888 }
889 
GetDisplayBrightness() const890 float WindowNodeContainer::GetDisplayBrightness() const
891 {
892     return displayBrightness_;
893 }
894 
SetBrightnessWindow(uint32_t windowId)895 void WindowNodeContainer::SetBrightnessWindow(uint32_t windowId)
896 {
897     brightnessWindow_ = windowId;
898 }
899 
GetBrightnessWindow() const900 uint32_t WindowNodeContainer::GetBrightnessWindow() const
901 {
902     return brightnessWindow_;
903 }
904 
ToOverrideBrightness(float brightness)905 uint32_t WindowNodeContainer::ToOverrideBrightness(float brightness)
906 {
907     return static_cast<uint32_t>(brightness * MAX_BRIGHTNESS);
908 }
909 
GetActiveWindow() const910 uint32_t WindowNodeContainer::GetActiveWindow() const
911 {
912     return activeWindow_;
913 }
914 
GetLayoutPolicy() const915 sptr<WindowLayoutPolicy> WindowNodeContainer::GetLayoutPolicy() const
916 {
917     return layoutPolicy_;
918 }
919 
GetAvoidController() const920 sptr<AvoidAreaController> WindowNodeContainer::GetAvoidController() const
921 {
922     return avoidController_;
923 }
924 
GetMultiDisplayController() const925 sptr<DisplayGroupController> WindowNodeContainer::GetMultiDisplayController() const
926 {
927     return displayGroupController_;
928 }
929 
GetRootNode(WindowRootNodeType type) const930 sptr<WindowNode> WindowNodeContainer::GetRootNode(WindowRootNodeType type) const
931 {
932     if (type == WindowRootNodeType::ABOVE_WINDOW_NODE) {
933         return aboveAppWindowNode_;
934     } else if (type == WindowRootNodeType::APP_WINDOW_NODE) {
935         return appWindowNode_;
936     } else if (type == WindowRootNodeType::BELOW_WINDOW_NODE) {
937         return belowAppWindowNode_;
938     }
939     return nullptr;
940 }
941 
HandleKeepScreenOn(const sptr<WindowNode> & node,bool requireLock)942 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)
943 {
944     if (requireLock && node->keepScreenLock_ == nullptr) {
945         // reset ipc identity
946         std::string identity = IPCSkeleton::ResetCallingIdentity();
947         node->keepScreenLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(node->GetWindowName(),
948             PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
949         // set ipc identity to raw
950         IPCSkeleton::SetCallingIdentity(identity);
951     }
952     if (node->keepScreenLock_ == nullptr) {
953         return;
954     }
955     WLOGFI("handle keep screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), requireLock);
956     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "container:HandleKeepScreenOn(%s, %d)",
957         node->GetWindowName().c_str(), requireLock);
958     ErrCode res;
959     // reset ipc identity
960     std::string identity = IPCSkeleton::ResetCallingIdentity();
961     if (requireLock) {
962         res = node->keepScreenLock_->Lock();
963     } else {
964         res = node->keepScreenLock_->UnLock();
965     }
966     // set ipc identity to raw
967     IPCSkeleton::SetCallingIdentity(identity);
968     if (res != ERR_OK) {
969         WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]", requireLock, res);
970     }
971 }
972 
IsAboveSystemBarNode(sptr<WindowNode> node) const973 bool WindowNodeContainer::IsAboveSystemBarNode(sptr<WindowNode> node) const
974 {
975     int32_t curPriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
976     if ((curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_STATUS_BAR)) &&
977         (curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_NAVIGATION_BAR))) {
978         return true;
979     }
980     return false;
981 }
982 
IsSplitImmersiveNode(sptr<WindowNode> node) const983 bool WindowNodeContainer::IsSplitImmersiveNode(sptr<WindowNode> node) const
984 {
985     auto type = node->GetWindowType();
986     return node->IsSplitMode() || type == WindowType::WINDOW_TYPE_DOCK_SLICE;
987 }
988 
GetExpectImmersiveProperty() const989 std::unordered_map<WindowType, SystemBarProperty> WindowNodeContainer::GetExpectImmersiveProperty() const
990 {
991     std::unordered_map<WindowType, SystemBarProperty> sysBarPropMap {
992         { WindowType::WINDOW_TYPE_STATUS_BAR,     SystemBarProperty() },
993         { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() },
994     };
995 
996     std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
997     for (const auto& node : rootNodes) {
998         for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); ++iter) {
999             auto& sysBarPropMapNode = (*iter)->GetSystemBarProperty();
1000             if (IsAboveSystemBarNode(*iter)) {
1001                 continue;
1002             }
1003             if (WindowHelper::IsFullScreenWindow((*iter)->GetWindowMode())
1004 	        && (*iter)->GetWindowType() != WindowType::WINDOW_TYPE_PANEL) {
1005                 WLOGFI("Top immersive window id: %{public}d. Use full immersive prop", (*iter)->GetWindowId());
1006                 for (auto it : sysBarPropMap) {
1007                     sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1008                 }
1009                 return sysBarPropMap;
1010             } else if (IsSplitImmersiveNode(*iter)) {
1011                 WLOGFI("Top split window id: %{public}d. Use split immersive prop", (*iter)->GetWindowId());
1012                 for (auto it : sysBarPropMap) {
1013                     sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1014                     sysBarPropMap[it.first].enable_ = false;
1015                 }
1016                 return sysBarPropMap;
1017             }
1018         }
1019     }
1020 
1021     WLOGFI("No immersive window on top. Use default systembar Property");
1022     return sysBarPropMap;
1023 }
1024 
NotifyIfAvoidAreaChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1025 void WindowNodeContainer::NotifyIfAvoidAreaChanged(const sptr<WindowNode>& node,
1026     const AvoidControlType avoidType) const
1027 {
1028     auto checkFunc = [this](sptr<WindowNode> node) {
1029         return CheckWindowNodeWhetherInWindowTree(node);
1030     };
1031     avoidController_->ProcessWindowChange(node, avoidType, checkFunc);
1032     if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
1033         NotifyIfSystemBarRegionChanged(node->GetDisplayId());
1034     } else {
1035         NotifyIfSystemBarTintChanged(node->GetDisplayId());
1036     }
1037 
1038     NotifyIfKeyboardRegionChanged(node, avoidType);
1039 }
1040 
BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const1041 void WindowNodeContainer::BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const
1042 {
1043     avoidController_->SetFlagForProcessWindowChange(true);
1044 }
1045 
ProcessWindowAvoidAreaChangeWhenDisplayChange() const1046 void WindowNodeContainer::ProcessWindowAvoidAreaChangeWhenDisplayChange() const
1047 {
1048     avoidController_->SetFlagForProcessWindowChange(false);
1049     auto checkFunc = [this](sptr<WindowNode> node) {
1050         return CheckWindowNodeWhetherInWindowTree(node);
1051     };
1052     WindowNodeOperationFunc func = [avoidController = avoidController_, &checkFunc](sptr<WindowNode> node) {
1053         avoidController->ProcessWindowChange(node, AvoidControlType::AVOID_NODE_UPDATE, checkFunc);
1054         return false;
1055     };
1056     TraverseWindowTree(func, true);
1057 }
1058 
NotifyIfSystemBarTintChanged(DisplayId displayId) const1059 void WindowNodeContainer::NotifyIfSystemBarTintChanged(DisplayId displayId) const
1060 {
1061     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1062     auto expectSystemBarProp = GetExpectImmersiveProperty();
1063     SystemBarRegionTints tints;
1064     SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1065     for (auto it : sysBarTintMap) {
1066         auto expectProp = expectSystemBarProp.find(it.first)->second;
1067         if (it.second.prop_ == expectProp) {
1068             continue;
1069         }
1070         WLOGFI("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x",
1071             static_cast<int32_t>(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_);
1072         sysBarTintMap[it.first].prop_ = expectProp;
1073         sysBarTintMap[it.first].type_ = it.first;
1074         tints.emplace_back(sysBarTintMap[it.first]);
1075     }
1076     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1077 }
1078 
NotifyIfSystemBarRegionChanged(DisplayId displayId) const1079 void WindowNodeContainer::NotifyIfSystemBarRegionChanged(DisplayId displayId) const
1080 {
1081     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1082     SystemBarRegionTints tints;
1083     SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1084     SysBarNodeMap& sysBarNodeMap = displayGroupController_->sysBarNodeMaps_[displayId];
1085     for (auto it : sysBarTintMap) { // split screen mode not support yet
1086         auto sysNode = sysBarNodeMap[it.first];
1087         if (sysNode == nullptr || it.second.region_ == sysNode->GetWindowRect()) {
1088             continue;
1089         }
1090         const Rect& newRegion = sysNode->GetWindowRect();
1091         sysBarTintMap[it.first].region_ = newRegion;
1092         sysBarTintMap[it.first].type_ = it.first;
1093         tints.emplace_back(sysBarTintMap[it.first]);
1094         WLOGFI("system bar region update, type: %{public}d" \
1095             "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
1096             static_cast<int32_t>(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_);
1097     }
1098     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1099 }
1100 
NotifyIfKeyboardRegionChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1101 void WindowNodeContainer::NotifyIfKeyboardRegionChanged(const sptr<WindowNode>& node,
1102     const AvoidControlType avoidType) const
1103 {
1104     if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1105         WLOGFD("windowType: %{public}u", node->GetWindowType());
1106         return;
1107     }
1108 
1109     auto callingWindow = FindWindowNodeById(node->GetCallingWindow());
1110     if (callingWindow == nullptr) {
1111         WLOGFI("callingWindow: %{public}u does not be set", node->GetCallingWindow());
1112         callingWindow = FindWindowNodeById(GetFocusWindow());
1113     }
1114     if (callingWindow == nullptr || callingWindow->GetWindowToken() == nullptr) {
1115         WLOGFE("does not have correct callingWindow for input method window");
1116         return;
1117     }
1118     const WindowMode callingWindowMode = callingWindow->GetWindowMode();
1119     if (callingWindowMode == WindowMode::WINDOW_MODE_FULLSCREEN ||
1120         callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1121         callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
1122         const Rect keyRect = node->GetWindowRect();
1123         const Rect callingRect = callingWindow->GetWindowRect();
1124         if (WindowHelper::IsEmptyRect(WindowHelper::GetOverlap(callingRect, keyRect, 0, 0))) {
1125             WLOGFD("no overlap between two windows");
1126             return;
1127         }
1128         Rect overlapRect = { 0, 0, 0, 0 };
1129         if (avoidType == AvoidControlType::AVOID_NODE_ADD || avoidType == AvoidControlType::AVOID_NODE_UPDATE) {
1130             overlapRect = WindowHelper::GetOverlap(keyRect, callingRect, callingRect.posX_, callingRect.posY_);
1131         }
1132 
1133         WLOGFI("keyboard size change callingWindow: [%{public}s, %{public}u], " \
1134         "overlap rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
1135             callingWindow->GetWindowName().c_str(), callingWindow->GetWindowId(),
1136             overlapRect.posX_, overlapRect.posY_, overlapRect.width_, overlapRect.height_);
1137         sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT, overlapRect);
1138         callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info);
1139         return;
1140     }
1141     WLOGFE("does not have correct callingWindowMode for input method window");
1142 }
1143 
NotifySystemBarTints(std::vector<DisplayId> displayIdVec)1144 void WindowNodeContainer::NotifySystemBarTints(std::vector<DisplayId> displayIdVec)
1145 {
1146     if (displayIdVec.size() != displayGroupController_->sysBarTintMaps_.size()) {
1147         WLOGE("[Immersive] the number of display is error");
1148     }
1149 
1150     for (auto displayId : displayIdVec) {
1151         SystemBarRegionTints tints;
1152         SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1153         for (auto it : sysBarTintMap) {
1154             WLOGFI("[Immersive] system bar cur notify, T: %{public}d, " \
1155                 "V: %{public}d, C: %{public}x | %{public}x, " \
1156                 "R: [%{public}d, %{public}d, %{public}d, %{public}d]",
1157                 static_cast<int32_t>(it.first),
1158                 sysBarTintMap[it.first].prop_.enable_,
1159                 sysBarTintMap[it.first].prop_.backgroundColor_, sysBarTintMap[it.first].prop_.contentColor_,
1160                 sysBarTintMap[it.first].region_.posX_, sysBarTintMap[it.first].region_.posY_,
1161                 sysBarTintMap[it.first].region_.width_, sysBarTintMap[it.first].region_.height_);
1162             tints.push_back(sysBarTintMap[it.first]);
1163         }
1164         WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1165     }
1166 }
1167 
NotifyDockWindowStateChanged(sptr<WindowNode> & node,bool isEnable)1168 void WindowNodeContainer::NotifyDockWindowStateChanged(sptr<WindowNode>& node, bool isEnable)
1169 {
1170     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1171     WLOGFI("[Immersive] begin isEnable: %{public}d", isEnable);
1172     if (isEnable) {
1173         for (auto& windowNode : appWindowNode_->children_) {
1174             if (windowNode->GetWindowId() == node->GetWindowId()) {
1175                 continue;
1176             }
1177             if (!WindowHelper::IsFloatingWindow(windowNode->GetWindowMode())) {
1178                 return;
1179             }
1180         }
1181     }
1182     SystemBarProperty prop;
1183     prop.enable_ = isEnable;
1184     SystemBarRegionTint tint;
1185     tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1186     tint.prop_ = prop;
1187     SystemBarRegionTints tints;
1188     tints.push_back(tint);
1189     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(node->GetDisplayId(), tints);
1190 }
1191 
UpdateAvoidAreaListener(sptr<WindowNode> & windowNode,bool haveAvoidAreaListener)1192 void WindowNodeContainer::UpdateAvoidAreaListener(sptr<WindowNode>& windowNode, bool haveAvoidAreaListener)
1193 {
1194     avoidController_->UpdateAvoidAreaListener(windowNode, haveAvoidAreaListener);
1195 }
1196 
IsTopWindow(uint32_t windowId,sptr<WindowNode> & rootNode) const1197 bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const
1198 {
1199     if (rootNode->children_.empty()) {
1200         WLOGFE("root does not have any node");
1201         return false;
1202     }
1203     auto node = *(rootNode->children_.rbegin());
1204     if (node == nullptr) {
1205         WLOGFE("window tree does not have any node");
1206         return false;
1207     }
1208 
1209     for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); iter++) {
1210         if ((*iter)->priority_ > 0) {
1211             return (*iter)->GetWindowId() == windowId;
1212         } else {
1213             break;
1214         }
1215     }
1216     return node->GetWindowId() == windowId;
1217 }
1218 
RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>> & orderedNodes,std::vector<sptr<WindowNode>> & windowNodes)1219 void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes,
1220     std::vector<sptr<WindowNode>>& windowNodes)
1221 {
1222     for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
1223         uint32_t wid = (*iter)->GetWindowId();
1224         auto orderedIter = std::find_if(orderedNodes.begin(), orderedNodes.end(),
1225             [wid] (sptr<WindowNode> orderedNode) { return orderedNode->GetWindowId() == wid; });
1226         if (orderedIter != orderedNodes.end()) {
1227             iter = windowNodes.erase(iter);
1228         } else {
1229             iter++;
1230         }
1231     }
1232     for (auto iter = orderedNodes.begin(); iter != orderedNodes.end(); iter++) {
1233         UpdateWindowTree(*iter);
1234     }
1235     return;
1236 }
1237 
RaiseWindowToTop(uint32_t windowId,std::vector<sptr<WindowNode>> & windowNodes)1238 void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)
1239 {
1240     if (windowNodes.empty()) {
1241         WLOGFE("windowNodes is empty!");
1242         return;
1243     }
1244     auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
1245                              [windowId](sptr<WindowNode> node) {
1246                                  return node->GetWindowId() == windowId;
1247                              });
1248     // raise app node window to top
1249     if (iter != windowNodes.end()) {
1250         sptr<WindowNode> node = *iter;
1251         windowNodes.erase(iter);
1252         UpdateWindowTree(node);
1253         WLOGFI("raise window to top %{public}u", node->GetWindowId());
1254     }
1255 }
1256 
TraverseContainer(std::vector<sptr<WindowNode>> & windowNodes) const1257 void WindowNodeContainer::TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const
1258 {
1259     for (auto& node : belowAppWindowNode_->children_) {
1260         TraverseWindowNode(node, windowNodes);
1261     }
1262     for (auto& node : appWindowNode_->children_) {
1263         TraverseWindowNode(node, windowNodes);
1264     }
1265     for (auto& node : aboveAppWindowNode_->children_) {
1266         TraverseWindowNode(node, windowNodes);
1267     }
1268     std::reverse(windowNodes.begin(), windowNodes.end());
1269 }
1270 
TraverseWindowNode(sptr<WindowNode> & node,std::vector<sptr<WindowNode>> & windowNodes) const1271 void WindowNodeContainer::TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const
1272 {
1273     if (node == nullptr) {
1274         return;
1275     }
1276     auto iter = node->children_.begin();
1277     for (; iter < node->children_.end(); ++iter) {
1278         if ((*iter)->priority_ < 0) {
1279             windowNodes.emplace_back(*iter);
1280         } else {
1281             break;
1282         }
1283     }
1284     windowNodes.emplace_back(node);
1285     for (; iter < node->children_.end(); ++iter) {
1286         windowNodes.emplace_back(*iter);
1287     }
1288 }
1289 
GetAvoidAreaByType(const sptr<WindowNode> & node,AvoidAreaType avoidAreaType) const1290 AvoidArea WindowNodeContainer::GetAvoidAreaByType(const sptr<WindowNode>& node, AvoidAreaType avoidAreaType) const
1291 {
1292     if (CheckWindowNodeWhetherInWindowTree(node)) {
1293         return avoidController_->GetAvoidAreaByType(node, avoidAreaType);
1294     }
1295     return {};
1296 }
1297 
CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode> & node) const1298 bool WindowNodeContainer::CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode>& node) const
1299 {
1300     bool isInWindowTree = false;
1301     WindowNodeOperationFunc func = [&node, &isInWindowTree](sptr<WindowNode> windowNode) {
1302         if (node->GetWindowId() == windowNode->GetWindowId()) {
1303             isInWindowTree = true;
1304             return true;
1305         }
1306         return false;
1307     };
1308     TraverseWindowTree(func, true);
1309     return isInWindowTree;
1310 }
1311 
DumpScreenWindowTree()1312 void WindowNodeContainer::DumpScreenWindowTree()
1313 {
1314     WLOGFI("-------- dump window info begin---------");
1315     WLOGFI("WindowName DisplayId WinId Type Mode Flag ZOrd Orientation abilityToken [   x    y    w    h]");
1316     uint32_t zOrder = zOrder_;
1317     WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
1318         Rect rect = node->GetWindowRect();
1319         const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1320             node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1321         WLOGI("DumpScreenWindowTree: %{public}10s %{public}9" PRIu64" %{public}5u %{public}4u %{public}4u %{public}4u "
1322             "%{public}4u %{public}11u %{public}12d [%{public}4d %{public}4d %{public}4u %{public}4u]",
1323             windowName.c_str(), node->GetDisplayId(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1324             node->GetWindowFlags(), --zOrder, static_cast<uint32_t>(node->GetRequestedOrientation()),
1325             node->abilityToken_ != nullptr, rect.posX_, rect.posY_, rect.width_, rect.height_);
1326         return false;
1327     };
1328     TraverseWindowTree(func, true);
1329     WLOGFI("-------- dump window info end  ---------");
1330 }
1331 
GetDisplayRect(DisplayId displayId) const1332 Rect WindowNodeContainer::GetDisplayRect(DisplayId displayId) const
1333 {
1334     return displayGroupInfo_->GetDisplayRect(displayId);
1335 }
1336 
IsVerticalDisplay(DisplayId displayId) const1337 bool WindowNodeContainer::IsVerticalDisplay(DisplayId displayId) const
1338 {
1339     return displayGroupInfo_->GetDisplayRect(displayId).width_ < displayGroupInfo_->GetDisplayRect(displayId).height_;
1340 }
1341 
ProcessWindowStateChange(WindowState state,WindowStateChangeReason reason)1342 void WindowNodeContainer::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)
1343 {
1344     switch (reason) {
1345         case WindowStateChangeReason::KEYGUARD: {
1346             int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
1347             TraverseAndUpdateWindowState(state, topPriority);
1348             break;
1349         }
1350         default:
1351             return;
1352     }
1353 }
1354 
TraverseAndUpdateWindowState(WindowState state,int32_t topPriority)1355 void WindowNodeContainer::TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)
1356 {
1357     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1358     for (auto& node : rootNodes) {
1359         UpdateWindowState(node, topPriority, state);
1360     }
1361 }
1362 
UpdateWindowState(sptr<WindowNode> node,int32_t topPriority,WindowState state)1363 void WindowNodeContainer::UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)
1364 {
1365     if (node == nullptr) {
1366         return;
1367     }
1368     if (node->parent_ != nullptr && node->currentVisibility_) {
1369         if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
1370             !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
1371             if (node->GetWindowToken()) {
1372                 node->GetWindowToken()->UpdateWindowState(state);
1373             }
1374             HandleKeepScreenOn(node, state);
1375         }
1376     }
1377     for (auto& childNode : node->children_) {
1378         UpdateWindowState(childNode, topPriority, state);
1379     }
1380 }
1381 
HandleKeepScreenOn(const sptr<WindowNode> & node,WindowState state)1382 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)
1383 {
1384     if (node == nullptr) {
1385         WLOGFE("window is invalid");
1386         return;
1387     }
1388     if (state == WindowState::STATE_FROZEN) {
1389         HandleKeepScreenOn(node, false);
1390     } else if (state == WindowState::STATE_UNFROZEN) {
1391         HandleKeepScreenOn(node, node->IsKeepScreenOn());
1392     } else {
1393         // do nothing
1394     }
1395 }
1396 
FindDividerNode() const1397 sptr<WindowNode> WindowNodeContainer::FindDividerNode() const
1398 {
1399     for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) {
1400         if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1401             return *iter;
1402         }
1403     }
1404     return nullptr;
1405 }
1406 
RaiseSplitRelatedWindowToTop(sptr<WindowNode> & node)1407 void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
1408 {
1409     if (node == nullptr) {
1410         return;
1411     }
1412     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
1413     if (windowPair == nullptr) {
1414         WLOGFE("Window pair is nullptr");
1415         return;
1416     }
1417     std::vector<sptr<WindowNode>> orderedPair = windowPair->GetOrderedPair(node);
1418     RaiseOrderedWindowToTop(orderedPair, appWindowNode_->children_);
1419     AssignZOrder();
1420     return;
1421 }
1422 
RaiseZOrderForAppWindow(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)1423 WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
1424 {
1425     if (node == nullptr) {
1426         return WMError::WM_ERROR_NULLPTR;
1427     }
1428     if (IsTopWindow(node->GetWindowId(), appWindowNode_) || IsTopWindow(node->GetWindowId(), aboveAppWindowNode_)) {
1429         WLOGFI("it is already top app window, id: %{public}u", node->GetWindowId());
1430         return WMError::WM_ERROR_INVALID_TYPE;
1431     }
1432 
1433     if (WindowHelper::IsSubWindow(node->GetWindowType()) ||
1434         (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1435         if (parentNode == nullptr) {
1436             WLOGFE("window type is invalid");
1437             return WMError::WM_ERROR_NULLPTR;
1438         }
1439         RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself
1440         if (parentNode->IsSplitMode()) {
1441             RaiseSplitRelatedWindowToTop(parentNode);
1442         } else if (parentNode->parent_ != nullptr) {
1443             RaiseWindowToTop(parentNode->GetWindowId(), parentNode->parent_->children_); // raise parent window
1444         }
1445     } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
1446         if (node->IsSplitMode()) {
1447             RaiseSplitRelatedWindowToTop(node);
1448         } else {
1449             // remote animation continuous start and exit allow parent is nullptr
1450             if (node->parent_ == nullptr) {
1451                 WLOGFW("node parent is nullptr");
1452                 return WMError::WM_OK;
1453             }
1454             RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
1455         }
1456     } else {
1457         // do nothing
1458     }
1459     AssignZOrder();
1460     WLOGFI("RaiseZOrderForAppWindow finished");
1461     DumpScreenWindowTree();
1462     return WMError::WM_OK;
1463 }
1464 
GetNextFocusableWindow(uint32_t windowId) const1465 sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
1466 {
1467     sptr<WindowNode> nextFocusableWindow;
1468     bool previousFocusedWindowFound = false;
1469     WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
1470         sptr<WindowNode> node) {
1471         if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable() && node->currentVisibility_) {
1472             nextFocusableWindow = node;
1473             return true;
1474         }
1475         if (node->GetWindowId() == windowId) {
1476             previousFocusedWindowFound = true;
1477         }
1478         return false;
1479     };
1480     TraverseWindowTree(func, true);
1481     return nextFocusableWindow;
1482 }
1483 
GetNextRotatableWindow(uint32_t windowId) const1484 sptr<WindowNode> WindowNodeContainer::GetNextRotatableWindow(uint32_t windowId) const
1485 {
1486     sptr<WindowNode> nextRotatableWindow;
1487     WindowNodeOperationFunc func = [windowId, &nextRotatableWindow](
1488         sptr<WindowNode> node) {
1489         if (windowId != node->GetWindowId() &&
1490             WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
1491             nextRotatableWindow = node;
1492             return true;
1493         }
1494         return false;
1495     };
1496     TraverseWindowTree(func, true);
1497     return nextRotatableWindow;
1498 }
1499 
GetNextActiveWindow(uint32_t windowId) const1500 sptr<WindowNode> WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) const
1501 {
1502     auto currentNode = FindWindowNodeById(windowId);
1503     if (currentNode == nullptr) {
1504         WLOGFE("cannot find window id: %{public}u by tree", windowId);
1505         return nullptr;
1506     }
1507     WLOGFI("current window: [%{public}u, %{public}u]", windowId, static_cast<uint32_t>(currentNode->GetWindowType()));
1508     if (WindowHelper::IsSystemWindow(currentNode->GetWindowType())) {
1509         for (auto& node : appWindowNode_->children_) {
1510             if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1511                 continue;
1512             }
1513             return node;
1514         }
1515         for (auto& node : belowAppWindowNode_->children_) {
1516             if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1517                 return node;
1518             }
1519         }
1520     } else if (WindowHelper::IsAppWindow(currentNode->GetWindowType())) {
1521         std::vector<sptr<WindowNode>> windowNodes;
1522         TraverseContainer(windowNodes);
1523         auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), [windowId](sptr<WindowNode>& node) {
1524             return node->GetWindowId() == windowId;
1525             });
1526         if (iter == windowNodes.end()) {
1527             WLOGFE("could not find this window");
1528             return nullptr;
1529         }
1530         int index = std::distance(windowNodes.begin(), iter);
1531         for (size_t i = static_cast<size_t>(index) + 1; i < windowNodes.size(); i++) {
1532             if (windowNodes[i]->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE
1533                 || !windowNodes[i]->currentVisibility_) {
1534                 continue;
1535             }
1536             return windowNodes[i];
1537         }
1538     } else {
1539         // do nothing
1540     }
1541     WLOGFE("could not get next active window");
1542     return nullptr;
1543 }
1544 
IsForbidDockSliceMove(DisplayId displayId) const1545 bool WindowNodeContainer::IsForbidDockSliceMove(DisplayId displayId) const
1546 {
1547     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1548     if (windowPair == nullptr) {
1549         WLOGFE("window pair is nullptr");
1550         return true;
1551     }
1552     if (windowPair->IsForbidDockSliceMove()) {
1553         return true;
1554     }
1555     return false;
1556 }
1557 
IsDockSliceInExitSplitModeArea(DisplayId displayId) const1558 bool WindowNodeContainer::IsDockSliceInExitSplitModeArea(DisplayId displayId) const
1559 {
1560     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1561     if (windowPair == nullptr) {
1562         WLOGFE("window pair is nullptr");
1563         return false;
1564     }
1565     std::vector<int32_t> exitSplitPoints = layoutPolicy_->GetExitSplitPoints(displayId);
1566     if (exitSplitPoints.size() != EXIT_SPLIT_POINTS_NUMBER) {
1567         return false;
1568     }
1569     return windowPair->IsDockSliceInExitSplitModeArea(exitSplitPoints);
1570 }
1571 
ExitSplitMode(DisplayId displayId)1572 void WindowNodeContainer::ExitSplitMode(DisplayId displayId)
1573 {
1574     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1575     if (windowPair == nullptr) {
1576         WLOGFE("window pair is nullptr");
1577         return;
1578     }
1579     windowPair->ExitSplitMode();
1580 }
1581 
MinimizeAllAppWindows(DisplayId displayId)1582 void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId)
1583 {
1584     WMError ret = MinimizeAppNodeExceptOptions(MinimizeReason::MINIMIZE_ALL);
1585     SwitchLayoutPolicy(WindowLayoutMode::CASCADE, displayId);
1586     if (ret != WMError::WM_OK) {
1587         WLOGFE("Minimize all app window failed");
1588     }
1589     return;
1590 }
1591 
GetDeskTopWindow()1592 sptr<WindowNode> WindowNodeContainer::GetDeskTopWindow()
1593 {
1594     sptr<WindowNode> deskTop;
1595     WindowNodeOperationFunc findDeskTopFunc = [this, &deskTop](sptr<WindowNode> node) {
1596         if (node->GetWindowProperty()->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1597             deskTop = node;
1598             return true;
1599         }
1600         return false;
1601     };
1602     TraverseWindowTree(findDeskTopFunc, false);
1603     return deskTop;
1604 }
1605 
HasPrivateWindow()1606 bool WindowNodeContainer::HasPrivateWindow()
1607 {
1608     std::vector<sptr<WindowNode>> windowNodes;
1609     TraverseContainer(windowNodes);
1610     for (const auto& node : windowNodes) {
1611         if (node->isVisible_ && node->GetWindowProperty()->GetPrivacyMode()) {
1612             WLOGFI("window name %{public}s", node->GetWindowName().c_str());
1613             return true;
1614         }
1615     }
1616     return false;
1617 }
1618 
MinimizeOldestAppWindow()1619 void WindowNodeContainer::MinimizeOldestAppWindow()
1620 {
1621     for (auto& appNode : appWindowNode_->children_) {
1622         if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1623             MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
1624             return;
1625         }
1626     }
1627     for (auto& appNode : aboveAppWindowNode_->children_) {
1628         if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1629             MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
1630             return;
1631         }
1632     }
1633     WLOGFI("no window needs to minimize");
1634 }
1635 
ToggleShownStateForAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc,bool restore)1636 WMError WindowNodeContainer::ToggleShownStateForAllAppWindows(
1637     std::function<bool(uint32_t, WindowMode)> restoreFunc, bool restore)
1638 {
1639     WLOGFI("ToggleShownStateForAllAppWindows");
1640     for (auto node : aboveAppWindowNode_->children_) {
1641         if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT &&
1642             node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && restore) {
1643             return WMError::WM_DO_NOTHING;
1644         }
1645     }
1646     // to do, backup reentry: 1.ToggleShownStateForAllAppWindows fast; 2.this display should reset backupWindowIds_.
1647     if (!restore && appWindowNode_->children_.empty() && !backupWindowIds_.empty()) {
1648         backupWindowIds_.clear();
1649         backupWindowMode_.clear();
1650         backupDisplaySplitWindowMode_.clear();
1651         backupDividerWindowRect_.clear();
1652     }
1653     if (!restore && !appWindowNode_->children_.empty() && backupWindowIds_.empty()) {
1654         WLOGFI("backup");
1655         BackUpAllAppWindows();
1656     } else if (restore && !backupWindowIds_.empty()) {
1657         WLOGFI("restore");
1658         RestoreAllAppWindows(restoreFunc);
1659     } else {
1660         WLOGFI("do nothing because shown app windows is empty or backup windows is empty.");
1661     }
1662     return WMError::WM_OK;
1663 }
1664 
BackUpAllAppWindows()1665 void WindowNodeContainer::BackUpAllAppWindows()
1666 {
1667     std::set<DisplayId> displayIdSet;
1668     backupWindowMode_.clear();
1669     backupDisplaySplitWindowMode_.clear();
1670     std::vector<sptr<WindowNode>> children = appWindowNode_->children_;
1671     for (auto& appNode : children) {
1672         if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
1673             continue;
1674         }
1675         auto windowMode = appNode->GetWindowMode();
1676         backupWindowMode_[appNode->GetWindowId()] = windowMode;
1677         if (WindowHelper::IsSplitWindowMode(windowMode)) {
1678             backupDisplaySplitWindowMode_[appNode->GetDisplayId()].insert(windowMode);
1679         }
1680         displayIdSet.insert(appNode->GetDisplayId());
1681     }
1682     for (auto& appNode : children) {
1683         // exclude exceptional window
1684         if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
1685             WLOGFE("is not main window, windowId:%{public}u", appNode->GetWindowId());
1686             continue;
1687         }
1688         // minimize window
1689         WLOGFD("minimize window, windowId:%{public}u", appNode->GetWindowId());
1690         backupWindowIds_.emplace_back(appNode->GetWindowId());
1691         WindowManagerService::GetInstance().RemoveWindow(appNode->GetWindowId());
1692         wptr<IRemoteObject> abilityToken = appNode->abilityToken_;
1693         WindowInnerManager::GetInstance().PostTask([abilityToken]() {
1694             auto token = abilityToken.promote();
1695             if (token == nullptr) {
1696                 WLOGFW("Ability token is null");
1697                 return;
1698             }
1699             AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(token,
1700                 static_cast<uint32_t>(WindowStateChangeReason::TOGGLING));
1701         });
1702     }
1703     backupDividerWindowRect_.clear();
1704     for (auto displayId : displayIdSet) {
1705         auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1706         if (windowPair == nullptr || windowPair->GetDividerWindow() == nullptr) {
1707             continue;
1708         }
1709         backupDividerWindowRect_[displayId] = windowPair->GetDividerWindow()->GetWindowRect();
1710     }
1711 }
1712 
RestoreAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc)1713 void WindowNodeContainer::RestoreAllAppWindows(std::function<bool(uint32_t, WindowMode)> restoreFunc)
1714 {
1715     std::vector<uint32_t> backupWindowIds(backupWindowIds_);
1716     auto displayIds = DisplayManagerServiceInner::GetInstance().GetAllDisplayIds();
1717     std::vector<sptr<WindowPair>> windowPairs;
1718     for (auto displayId : displayIds) {
1719         auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1720         if (windowPair != nullptr) {
1721             if (backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_PRIMARY) > 0 &&
1722                 backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_SECONDARY) > 0) {
1723                 windowPair->SetAllSplitAppWindowsRestoring(true);
1724             }
1725             windowPairs.emplace_back(windowPair);
1726         }
1727     }
1728     for (auto windowId: backupWindowIds) {
1729         if (!restoreFunc(windowId, backupWindowMode_[windowId])) {
1730             WLOGFE("restore %{public}u failed", windowId);
1731             continue;
1732         }
1733         WLOGFD("restore %{public}u", windowId);
1734     }
1735     for (auto windowPair : windowPairs) {
1736         windowPair->SetAllSplitAppWindowsRestoring(false);
1737     }
1738     layoutPolicy_->SetSplitDividerWindowRects(backupDividerWindowRect_);
1739     backupWindowIds_.clear();
1740     backupWindowMode_.clear();
1741     backupDividerWindowRect_.clear();
1742 }
1743 
IsAppWindowsEmpty() const1744 bool WindowNodeContainer::IsAppWindowsEmpty() const
1745 {
1746     return appWindowNode_->children_.empty();
1747 }
1748 
MinimizeAppNodeExceptOptions(MinimizeReason reason,const std::vector<uint32_t> & exceptionalIds,const std::vector<WindowMode> & exceptionalModes)1749 WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(MinimizeReason reason,
1750     const std::vector<uint32_t> &exceptionalIds, const std::vector<WindowMode> &exceptionalModes)
1751 {
1752     if (appWindowNode_->children_.empty()) {
1753         return WMError::WM_OK;
1754     }
1755     for (auto& appNode : appWindowNode_->children_) {
1756         // exclude exceptional window
1757         if (std::find(exceptionalIds.begin(), exceptionalIds.end(), appNode->GetWindowId()) != exceptionalIds.end() ||
1758             std::find(exceptionalModes.begin(), exceptionalModes.end(),
1759                 appNode->GetWindowMode()) != exceptionalModes.end() ||
1760                 appNode->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1761             continue;
1762         }
1763         MinimizeApp::AddNeedMinimizeApp(appNode, reason);
1764     }
1765     return WMError::WM_OK;
1766 }
1767 
MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode> & node)1768 WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)
1769 {
1770     std::vector<uint32_t> exceptionalIds = { node->GetWindowId() };
1771     std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
1772     return MinimizeAppNodeExceptOptions(MinimizeReason::OTHER_WINDOW, exceptionalIds, exceptionalModes);
1773 }
1774 
ResetLayoutPolicy()1775 void WindowNodeContainer::ResetLayoutPolicy()
1776 {
1777     layoutPolicy_->Reset();
1778 }
1779 
SwitchLayoutPolicy(WindowLayoutMode dstMode,DisplayId displayId,bool reorder)1780 WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder)
1781 {
1782     WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d, reorder: %{public}d, displayId: %{public}" PRIu64"",
1783         static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder), displayId);
1784     if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) {
1785         WLOGFE("invalid layout mode");
1786         return WMError::WM_ERROR_INVALID_PARAM;
1787     }
1788     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1789     if (windowPair == nullptr) {
1790         WLOGFE("Window pair is nullptr");
1791         return WMError::WM_ERROR_NULLPTR;
1792     }
1793     if (layoutMode_ != dstMode) {
1794         if (layoutMode_ == WindowLayoutMode::CASCADE) {
1795             layoutPolicy_->Reset();
1796             windowPair->Clear();
1797         }
1798         layoutMode_ = dstMode;
1799         layoutPolicy_->Clean();
1800         layoutPolicy_ = layoutPolicies_[dstMode];
1801         layoutPolicy_->Launch();
1802         DumpScreenWindowTree();
1803     } else {
1804         WLOGFI("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
1805     }
1806     if (reorder) {
1807         windowPair->Clear();
1808         layoutPolicy_->Reorder();
1809         DumpScreenWindowTree();
1810     }
1811     NotifyIfSystemBarTintChanged(displayId);
1812     return WMError::WM_OK;
1813 }
1814 
UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode> & node,bool up)1815 void WindowNodeContainer::UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode>& node, bool up)
1816 {
1817     if (!WindowHelper::IsWindowModeSupported(node->GetWindowProperty()->GetRequestModeSupportInfo(),
1818                                              WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
1819         WLOGFD("window doesn't support split mode, winId: %{public}d", node->GetWindowId());
1820         return;
1821     }
1822     uint32_t modeSupportInfo;
1823     if (up) {
1824         modeSupportInfo = node->GetModeSupportInfo() & (~WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY);
1825     } else {
1826         modeSupportInfo = node->GetModeSupportInfo() | WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY;
1827     }
1828     node->SetModeSupportInfo(modeSupportInfo);
1829     if (node->GetWindowToken() != nullptr) {
1830         node->GetWindowToken()->UpdateWindowModeSupportInfo(modeSupportInfo);
1831     }
1832 }
1833 
RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode> & node) const1834 void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const
1835 {
1836     if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || !isScreenLocked_) {
1837         return;
1838     }
1839 
1840     WLOGFI("raise input method float window priority.");
1841     node->priority_ = zorderPolicy_->GetWindowPriority(
1842         WindowType::WINDOW_TYPE_KEYGUARD) + 2; // 2: higher than keyguard and show when locked window
1843 }
1844 
ReZOrderShowWhenLockedWindows(bool up)1845 void WindowNodeContainer::ReZOrderShowWhenLockedWindows(bool up)
1846 {
1847     WLOGFI("Keyguard change %{public}u, re-zorder showWhenLocked window", up);
1848     std::vector<sptr<WindowNode>> needReZOrderNodes;
1849     auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_;
1850     auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_;
1851 
1852     auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 :
1853         zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
1854 
1855     for (auto iter = srcRoot->children_.begin(); iter != srcRoot->children_.end();) {
1856         if ((*iter)->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
1857             needReZOrderNodes.emplace_back(*iter);
1858             iter = srcRoot->children_.erase(iter);
1859         } else {
1860             iter++;
1861         }
1862     }
1863 
1864     for (auto& needReZOrderNode : needReZOrderNodes) {
1865         needReZOrderNode->priority_ = dstPriority;
1866         needReZOrderNode->parent_ = dstRoot;
1867         auto parentNode = needReZOrderNode->parent_;
1868         auto position = parentNode->children_.end();
1869         for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
1870             if ((*iter)->priority_ > needReZOrderNode->priority_) {
1871                 position = iter;
1872                 break;
1873             }
1874         }
1875 
1876         UpdateModeSupportInfoWhenKeyguardChange(needReZOrderNode, up);
1877 
1878         parentNode->children_.insert(position, needReZOrderNode);
1879         if (up && WindowHelper::IsSplitWindowMode(needReZOrderNode->GetWindowMode())) {
1880             needReZOrderNode->GetWindowProperty()->ResumeLastWindowMode();
1881             if (needReZOrderNode->GetWindowToken() != nullptr) {
1882                 needReZOrderNode->GetWindowToken()->UpdateWindowMode(needReZOrderNode->GetWindowMode());
1883             }
1884             auto windowPair = displayGroupController_->GetWindowPairByDisplayId(needReZOrderNode->GetDisplayId());
1885             if (windowPair == nullptr) {
1886                 WLOGFE("Window pair is nullptr");
1887                 return;
1888             }
1889             windowPair->UpdateIfSplitRelated(needReZOrderNode);
1890         }
1891         WLOGFI("window %{public}u re-zorder when keyguard change %{public}u", needReZOrderNode->GetWindowId(), up);
1892     }
1893 }
1894 
ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1895 void WindowNodeContainer::ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1896 {
1897     if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
1898         !isScreenLocked_) {
1899         return;
1900     }
1901 
1902     WLOGFI("ShowWhenLocked window %{public}u re-zorder to up", node->GetWindowId());
1903     ReZOrderShowWhenLockedWindows(true);
1904 }
1905 
RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1906 void WindowNodeContainer::RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1907 {
1908     // if keyguard window show, raise show when locked windows
1909     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1910         ReZOrderShowWhenLockedWindows(true);
1911         return;
1912     }
1913 
1914     // if show when locked window show, raise itself when exist keyguard
1915     if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
1916         !isScreenLocked_) {
1917         return;
1918     }
1919 
1920     WLOGFI("ShowWhenLocked window %{public}u raise itself", node->GetWindowId());
1921     node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
1922     node->parent_ = aboveAppWindowNode_;
1923     if (WindowHelper::IsSplitWindowMode(node->GetWindowMode())) {
1924         node->GetWindowProperty()->ResumeLastWindowMode();
1925         if (node->GetWindowToken() != nullptr) {
1926             node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
1927         }
1928     }
1929 }
1930 
DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1931 void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1932 {
1933     // if keyguard window hide, drop show when locked windows
1934     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1935         ReZOrderShowWhenLockedWindows(false);
1936         AssignZOrder();
1937     }
1938 }
1939 
TraverseWindowTree(const WindowNodeOperationFunc & func,bool isFromTopToBottom) const1940 void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
1941 {
1942     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1943     if (isFromTopToBottom) {
1944         std::reverse(rootNodes.begin(), rootNodes.end());
1945     }
1946 
1947     for (const auto& node : rootNodes) {
1948         if (isFromTopToBottom) {
1949             for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
1950                 if (TraverseFromTopToBottom(*iter, func)) {
1951                     return;
1952                 }
1953             }
1954         } else {
1955             for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
1956                 if (TraverseFromBottomToTop(*iter, func)) {
1957                     return;
1958                 }
1959             }
1960         }
1961     }
1962 }
1963 
TraverseFromTopToBottom(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1964 bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1965 {
1966     if (node == nullptr) {
1967         return false;
1968     }
1969     auto iterBegin = node->children_.rbegin();
1970     for (; iterBegin != node->children_.rend(); ++iterBegin) {
1971         if ((*iterBegin)->priority_ <= 0) {
1972             break;
1973         }
1974         if (func(*iterBegin)) {
1975             return true;
1976         }
1977     }
1978     if (func(node)) {
1979         return true;
1980     }
1981     for (; iterBegin != node->children_.rend(); ++iterBegin) {
1982         if (func(*iterBegin)) {
1983             return true;
1984         }
1985     }
1986     return false;
1987 }
1988 
TraverseFromBottomToTop(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1989 bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1990 {
1991     if (node == nullptr) {
1992         return false;
1993     }
1994     auto iterBegin = node->children_.begin();
1995     for (; iterBegin != node->children_.end(); ++iterBegin) {
1996         if ((*iterBegin)->priority_ >= 0) {
1997             break;
1998         }
1999         if (func(*iterBegin)) {
2000             return true;
2001         }
2002     }
2003     if (func(node)) {
2004         return true;
2005     }
2006     for (; iterBegin != node->children_.end(); ++iterBegin) {
2007         if (func(*iterBegin)) {
2008             return true;
2009         }
2010     }
2011     return false;
2012 }
2013 
GetVirtualPixelRatio(DisplayId displayId) const2014 float WindowNodeContainer::GetVirtualPixelRatio(DisplayId displayId) const
2015 {
2016     return layoutPolicy_->GetVirtualPixelRatio(displayId);
2017 }
2018 
GetDisplayGroupRect() const2019 Rect WindowNodeContainer::GetDisplayGroupRect() const
2020 {
2021     return layoutPolicy_->GetDisplayGroupRect();
2022 }
2023 
SetWindowMode(sptr<WindowNode> & node,WindowMode dstMode)2024 WMError WindowNodeContainer::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
2025 {
2026     if (node == nullptr) {
2027         WLOGFE("could not find window");
2028         return WMError::WM_ERROR_NULLPTR;
2029     }
2030     WindowMode srcMode = node->GetWindowMode();
2031     if (srcMode == dstMode) {
2032         return WMError::WM_OK;
2033     }
2034 
2035     if (WindowHelper::IsSplitWindowMode(dstMode) && isScreenLocked_ &&
2036         (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2037         return WMError::WM_ERROR_INVALID_PARAM;
2038     }
2039 
2040     WMError res = WMError::WM_OK;
2041     if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) {
2042         node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER);
2043     } else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2044         node->SetWindowSizeChangeReason(WindowSizeChangeReason::MAXIMIZE);
2045         if (srcMode == WindowMode::WINDOW_MODE_FLOATING) {
2046             node->SetRequestRect(node->GetWindowRect());
2047         }
2048     } else {
2049         node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
2050     }
2051     node->SetWindowMode(dstMode);
2052     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
2053     if (windowPair == nullptr) {
2054         WLOGFE("Window pair is nullptr");
2055         return WMError::WM_ERROR_NULLPTR;
2056     }
2057     windowPair->UpdateIfSplitRelated(node);
2058     if (WindowHelper::IsMainWindow(node->GetWindowType())) {
2059         if (WindowHelper::IsFloatingWindow(node->GetWindowMode())) {
2060             NotifyDockWindowStateChanged(node, true);
2061         } else {
2062             NotifyDockWindowStateChanged(node, false);
2063         }
2064     }
2065 
2066     if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2067         WindowHelper::IsAppWindow(node->GetWindowType())) {
2068         // minimize other app window
2069         res = MinimizeStructuredAppWindowsExceptSelf(node);
2070         if (res != WMError::WM_OK) {
2071             return res;
2072         }
2073     }
2074     if (node->GetWindowToken() != nullptr) {
2075         node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2076     }
2077     res = UpdateWindowNode(node, WindowUpdateReason::UPDATE_MODE);
2078     if (res != WMError::WM_OK) {
2079         WLOGFE("Set window mode failed, update node failed");
2080         return res;
2081     }
2082     return WMError::WM_OK;
2083 }
2084 
GetModeChangeHotZones(DisplayId displayId,ModeChangeHotZones & hotZones,const ModeChangeHotZonesConfig & config)2085 void WindowNodeContainer::GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones,
2086     const ModeChangeHotZonesConfig& config)
2087 {
2088     const auto& displayRect = displayGroupInfo_->GetDisplayRect(displayId);
2089 
2090     hotZones.fullscreen_.width_ = displayRect.width_;
2091     hotZones.fullscreen_.height_ = config.fullscreenRange_;
2092 
2093     hotZones.primary_.width_ = config.primaryRange_;
2094     hotZones.primary_.height_ = displayRect.height_;
2095 
2096     hotZones.secondary_.posX_ = static_cast<int32_t>(displayRect.width_) - config.secondaryRange_;
2097     hotZones.secondary_.width_ = config.secondaryRange_;
2098     hotZones.secondary_.height_ = displayRect.height_;
2099 }
2100 
GetDisplayVirtualPixelRatio(DisplayId displayId) const2101 float WindowNodeContainer::GetDisplayVirtualPixelRatio(DisplayId displayId) const
2102 {
2103     return displayGroupInfo_->GetDisplayVirtualPixelRatio(displayId);
2104 }
2105 
GetDisplayInfo(DisplayId displayId)2106 sptr<DisplayInfo> WindowNodeContainer::GetDisplayInfo(DisplayId displayId)
2107 {
2108     return displayGroupInfo_->GetDisplayInfo(displayId);
2109 }
2110 
UpdateDisplayInfo(sptr<DisplayInfo> displayInfo)2111 void WindowNodeContainer::UpdateDisplayInfo(sptr<DisplayInfo> displayInfo)
2112 {
2113     displayGroupInfo_->UpdateDisplayInfo(displayInfo);
2114 }
2115 
GetAllDisplayInfo()2116 std::vector<sptr<DisplayInfo>> WindowNodeContainer::GetAllDisplayInfo()
2117 {
2118     return displayGroupInfo_->GetAllDisplayInfo();
2119 }
2120 
UpdateCameraFloatWindowStatus(const sptr<WindowNode> & node,bool isShowing)2121 void WindowNodeContainer::UpdateCameraFloatWindowStatus(const sptr<WindowNode>& node, bool isShowing)
2122 {
2123     if (node->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2124         WindowManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(node->GetAccessTokenId(), isShowing);
2125     }
2126 }
2127 
GetCurrentLayoutMode() const2128 WindowLayoutMode WindowNodeContainer::GetCurrentLayoutMode() const
2129 {
2130     return layoutMode_;
2131 }
2132 
RemoveSingleUserWindowNodes(int accountId)2133 void WindowNodeContainer::RemoveSingleUserWindowNodes(int accountId)
2134 {
2135     std::vector<sptr<WindowNode>> windowNodes;
2136     TraverseContainer(windowNodes);
2137     WLOGFI("%{public}d", accountId);
2138     for (auto& windowNode : windowNodes) {
2139         int windowAccountId = windowNode->GetCallingUid() / UID_TRANSFROM_DIVISOR;
2140         if (windowAccountId < UID_MIN || windowAccountId == accountId) {
2141             WLOGFI("skiped window %{public}s, windowId %{public}d uid %{public}d",
2142                 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2143             continue;
2144         }
2145         WLOGFI("remove window %{public}s, windowId %{public}d uid %{public}d",
2146             windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2147         windowNode->GetWindowProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
2148         if (windowNode->GetWindowToken()) {
2149             if (windowNode->surfaceNode_ != nullptr) {
2150                 windowNode->surfaceNode_->SetVisible(true);
2151             }
2152             windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_HIDDEN);
2153         }
2154     }
2155 }
2156 
TakeWindowPairSnapshot(DisplayId displayId)2157 bool WindowNodeContainer::TakeWindowPairSnapshot(DisplayId displayId)
2158 {
2159     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2160     return windowPair == nullptr ? false : windowPair->TakePairSnapshot();
2161 }
2162 
ClearWindowPairSnapshot(DisplayId displayId)2163 void WindowNodeContainer::ClearWindowPairSnapshot(DisplayId displayId)
2164 {
2165     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2166     if (windowPair == nullptr) {
2167         WLOGFE("Window pair is nullptr");
2168         return;
2169     }
2170     windowPair->ClearPairSnapshot();
2171 }
2172 
IsScreenLocked()2173 bool WindowNodeContainer::IsScreenLocked()
2174 {
2175     return isScreenLocked_;
2176 }
2177 } // namespace Rosen
2178 } // namespace OHOS
2179