• 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     WLOGFD("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     WLOGFD("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             WLOGFD("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     WLOGFD("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             WLOGFD("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             WLOGFD("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     WLOGFD("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     WLOGFD("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             WLOGFD("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 
455     UpdateAvoidAreaListener(node, false);
456     WLOGFD("DestroyWindowNode windowId: %{public}u end", node->GetWindowId());
457     return WMError::WM_OK;
458 }
459 
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowSizeChangeReason reason)460 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowSizeChangeReason reason)
461 {
462     if (!node->GetWindowToken()) {
463         WLOGFE("windowToken is null");
464         return;
465     }
466     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
467         for (auto& childNode : appWindowNode_->children_) {
468             if (childNode->IsSplitMode()) {
469                 layoutPolicy_->UpdateClientRect(childNode->GetWindowRect(), childNode, reason);
470                 childNode->ResetWindowSizeChangeReason();
471                 WLOGFD("Notify split window that the drag action is start or end, windowId: %{public}d, "
472                     "reason: %{public}u", childNode->GetWindowId(), reason);
473             }
474         }
475     } else {
476         layoutPolicy_->UpdateClientRect(node->GetWindowRect(), node, reason);
477         node->ResetWindowSizeChangeReason();
478         WLOGFD("Notify window that the drag action is start or end, windowId: %{public}d, "
479             "reason: %{public}u", node->GetWindowId(), reason);
480     }
481 }
482 
UpdateWindowTree(sptr<WindowNode> & node)483 void WindowNodeContainer::UpdateWindowTree(sptr<WindowNode>& node)
484 {
485     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
486     node->priority_ = zorderPolicy_->GetWindowPriority(node->GetWindowType());
487     RaiseInputMethodWindowPriorityIfNeeded(node);
488     RaiseShowWhenLockedWindowIfNeeded(node);
489     auto parentNode = node->parent_;
490     if (parentNode == nullptr) {
491         WLOGFD("Current window node has no parent: %{public}u", node->GetWindowId());
492         return;
493     }
494     auto iter = std::find(parentNode->children_.begin(), parentNode->children_.end(), node);
495     if (iter != parentNode->children_.end()) {
496         WLOGFD("node %{public}u is already on window tree, no need to update!", node->GetWindowId());
497         return;
498     }
499     auto position = parentNode->children_.end();
500     int splitWindowCnt = 0;
501     for (auto child = parentNode->children_.begin(); child < parentNode->children_.end(); ++child) {
502         if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && splitWindowCnt == SPLIT_WINDOWS_CNT) {
503             position = child;
504             break;
505         }
506         if (WindowHelper::IsSplitWindowMode((*child)->GetWindowMode())) {
507             splitWindowCnt++;
508         }
509         if ((*child)->priority_ > node->priority_) {
510             position = child;
511             break;
512         }
513     }
514     parentNode->children_.insert(position, node);
515 }
516 
AddAppSurfaceNodeOnRSTree(sptr<WindowNode> & node)517 bool WindowNodeContainer::AddAppSurfaceNodeOnRSTree(sptr<WindowNode>& node)
518 {
519     /*
520      * App main window must has starting window, and show after starting window
521      * Starting Window has already update leashWindowSurfaceNode and starting window surfaceNode on RSTree
522      * Just need add appSurface Node as child of leashWindowSurfaceNode
523      */
524     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AddAppSurfaceNodeOnRSTree");
525     if (!WindowHelper::IsMainWindow(node->GetWindowType())) {
526         WLOGFE("id:%{public}u not main app window but has start window", node->GetWindowId());
527         return false;
528     }
529     if (!node->leashWinSurfaceNode_ || !node->surfaceNode_) {
530         WLOGFE("id:%{public}u leashWinSurfaceNode or surfaceNode is null but has start window!", node->GetWindowId());
531         return false;
532     }
533     WLOGFD("AddAppSurfaceNodeOnRSTree windowId: %{public}d", node->GetWindowId());
534     if (!node->currentVisibility_) {
535         WLOGFD("window: %{public}d is invisible, do not need update RS tree", node->GetWindowId());
536         return false;
537     }
538     node->leashWinSurfaceNode_->AddChild(node->surfaceNode_, -1);
539     return true;
540 }
541 
AddNodeOnRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)542 bool WindowNodeContainer::AddNodeOnRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
543     WindowUpdateType type, bool animationPlayed)
544 {
545     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
546     if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
547         node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
548         WLOGFD("not need to update RSTree");
549         return true;
550     }
551     bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
552     WLOGFD("AddNodeOnRSTree windowId: %{public}d, displayId: %{public}" PRIu64", parentDisplayId: %{public}" PRIu64", "
553         "isMultiDisplay: %{public}d, animationPlayed: %{public}d",
554         node->GetWindowId(), displayId, parentDisplayId, isMultiDisplay, animationPlayed);
555     auto updateRSTreeFunc = [&]() {
556         auto& dms = DisplayManagerServiceInner::GetInstance();
557         if (!node->currentVisibility_) {
558             WLOGFD("window: %{public}d is invisible, do not need update RS tree", node->GetWindowId());
559             return;
560         }
561         auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
562         dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, true, isMultiDisplay);
563         for (auto& child : node->children_) {
564             if (child->currentVisibility_) {
565                 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, true, isMultiDisplay);
566             }
567         }
568     };
569 
570     if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
571         updateRSTreeFunc();
572         return true;
573     }
574 
575     if (node->EnableDefaultAnimation(animationPlayed)) {
576         WLOGFD("add window with animation");
577         StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
578         RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
579             animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc);
580         FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
581     } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
582         !animationPlayed) { // add keyboard with animation
583         ProcessInputMethodWindowAddAnimation(node, updateRSTreeFunc);
584     } else {
585         WLOGFD("add window without animation");
586         updateRSTreeFunc();
587     }
588     return true;
589 }
590 
ProcessInputMethodWindowAddAnimation(sptr<WindowNode> & node,std::function<void ()> updateRSTreeFunc)591 void WindowNodeContainer::ProcessInputMethodWindowAddAnimation(sptr<WindowNode>& node,
592     std::function<void()> updateRSTreeFunc)
593 {
594     static sptr<WindowNode> imeNode = nullptr;
595     if (imeNode == node && imeNode != nullptr && imeNode->surfaceNode_ != nullptr) {
596         WLOGFD("imeNode SetAppFreeze(true)");
597         imeNode->surfaceNode_->SetAppFreeze(true);
598     }
599     sptr<WindowNode> launcherNode = nullptr;
600     for (auto& windowNode : belowAppWindowNode_->children_) {
601         if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
602             launcherNode = windowNode;
603             break;
604         }
605     }
606     if (launcherNode != nullptr && launcherNode->surfaceNode_ != nullptr) {
607         WLOGFD("launcherNode SetAppFreeze(true)");
608         launcherNode->surfaceNode_->SetAppFreeze(true);
609     }
610     auto timingProtocol = animationConfig_.keyboardAnimationConfig_.durationIn_;
611     RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationConfig_.curve_, updateRSTreeFunc,
612         [ime = imeNode, node, launcherNode]() {
613         if (ime == node && ime != nullptr && ime->surfaceNode_ != nullptr) {
614             WLOGFD("imeNode SetAppFreeze(false)");
615             ime->surfaceNode_->SetAppFreeze(false);
616         }
617         if (launcherNode != nullptr && launcherNode->surfaceNode_ != nullptr) {
618             WLOGFD("launcherNode SetAppFreeze(false)");
619             launcherNode->surfaceNode_->SetAppFreeze(false);
620         }
621         auto transactionProxy = RSTransactionProxy::GetInstance();
622         if (transactionProxy != nullptr) {
623             transactionProxy->FlushImplicitTransaction();
624         }
625     });
626     imeNode = node;
627 }
628 
RemoveNodeFromRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)629 bool WindowNodeContainer::RemoveNodeFromRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
630     WindowUpdateType type, bool animationPlayed)
631 {
632     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
633     if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
634         node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
635         WLOGFD("not need to update RSTree");
636         return true;
637     }
638     bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
639     WLOGFD("RemoveNodeFromRSTree  windowId: %{public}d, displayId: %{public}" PRIu64", isMultiDisplay: %{public}d, "
640         "parentDisplayId: %{public}" PRIu64", animationPlayed: %{public}d",
641         node->GetWindowId(), displayId, isMultiDisplay, parentDisplayId, animationPlayed);
642     auto updateRSTreeFunc = [&]() {
643         auto& dms = DisplayManagerServiceInner::GetInstance();
644         auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
645         dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, false, isMultiDisplay);
646         for (auto& child : node->children_) {
647             if (child->currentVisibility_) {
648                 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, false, isMultiDisplay);
649             }
650         }
651     };
652 
653     if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
654         updateRSTreeFunc();
655         return true;
656     }
657 
658     if (node->EnableDefaultAnimation(animationPlayed)) {
659         WLOGFD("remove window with animation");
660         StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
661         if (node->surfaceNode_) {
662             node->surfaceNode_->SetAppFreeze(true);
663         }
664 	wptr<WindowNode> weakNode(node);
665         RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
666             animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc, [weakNode]() {
667 	    auto weakWindow = weakNode.promote();
668             if (weakWindow && weakWindow->surfaceNode_) {
669                 weakWindow->surfaceNode_->SetAppFreeze(false);
670             }
671         });
672         FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
673     } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
674         !animationPlayed) { // remove keyboard with animation
675         auto timingProtocol = animationConfig_.keyboardAnimationConfig_.durationOut_;
676         RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationConfig_.curve_, updateRSTreeFunc);
677     } else {
678         WLOGFD("remove window without animation");
679         updateRSTreeFunc();
680     }
681     return true;
682 }
683 
Destroy()684 const std::vector<uint32_t>& WindowNodeContainer::Destroy()
685 {
686     // clear vector cache completely, swap with empty vector
687     auto emptyVector = std::vector<uint32_t>();
688     removedIds_.swap(emptyVector);
689     for (auto& node : belowAppWindowNode_->children_) {
690         DestroyWindowNode(node, removedIds_);
691     }
692     for (auto& node : appWindowNode_->children_) {
693         DestroyWindowNode(node, removedIds_);
694     }
695     for (auto& node : aboveAppWindowNode_->children_) {
696         DestroyWindowNode(node, removedIds_);
697     }
698     return removedIds_;
699 }
700 
FindRoot(WindowType type) const701 sptr<WindowNode> WindowNodeContainer::FindRoot(WindowType type) const
702 {
703     if (WindowHelper::IsAppWindow(type) || type == WindowType::WINDOW_TYPE_DOCK_SLICE ||
704         type == WindowType::WINDOW_TYPE_APP_COMPONENT || type == WindowType::WINDOW_TYPE_PLACEHOLDER ||
705         type == WindowType::WINDOW_TYPE_DIALOG) {
706         return appWindowNode_;
707     }
708     if (WindowHelper::IsBelowSystemWindow(type)) {
709         return belowAppWindowNode_;
710     }
711     if (WindowHelper::IsAboveSystemWindow(type)) {
712         return aboveAppWindowNode_;
713     }
714     return nullptr;
715 }
716 
FindWindowNodeById(uint32_t id) const717 sptr<WindowNode> WindowNodeContainer::FindWindowNodeById(uint32_t id) const
718 {
719     std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
720     for (const auto& rootNode : rootNodes) {
721         for (auto& node : rootNode->children_) {
722             if (node->GetWindowId() == id) {
723                 return node;
724             }
725             for (auto& subNode : node->children_) {
726                 if (subNode->GetWindowId() == id) {
727                     return subNode;
728                 }
729             }
730         }
731     }
732     return nullptr;
733 }
734 
UpdateFocusStatus(uint32_t id,bool focused)735 void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused)
736 {
737     auto node = FindWindowNodeById(id);
738     if (node == nullptr) {
739         WLOGFW("cannot find focused window id:%{public}d", id);
740         return;
741     }
742     if (focused) {
743         focusedPid_ = node->GetCallingPid();
744     }
745 
746     if (node->GetCallingPid() == 0) {
747         WLOGFW("focused window is starting window, no need notify");
748         return;
749     }
750 
751     if (focused && node->GetWindowProperty() != nullptr) {
752         AbilityInfo info = node->GetWindowProperty()->GetAbilityInfo();
753         WLOGFW("current focus window: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
754             " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", id,
755             node->GetWindowProperty()->GetWindowName().c_str(), info.bundleName_.c_str(), info.abilityName_.c_str(),
756             node->GetCallingPid(), node->GetCallingUid());
757         FocusAppInfo appInfo = { node->GetCallingPid(), node->GetCallingUid(), info.bundleName_, info.abilityName_ };
758         RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
759     }
760     if (node->GetWindowToken()) {
761         node->GetWindowToken()->UpdateFocusStatus(focused);
762     }
763     if (node->abilityToken_ == nullptr) {
764         WLOGFD("abilityToken is null, window : %{public}d", id);
765     }
766     sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(node->GetWindowId(), node->GetDisplayId(),
767         node->GetCallingPid(), node->GetCallingUid(), node->GetWindowType(), node->abilityToken_);
768     WindowManagerAgentController::GetInstance().UpdateFocusChangeInfo(
769         focusChangeInfo, focused);
770 }
771 
UpdateActiveStatus(uint32_t id,bool isActive)772 void WindowNodeContainer::UpdateActiveStatus(uint32_t id, bool isActive)
773 {
774     auto node = FindWindowNodeById(id);
775     if (node == nullptr) {
776         WLOGFE("cannot find active window id: %{public}d", id);
777         return;
778     }
779     if (isActive) {
780         activePid_ = node->GetCallingPid();
781     }
782     if (node->GetWindowToken()) {
783         node->GetWindowToken()->UpdateActiveStatus(isActive);
784     }
785 }
786 
UpdateBrightness(uint32_t id,bool byRemoved)787 void WindowNodeContainer::UpdateBrightness(uint32_t id, bool byRemoved)
788 {
789     auto node = FindWindowNodeById(id);
790     if (node == nullptr) {
791         WLOGFE("cannot find active window id: %{public}d", id);
792         return;
793     }
794 
795     if (!byRemoved) {
796         if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
797             return;
798         }
799     }
800     WLOGFD("brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), node->GetBrightness());
801     if (std::fabs(node->GetBrightness() - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
802         if (GetDisplayBrightness() != node->GetBrightness()) {
803             WLOGFD("adjust brightness with default value");
804             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
805             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
806         }
807         SetBrightnessWindow(INVALID_WINDOW_ID);
808     } else {
809         if (GetDisplayBrightness() != node->GetBrightness()) {
810             WLOGFD("adjust brightness with value: %{public}u", ToOverrideBrightness(node->GetBrightness()));
811             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
812                 ToOverrideBrightness(node->GetBrightness()));
813             SetDisplayBrightness(node->GetBrightness());
814         }
815         SetBrightnessWindow(node->GetWindowId());
816     }
817 }
818 
AssignZOrder()819 void WindowNodeContainer::AssignZOrder()
820 {
821     zOrder_ = 0;
822     WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
823         if (!node->leashWinSurfaceNode_ && !node->surfaceNode_ && !node->startingWinSurfaceNode_) {
824             ++zOrder_;
825             WLOGFE("Id: %{public}u has no surface nodes", node->GetWindowId());
826             return false;
827         }
828         if (node->leashWinSurfaceNode_ != nullptr) {
829             ++zOrder_;
830             node->leashWinSurfaceNode_->SetPositionZ(zOrder_);
831         }
832 
833         if (node->surfaceNode_ != nullptr) {
834             ++zOrder_;
835             node->surfaceNode_->SetPositionZ(zOrder_);
836             node->zOrder_ = zOrder_;
837         }
838         // make sure starting window above app
839         if (node->startingWinSurfaceNode_ != nullptr) {
840             ++zOrder_;
841             node->startingWinSurfaceNode_->SetPositionZ(zOrder_);
842         }
843         return false;
844     };
845     TraverseWindowTree(func, false);
846     displayGroupController_->UpdateDisplayGroupWindowTree();
847 }
848 
SetFocusWindow(uint32_t windowId)849 WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
850 {
851     if (focusedWindow_ == windowId) {
852         WLOGFD("focused window no change, id: %{public}u, %{public}d", windowId, focusedPid_);
853         // StartingWindow can be focused and this pid is 0, then notify info in UpdateFocusStatus.
854         // This info is invalid, so we must notify again when first frame callback.
855         if (focusedPid_ == 0) {
856             UpdateFocusStatus(windowId, true);
857         }
858         return WMError::WM_DO_NOTHING;
859     }
860     UpdateFocusStatus(focusedWindow_, false);
861     focusedWindow_ = windowId;
862     UpdateFocusStatus(focusedWindow_, true);
863     return WMError::WM_OK;
864 }
865 
GetFocusWindow() const866 uint32_t WindowNodeContainer::GetFocusWindow() const
867 {
868     return focusedWindow_;
869 }
870 
SetActiveWindow(uint32_t windowId,bool byRemoved)871 WMError WindowNodeContainer::SetActiveWindow(uint32_t windowId, bool byRemoved)
872 {
873     if (activeWindow_ == windowId) {
874         WLOGFD("active window not change, id: %{public}u, %{public}d", windowId, activePid_);
875         if (activePid_ == 0) {
876             UpdateActiveStatus(windowId, true);
877         }
878         return WMError::WM_DO_NOTHING;
879     }
880     UpdateActiveStatus(activeWindow_, false);
881     activeWindow_ = windowId;
882     UpdateActiveStatus(activeWindow_, true);
883     UpdateBrightness(activeWindow_, byRemoved);
884     return WMError::WM_OK;
885 }
886 
SetDisplayBrightness(float brightness)887 void WindowNodeContainer::SetDisplayBrightness(float brightness)
888 {
889     displayBrightness_ = brightness;
890 }
891 
GetDisplayBrightness() const892 float WindowNodeContainer::GetDisplayBrightness() const
893 {
894     return displayBrightness_;
895 }
896 
SetBrightnessWindow(uint32_t windowId)897 void WindowNodeContainer::SetBrightnessWindow(uint32_t windowId)
898 {
899     brightnessWindow_ = windowId;
900 }
901 
GetBrightnessWindow() const902 uint32_t WindowNodeContainer::GetBrightnessWindow() const
903 {
904     return brightnessWindow_;
905 }
906 
ToOverrideBrightness(float brightness)907 uint32_t WindowNodeContainer::ToOverrideBrightness(float brightness)
908 {
909     return static_cast<uint32_t>(brightness * MAX_BRIGHTNESS);
910 }
911 
GetActiveWindow() const912 uint32_t WindowNodeContainer::GetActiveWindow() const
913 {
914     return activeWindow_;
915 }
916 
GetLayoutPolicy() const917 sptr<WindowLayoutPolicy> WindowNodeContainer::GetLayoutPolicy() const
918 {
919     return layoutPolicy_;
920 }
921 
GetAvoidController() const922 sptr<AvoidAreaController> WindowNodeContainer::GetAvoidController() const
923 {
924     return avoidController_;
925 }
926 
GetMultiDisplayController() const927 sptr<DisplayGroupController> WindowNodeContainer::GetMultiDisplayController() const
928 {
929     return displayGroupController_;
930 }
931 
GetRootNode(WindowRootNodeType type) const932 sptr<WindowNode> WindowNodeContainer::GetRootNode(WindowRootNodeType type) const
933 {
934     if (type == WindowRootNodeType::ABOVE_WINDOW_NODE) {
935         return aboveAppWindowNode_;
936     } else if (type == WindowRootNodeType::APP_WINDOW_NODE) {
937         return appWindowNode_;
938     } else if (type == WindowRootNodeType::BELOW_WINDOW_NODE) {
939         return belowAppWindowNode_;
940     }
941     return nullptr;
942 }
943 
HandleKeepScreenOn(const sptr<WindowNode> & node,bool requireLock)944 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)
945 {
946     if (requireLock && node->keepScreenLock_ == nullptr) {
947         // reset ipc identity
948         std::string identity = IPCSkeleton::ResetCallingIdentity();
949         node->keepScreenLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(node->GetWindowName(),
950             PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
951         // set ipc identity to raw
952         IPCSkeleton::SetCallingIdentity(identity);
953     }
954     if (node->keepScreenLock_ == nullptr) {
955         return;
956     }
957     WLOGFD("handle keep screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), requireLock);
958     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "container:HandleKeepScreenOn(%s, %d)",
959         node->GetWindowName().c_str(), requireLock);
960     ErrCode res;
961     // reset ipc identity
962     std::string identity = IPCSkeleton::ResetCallingIdentity();
963     if (requireLock) {
964         res = node->keepScreenLock_->Lock();
965     } else {
966         res = node->keepScreenLock_->UnLock();
967     }
968     // set ipc identity to raw
969     IPCSkeleton::SetCallingIdentity(identity);
970     if (res != ERR_OK) {
971         WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]", requireLock, res);
972     }
973 }
974 
IsAboveSystemBarNode(sptr<WindowNode> node) const975 bool WindowNodeContainer::IsAboveSystemBarNode(sptr<WindowNode> node) const
976 {
977     int32_t curPriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
978     if ((curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_STATUS_BAR)) &&
979         (curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_NAVIGATION_BAR))) {
980         return true;
981     }
982     return false;
983 }
984 
IsSplitImmersiveNode(sptr<WindowNode> node) const985 bool WindowNodeContainer::IsSplitImmersiveNode(sptr<WindowNode> node) const
986 {
987     auto type = node->GetWindowType();
988     return node->IsSplitMode() || type == WindowType::WINDOW_TYPE_DOCK_SLICE;
989 }
990 
GetExpectImmersiveProperty() const991 std::unordered_map<WindowType, SystemBarProperty> WindowNodeContainer::GetExpectImmersiveProperty() const
992 {
993     std::unordered_map<WindowType, SystemBarProperty> sysBarPropMap {
994         { WindowType::WINDOW_TYPE_STATUS_BAR,     SystemBarProperty() },
995         { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() },
996     };
997 
998     std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
999     for (const auto& node : rootNodes) {
1000         for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); ++iter) {
1001             auto& sysBarPropMapNode = (*iter)->GetSystemBarProperty();
1002             if (IsAboveSystemBarNode(*iter)) {
1003                 continue;
1004             }
1005             if (WindowHelper::IsFullScreenWindow((*iter)->GetWindowMode())
1006 	        && (*iter)->GetWindowType() != WindowType::WINDOW_TYPE_PANEL) {
1007                 WLOGFD("Top immersive window id: %{public}d. Use full immersive prop", (*iter)->GetWindowId());
1008                 for (auto it : sysBarPropMap) {
1009                     sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1010                 }
1011                 return sysBarPropMap;
1012             } else if (IsSplitImmersiveNode(*iter)) {
1013                 WLOGFD("Top split window id: %{public}d. Use split immersive prop", (*iter)->GetWindowId());
1014                 for (auto it : sysBarPropMap) {
1015                     sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1016                     sysBarPropMap[it.first].enable_ = false;
1017                 }
1018                 return sysBarPropMap;
1019             }
1020         }
1021     }
1022 
1023     WLOGFD("No immersive window on top. Use default systembar Property");
1024     return sysBarPropMap;
1025 }
1026 
NotifyIfAvoidAreaChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1027 void WindowNodeContainer::NotifyIfAvoidAreaChanged(const sptr<WindowNode>& node,
1028     const AvoidControlType avoidType) const
1029 {
1030     auto checkFunc = [this](sptr<WindowNode> node) {
1031         return CheckWindowNodeWhetherInWindowTree(node);
1032     };
1033     avoidController_->ProcessWindowChange(node, avoidType, checkFunc);
1034     if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
1035         NotifyIfSystemBarRegionChanged(node->GetDisplayId());
1036     } else {
1037         NotifyIfSystemBarTintChanged(node->GetDisplayId());
1038     }
1039 
1040     NotifyIfKeyboardRegionChanged(node, avoidType);
1041 }
1042 
BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const1043 void WindowNodeContainer::BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const
1044 {
1045     avoidController_->SetFlagForProcessWindowChange(true);
1046 }
1047 
ProcessWindowAvoidAreaChangeWhenDisplayChange() const1048 void WindowNodeContainer::ProcessWindowAvoidAreaChangeWhenDisplayChange() const
1049 {
1050     avoidController_->SetFlagForProcessWindowChange(false);
1051     auto checkFunc = [this](sptr<WindowNode> node) {
1052         return CheckWindowNodeWhetherInWindowTree(node);
1053     };
1054     WindowNodeOperationFunc func = [avoidController = avoidController_, &checkFunc](sptr<WindowNode> node) {
1055         avoidController->ProcessWindowChange(node, AvoidControlType::AVOID_NODE_UPDATE, checkFunc);
1056         return false;
1057     };
1058     TraverseWindowTree(func, true);
1059 }
1060 
NotifyIfSystemBarTintChanged(DisplayId displayId) const1061 void WindowNodeContainer::NotifyIfSystemBarTintChanged(DisplayId displayId) const
1062 {
1063     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1064     auto expectSystemBarProp = GetExpectImmersiveProperty();
1065     SystemBarRegionTints tints;
1066     SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1067     for (auto it : sysBarTintMap) {
1068         auto expectProp = expectSystemBarProp.find(it.first)->second;
1069         if (it.second.prop_ == expectProp) {
1070             continue;
1071         }
1072         WLOGFD("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x",
1073             static_cast<int32_t>(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_);
1074         sysBarTintMap[it.first].prop_ = expectProp;
1075         sysBarTintMap[it.first].type_ = it.first;
1076         tints.emplace_back(sysBarTintMap[it.first]);
1077     }
1078     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1079 }
1080 
NotifyIfSystemBarRegionChanged(DisplayId displayId) const1081 void WindowNodeContainer::NotifyIfSystemBarRegionChanged(DisplayId displayId) const
1082 {
1083     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1084     SystemBarRegionTints tints;
1085     SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1086     SysBarNodeMap& sysBarNodeMap = displayGroupController_->sysBarNodeMaps_[displayId];
1087     for (auto it : sysBarTintMap) { // split screen mode not support yet
1088         auto sysNode = sysBarNodeMap[it.first];
1089         if (sysNode == nullptr || it.second.region_ == sysNode->GetWindowRect()) {
1090             continue;
1091         }
1092         const Rect& newRegion = sysNode->GetWindowRect();
1093         sysBarTintMap[it.first].region_ = newRegion;
1094         sysBarTintMap[it.first].type_ = it.first;
1095         tints.emplace_back(sysBarTintMap[it.first]);
1096         WLOGFD("system bar region update, type: %{public}d" \
1097             "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
1098             static_cast<int32_t>(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_);
1099     }
1100     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1101 }
1102 
NotifyIfKeyboardRegionChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1103 void WindowNodeContainer::NotifyIfKeyboardRegionChanged(const sptr<WindowNode>& node,
1104     const AvoidControlType avoidType) const
1105 {
1106     if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1107         WLOGFD("windowType: %{public}u", node->GetWindowType());
1108         return;
1109     }
1110 
1111     auto callingWindow = FindWindowNodeById(node->GetCallingWindow());
1112     if (callingWindow == nullptr) {
1113         WLOGFD("callingWindow: %{public}u does not be set", node->GetCallingWindow());
1114         callingWindow = FindWindowNodeById(GetFocusWindow());
1115     }
1116     if (callingWindow == nullptr || callingWindow->GetWindowToken() == nullptr) {
1117         WLOGFE("does not have correct callingWindow for input method window");
1118         return;
1119     }
1120     const WindowMode callingWindowMode = callingWindow->GetWindowMode();
1121     if (callingWindowMode == WindowMode::WINDOW_MODE_FULLSCREEN ||
1122         callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1123         callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
1124         const Rect keyRect = node->GetWindowRect();
1125         const Rect callingRect = callingWindow->GetWindowRect();
1126         if (WindowHelper::IsEmptyRect(WindowHelper::GetOverlap(callingRect, keyRect, 0, 0))) {
1127             WLOGFD("no overlap between two windows");
1128             return;
1129         }
1130         Rect overlapRect = { 0, 0, 0, 0 };
1131         if (avoidType == AvoidControlType::AVOID_NODE_ADD || avoidType == AvoidControlType::AVOID_NODE_UPDATE) {
1132             overlapRect = WindowHelper::GetOverlap(keyRect, callingRect, callingRect.posX_, callingRect.posY_);
1133         }
1134 
1135         WLOGFD("keyboard size change callingWindow: [%{public}s, %{public}u], " \
1136         "overlap rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
1137             callingWindow->GetWindowName().c_str(), callingWindow->GetWindowId(),
1138             overlapRect.posX_, overlapRect.posY_, overlapRect.width_, overlapRect.height_);
1139         sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT, overlapRect);
1140         callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info);
1141         return;
1142     }
1143     WLOGFE("does not have correct callingWindowMode for input method window");
1144 }
1145 
NotifySystemBarTints(std::vector<DisplayId> displayIdVec)1146 void WindowNodeContainer::NotifySystemBarTints(std::vector<DisplayId> displayIdVec)
1147 {
1148     if (displayIdVec.size() != displayGroupController_->sysBarTintMaps_.size()) {
1149         WLOGE("[Immersive] the number of display is error");
1150     }
1151 
1152     for (auto displayId : displayIdVec) {
1153         SystemBarRegionTints tints;
1154         SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1155         for (auto it : sysBarTintMap) {
1156             WLOGFD("[Immersive] system bar cur notify, T: %{public}d, " \
1157                 "V: %{public}d, C: %{public}x | %{public}x, " \
1158                 "R: [%{public}d, %{public}d, %{public}d, %{public}d]",
1159                 static_cast<int32_t>(it.first),
1160                 sysBarTintMap[it.first].prop_.enable_,
1161                 sysBarTintMap[it.first].prop_.backgroundColor_, sysBarTintMap[it.first].prop_.contentColor_,
1162                 sysBarTintMap[it.first].region_.posX_, sysBarTintMap[it.first].region_.posY_,
1163                 sysBarTintMap[it.first].region_.width_, sysBarTintMap[it.first].region_.height_);
1164             tints.push_back(sysBarTintMap[it.first]);
1165         }
1166         WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1167     }
1168 }
1169 
NotifyDockWindowStateChanged(sptr<WindowNode> & node,bool isEnable)1170 void WindowNodeContainer::NotifyDockWindowStateChanged(sptr<WindowNode>& node, bool isEnable)
1171 {
1172     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1173     WLOGFD("[Immersive] begin isEnable: %{public}d", isEnable);
1174     if (isEnable) {
1175         for (auto& windowNode : appWindowNode_->children_) {
1176             if (windowNode->GetWindowId() == node->GetWindowId()) {
1177                 continue;
1178             }
1179             if (!WindowHelper::IsFloatingWindow(windowNode->GetWindowMode())) {
1180                 return;
1181             }
1182         }
1183     }
1184     SystemBarProperty prop;
1185     prop.enable_ = isEnable;
1186     SystemBarRegionTint tint;
1187     tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1188     tint.prop_ = prop;
1189     SystemBarRegionTints tints;
1190     tints.push_back(tint);
1191     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(node->GetDisplayId(), tints);
1192 }
1193 
UpdateAvoidAreaListener(sptr<WindowNode> & windowNode,bool haveAvoidAreaListener)1194 void WindowNodeContainer::UpdateAvoidAreaListener(sptr<WindowNode>& windowNode, bool haveAvoidAreaListener)
1195 {
1196     avoidController_->UpdateAvoidAreaListener(windowNode, haveAvoidAreaListener);
1197 }
1198 
IsTopWindow(uint32_t windowId,sptr<WindowNode> & rootNode) const1199 bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const
1200 {
1201     if (rootNode->children_.empty()) {
1202         WLOGFE("root does not have any node");
1203         return false;
1204     }
1205     auto node = *(rootNode->children_.rbegin());
1206     if (node == nullptr) {
1207         WLOGFE("window tree does not have any node");
1208         return false;
1209     }
1210 
1211     for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); iter++) {
1212         if ((*iter)->priority_ > 0) {
1213             return (*iter)->GetWindowId() == windowId;
1214         } else {
1215             break;
1216         }
1217     }
1218     return node->GetWindowId() == windowId;
1219 }
1220 
RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>> & orderedNodes,std::vector<sptr<WindowNode>> & windowNodes)1221 void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes,
1222     std::vector<sptr<WindowNode>>& windowNodes)
1223 {
1224     for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
1225         uint32_t wid = (*iter)->GetWindowId();
1226         auto orderedIter = std::find_if(orderedNodes.begin(), orderedNodes.end(),
1227             [wid] (sptr<WindowNode> orderedNode) { return orderedNode->GetWindowId() == wid; });
1228         if (orderedIter != orderedNodes.end()) {
1229             iter = windowNodes.erase(iter);
1230         } else {
1231             iter++;
1232         }
1233     }
1234     for (auto iter = orderedNodes.begin(); iter != orderedNodes.end(); iter++) {
1235         UpdateWindowTree(*iter);
1236     }
1237     return;
1238 }
1239 
RaiseWindowToTop(uint32_t windowId,std::vector<sptr<WindowNode>> & windowNodes)1240 void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)
1241 {
1242     if (windowNodes.empty()) {
1243         WLOGFE("windowNodes is empty!");
1244         return;
1245     }
1246     auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
1247                              [windowId](sptr<WindowNode> node) {
1248                                  return node->GetWindowId() == windowId;
1249                              });
1250     // raise app node window to top
1251     if (iter != windowNodes.end()) {
1252         sptr<WindowNode> node = *iter;
1253         windowNodes.erase(iter);
1254         UpdateWindowTree(node);
1255         WLOGFD("raise window to top %{public}u", node->GetWindowId());
1256     }
1257 }
1258 
TraverseContainer(std::vector<sptr<WindowNode>> & windowNodes) const1259 void WindowNodeContainer::TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const
1260 {
1261     for (auto& node : belowAppWindowNode_->children_) {
1262         TraverseWindowNode(node, windowNodes);
1263     }
1264     for (auto& node : appWindowNode_->children_) {
1265         TraverseWindowNode(node, windowNodes);
1266     }
1267     for (auto& node : aboveAppWindowNode_->children_) {
1268         TraverseWindowNode(node, windowNodes);
1269     }
1270     std::reverse(windowNodes.begin(), windowNodes.end());
1271 }
1272 
TraverseWindowNode(sptr<WindowNode> & node,std::vector<sptr<WindowNode>> & windowNodes) const1273 void WindowNodeContainer::TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const
1274 {
1275     if (node == nullptr) {
1276         return;
1277     }
1278     auto iter = node->children_.begin();
1279     for (; iter < node->children_.end(); ++iter) {
1280         if ((*iter)->priority_ < 0) {
1281             windowNodes.emplace_back(*iter);
1282         } else {
1283             break;
1284         }
1285     }
1286     windowNodes.emplace_back(node);
1287     for (; iter < node->children_.end(); ++iter) {
1288         windowNodes.emplace_back(*iter);
1289     }
1290 }
1291 
GetAvoidAreaByType(const sptr<WindowNode> & node,AvoidAreaType avoidAreaType) const1292 AvoidArea WindowNodeContainer::GetAvoidAreaByType(const sptr<WindowNode>& node, AvoidAreaType avoidAreaType) const
1293 {
1294     if (CheckWindowNodeWhetherInWindowTree(node)) {
1295         return avoidController_->GetAvoidAreaByType(node, avoidAreaType);
1296     }
1297     return {};
1298 }
1299 
CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode> & node) const1300 bool WindowNodeContainer::CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode>& node) const
1301 {
1302     bool isInWindowTree = false;
1303     WindowNodeOperationFunc func = [&node, &isInWindowTree](sptr<WindowNode> windowNode) {
1304         if (node->GetWindowId() == windowNode->GetWindowId()) {
1305             isInWindowTree = true;
1306             return true;
1307         }
1308         return false;
1309     };
1310     TraverseWindowTree(func, true);
1311     return isInWindowTree;
1312 }
1313 
DumpScreenWindowTree()1314 void WindowNodeContainer::DumpScreenWindowTree()
1315 {
1316     WLOGFD("-------- dump window info begin---------");
1317     WLOGFD("WindowName DisplayId WinId Type Mode Flag ZOrd Orientation abilityToken [   x    y    w    h]");
1318     uint32_t zOrder = zOrder_;
1319     WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
1320         Rect rect = node->GetWindowRect();
1321         const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1322             node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1323         WLOGFD("DumpScreenWindowTree: %{public}10s %{public}9" PRIu64" %{public}5u %{public}4u %{public}4u %{public}4u "
1324             "%{public}4u %{public}11u %{public}12d [%{public}4d %{public}4d %{public}4u %{public}4u]",
1325             windowName.c_str(), node->GetDisplayId(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1326             node->GetWindowFlags(), --zOrder, static_cast<uint32_t>(node->GetRequestedOrientation()),
1327             node->abilityToken_ != nullptr, rect.posX_, rect.posY_, rect.width_, rect.height_);
1328         return false;
1329     };
1330     TraverseWindowTree(func, true);
1331     WLOGFD("-------- dump window info end  ---------");
1332 }
1333 
GetDisplayRect(DisplayId displayId) const1334 Rect WindowNodeContainer::GetDisplayRect(DisplayId displayId) const
1335 {
1336     return displayGroupInfo_->GetDisplayRect(displayId);
1337 }
1338 
IsVerticalDisplay(DisplayId displayId) const1339 bool WindowNodeContainer::IsVerticalDisplay(DisplayId displayId) const
1340 {
1341     return displayGroupInfo_->GetDisplayRect(displayId).width_ < displayGroupInfo_->GetDisplayRect(displayId).height_;
1342 }
1343 
ProcessWindowStateChange(WindowState state,WindowStateChangeReason reason)1344 void WindowNodeContainer::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)
1345 {
1346     switch (reason) {
1347         case WindowStateChangeReason::KEYGUARD: {
1348             int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
1349             TraverseAndUpdateWindowState(state, topPriority);
1350             break;
1351         }
1352         default:
1353             return;
1354     }
1355 }
1356 
TraverseAndUpdateWindowState(WindowState state,int32_t topPriority)1357 void WindowNodeContainer::TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)
1358 {
1359     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1360     for (auto& node : rootNodes) {
1361         UpdateWindowState(node, topPriority, state);
1362     }
1363 }
1364 
UpdateWindowState(sptr<WindowNode> node,int32_t topPriority,WindowState state)1365 void WindowNodeContainer::UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)
1366 {
1367     if (node == nullptr) {
1368         return;
1369     }
1370     if (node->parent_ != nullptr && node->currentVisibility_) {
1371         if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
1372             !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
1373             if (node->GetWindowToken()) {
1374                 node->GetWindowToken()->UpdateWindowState(state);
1375             }
1376             HandleKeepScreenOn(node, state);
1377         }
1378     }
1379     for (auto& childNode : node->children_) {
1380         UpdateWindowState(childNode, topPriority, state);
1381     }
1382 }
1383 
HandleKeepScreenOn(const sptr<WindowNode> & node,WindowState state)1384 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)
1385 {
1386     if (node == nullptr) {
1387         WLOGFE("window is invalid");
1388         return;
1389     }
1390     if (state == WindowState::STATE_FROZEN) {
1391         HandleKeepScreenOn(node, false);
1392     } else if (state == WindowState::STATE_UNFROZEN) {
1393         HandleKeepScreenOn(node, node->IsKeepScreenOn());
1394     } else {
1395         // do nothing
1396     }
1397 }
1398 
FindDividerNode() const1399 sptr<WindowNode> WindowNodeContainer::FindDividerNode() const
1400 {
1401     for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) {
1402         if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1403             return *iter;
1404         }
1405     }
1406     return nullptr;
1407 }
1408 
RaiseSplitRelatedWindowToTop(sptr<WindowNode> & node)1409 void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
1410 {
1411     if (node == nullptr) {
1412         return;
1413     }
1414     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
1415     if (windowPair == nullptr) {
1416         WLOGFE("Window pair is nullptr");
1417         return;
1418     }
1419     std::vector<sptr<WindowNode>> orderedPair = windowPair->GetOrderedPair(node);
1420     RaiseOrderedWindowToTop(orderedPair, appWindowNode_->children_);
1421     AssignZOrder();
1422     return;
1423 }
1424 
RaiseZOrderForAppWindow(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)1425 WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
1426 {
1427     if (node == nullptr) {
1428         return WMError::WM_ERROR_NULLPTR;
1429     }
1430     if (IsTopWindow(node->GetWindowId(), appWindowNode_) || IsTopWindow(node->GetWindowId(), aboveAppWindowNode_)) {
1431         WLOGFD("it is already top app window, id: %{public}u", node->GetWindowId());
1432         return WMError::WM_ERROR_INVALID_TYPE;
1433     }
1434 
1435     if (WindowHelper::IsSubWindow(node->GetWindowType()) ||
1436         (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1437         if (parentNode == nullptr) {
1438             WLOGFE("window type is invalid");
1439             return WMError::WM_ERROR_NULLPTR;
1440         }
1441         RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself
1442         if (parentNode->IsSplitMode()) {
1443             RaiseSplitRelatedWindowToTop(parentNode);
1444         } else if (parentNode->parent_ != nullptr) {
1445             RaiseWindowToTop(parentNode->GetWindowId(), parentNode->parent_->children_); // raise parent window
1446         }
1447     } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
1448         if (node->IsSplitMode()) {
1449             RaiseSplitRelatedWindowToTop(node);
1450         } else {
1451             // remote animation continuous start and exit allow parent is nullptr
1452             if (node->parent_ == nullptr) {
1453                 WLOGFW("node parent is nullptr");
1454                 return WMError::WM_OK;
1455             }
1456             RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
1457         }
1458     } else {
1459         // do nothing
1460     }
1461     AssignZOrder();
1462     WLOGFD("RaiseZOrderForAppWindow finished");
1463     DumpScreenWindowTree();
1464     return WMError::WM_OK;
1465 }
1466 
GetNextFocusableWindow(uint32_t windowId) const1467 sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
1468 {
1469     sptr<WindowNode> nextFocusableWindow;
1470     bool previousFocusedWindowFound = false;
1471     WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
1472         sptr<WindowNode> node) {
1473         if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable() && node->currentVisibility_) {
1474             nextFocusableWindow = node;
1475             return true;
1476         }
1477         if (node->GetWindowId() == windowId) {
1478             previousFocusedWindowFound = true;
1479         }
1480         return false;
1481     };
1482     TraverseWindowTree(func, true);
1483     return nextFocusableWindow;
1484 }
1485 
GetNextRotatableWindow(uint32_t windowId) const1486 sptr<WindowNode> WindowNodeContainer::GetNextRotatableWindow(uint32_t windowId) const
1487 {
1488     sptr<WindowNode> nextRotatableWindow;
1489     WindowNodeOperationFunc func = [windowId, &nextRotatableWindow](
1490         sptr<WindowNode> node) {
1491         if (windowId != node->GetWindowId() &&
1492             WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
1493             nextRotatableWindow = node;
1494             return true;
1495         }
1496         return false;
1497     };
1498     TraverseWindowTree(func, true);
1499     return nextRotatableWindow;
1500 }
1501 
GetNextActiveWindow(uint32_t windowId) const1502 sptr<WindowNode> WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) const
1503 {
1504     auto currentNode = FindWindowNodeById(windowId);
1505     if (currentNode == nullptr) {
1506         WLOGFE("cannot find window id: %{public}u by tree", windowId);
1507         return nullptr;
1508     }
1509     WLOGFD("current window: [%{public}u, %{public}u]", windowId, static_cast<uint32_t>(currentNode->GetWindowType()));
1510     if (WindowHelper::IsSystemWindow(currentNode->GetWindowType())) {
1511         for (auto& node : appWindowNode_->children_) {
1512             if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1513                 continue;
1514             }
1515             return node;
1516         }
1517         for (auto& node : belowAppWindowNode_->children_) {
1518             if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1519                 return node;
1520             }
1521         }
1522     } else if (WindowHelper::IsAppWindow(currentNode->GetWindowType())) {
1523         std::vector<sptr<WindowNode>> windowNodes;
1524         TraverseContainer(windowNodes);
1525         auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), [windowId](sptr<WindowNode>& node) {
1526             return node->GetWindowId() == windowId;
1527             });
1528         if (iter == windowNodes.end()) {
1529             WLOGFE("could not find this window");
1530             return nullptr;
1531         }
1532         int index = std::distance(windowNodes.begin(), iter);
1533         for (size_t i = static_cast<size_t>(index) + 1; i < windowNodes.size(); i++) {
1534             if (windowNodes[i]->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE
1535                 || !windowNodes[i]->currentVisibility_) {
1536                 continue;
1537             }
1538             return windowNodes[i];
1539         }
1540     } else {
1541         // do nothing
1542     }
1543     WLOGFE("could not get next active window");
1544     return nullptr;
1545 }
1546 
IsForbidDockSliceMove(DisplayId displayId) const1547 bool WindowNodeContainer::IsForbidDockSliceMove(DisplayId displayId) const
1548 {
1549     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1550     if (windowPair == nullptr) {
1551         WLOGFE("window pair is nullptr");
1552         return true;
1553     }
1554     if (windowPair->IsForbidDockSliceMove()) {
1555         return true;
1556     }
1557     return false;
1558 }
1559 
IsDockSliceInExitSplitModeArea(DisplayId displayId) const1560 bool WindowNodeContainer::IsDockSliceInExitSplitModeArea(DisplayId displayId) const
1561 {
1562     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1563     if (windowPair == nullptr) {
1564         WLOGFE("window pair is nullptr");
1565         return false;
1566     }
1567     std::vector<int32_t> exitSplitPoints = layoutPolicy_->GetExitSplitPoints(displayId);
1568     if (exitSplitPoints.size() != EXIT_SPLIT_POINTS_NUMBER) {
1569         return false;
1570     }
1571     return windowPair->IsDockSliceInExitSplitModeArea(exitSplitPoints);
1572 }
1573 
ExitSplitMode(DisplayId displayId)1574 void WindowNodeContainer::ExitSplitMode(DisplayId displayId)
1575 {
1576     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1577     if (windowPair == nullptr) {
1578         WLOGFE("window pair is nullptr");
1579         return;
1580     }
1581     windowPair->ExitSplitMode();
1582 }
1583 
MinimizeAllAppWindows(DisplayId displayId)1584 void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId)
1585 {
1586     WMError ret = MinimizeAppNodeExceptOptions(MinimizeReason::MINIMIZE_ALL);
1587     SwitchLayoutPolicy(WindowLayoutMode::CASCADE, displayId);
1588     if (ret != WMError::WM_OK) {
1589         WLOGFE("Minimize all app window failed");
1590     }
1591     return;
1592 }
1593 
GetDeskTopWindow()1594 sptr<WindowNode> WindowNodeContainer::GetDeskTopWindow()
1595 {
1596     sptr<WindowNode> deskTop;
1597     WindowNodeOperationFunc findDeskTopFunc = [this, &deskTop](sptr<WindowNode> node) {
1598         if (node->GetWindowProperty()->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1599             deskTop = node;
1600             return true;
1601         }
1602         return false;
1603     };
1604     TraverseWindowTree(findDeskTopFunc, false);
1605     return deskTop;
1606 }
1607 
HasPrivateWindow()1608 bool WindowNodeContainer::HasPrivateWindow()
1609 {
1610     std::vector<sptr<WindowNode>> windowNodes;
1611     TraverseContainer(windowNodes);
1612     for (const auto& node : windowNodes) {
1613         if (node->isVisible_ && node->GetWindowProperty()->GetPrivacyMode()) {
1614             WLOGFD("window name %{public}s", node->GetWindowName().c_str());
1615             return true;
1616         }
1617     }
1618     return false;
1619 }
1620 
MinimizeOldestAppWindow()1621 void WindowNodeContainer::MinimizeOldestAppWindow()
1622 {
1623     for (auto& appNode : appWindowNode_->children_) {
1624         if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1625             MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
1626             return;
1627         }
1628     }
1629     for (auto& appNode : aboveAppWindowNode_->children_) {
1630         if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1631             MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
1632             return;
1633         }
1634     }
1635     WLOGFD("no window needs to minimize");
1636 }
1637 
ToggleShownStateForAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc,bool restore)1638 WMError WindowNodeContainer::ToggleShownStateForAllAppWindows(
1639     std::function<bool(uint32_t, WindowMode)> restoreFunc, bool restore)
1640 {
1641     WLOGFD("ToggleShownStateForAllAppWindows");
1642     for (auto node : aboveAppWindowNode_->children_) {
1643         if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT &&
1644             node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && restore) {
1645             return WMError::WM_DO_NOTHING;
1646         }
1647     }
1648     // to do, backup reentry: 1.ToggleShownStateForAllAppWindows fast; 2.this display should reset backupWindowIds_.
1649     if (!restore && appWindowNode_->children_.empty() && !backupWindowIds_.empty()) {
1650         backupWindowIds_.clear();
1651         backupWindowMode_.clear();
1652         backupDisplaySplitWindowMode_.clear();
1653         backupDividerWindowRect_.clear();
1654     }
1655     if (!restore && !appWindowNode_->children_.empty() && backupWindowIds_.empty()) {
1656         WLOGFD("backup");
1657         BackUpAllAppWindows();
1658     } else if (restore && !backupWindowIds_.empty()) {
1659         WLOGFD("restore");
1660         RestoreAllAppWindows(restoreFunc);
1661     } else {
1662         WLOGFD("do nothing because shown app windows is empty or backup windows is empty.");
1663     }
1664     return WMError::WM_OK;
1665 }
1666 
BackUpAllAppWindows()1667 void WindowNodeContainer::BackUpAllAppWindows()
1668 {
1669     std::set<DisplayId> displayIdSet;
1670     backupWindowMode_.clear();
1671     backupDisplaySplitWindowMode_.clear();
1672     std::vector<sptr<WindowNode>> children = appWindowNode_->children_;
1673     for (auto& appNode : children) {
1674         if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
1675             continue;
1676         }
1677         auto windowMode = appNode->GetWindowMode();
1678         backupWindowMode_[appNode->GetWindowId()] = windowMode;
1679         if (WindowHelper::IsSplitWindowMode(windowMode)) {
1680             backupDisplaySplitWindowMode_[appNode->GetDisplayId()].insert(windowMode);
1681         }
1682         displayIdSet.insert(appNode->GetDisplayId());
1683     }
1684     for (auto& appNode : children) {
1685         // exclude exceptional window
1686         if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
1687             WLOGFE("is not main window, windowId:%{public}u", appNode->GetWindowId());
1688             continue;
1689         }
1690         // minimize window
1691         WLOGFD("minimize window, windowId:%{public}u", appNode->GetWindowId());
1692         backupWindowIds_.emplace_back(appNode->GetWindowId());
1693         WindowManagerService::GetInstance().RemoveWindow(appNode->GetWindowId());
1694         wptr<IRemoteObject> abilityToken = appNode->abilityToken_;
1695         WindowInnerManager::GetInstance().PostTask([abilityToken]() {
1696             auto token = abilityToken.promote();
1697             if (token == nullptr) {
1698                 WLOGFW("Ability token is null");
1699                 return;
1700             }
1701             AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(token,
1702                 static_cast<uint32_t>(WindowStateChangeReason::TOGGLING));
1703         });
1704     }
1705     backupDividerWindowRect_.clear();
1706     for (auto displayId : displayIdSet) {
1707         auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1708         if (windowPair == nullptr || windowPair->GetDividerWindow() == nullptr) {
1709             continue;
1710         }
1711         backupDividerWindowRect_[displayId] = windowPair->GetDividerWindow()->GetWindowRect();
1712     }
1713 }
1714 
RestoreAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc)1715 void WindowNodeContainer::RestoreAllAppWindows(std::function<bool(uint32_t, WindowMode)> restoreFunc)
1716 {
1717     std::vector<uint32_t> backupWindowIds(backupWindowIds_);
1718     auto displayIds = DisplayManagerServiceInner::GetInstance().GetAllDisplayIds();
1719     std::vector<sptr<WindowPair>> windowPairs;
1720     for (auto displayId : displayIds) {
1721         auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1722         if (windowPair != nullptr) {
1723             if (backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_PRIMARY) > 0 &&
1724                 backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_SECONDARY) > 0) {
1725                 windowPair->SetAllSplitAppWindowsRestoring(true);
1726             }
1727             windowPairs.emplace_back(windowPair);
1728         }
1729     }
1730     for (auto windowId: backupWindowIds) {
1731         if (!restoreFunc(windowId, backupWindowMode_[windowId])) {
1732             WLOGFE("restore %{public}u failed", windowId);
1733             continue;
1734         }
1735         WLOGFD("restore %{public}u", windowId);
1736     }
1737     for (auto windowPair : windowPairs) {
1738         windowPair->SetAllSplitAppWindowsRestoring(false);
1739     }
1740     layoutPolicy_->SetSplitDividerWindowRects(backupDividerWindowRect_);
1741     backupWindowIds_.clear();
1742     backupWindowMode_.clear();
1743     backupDividerWindowRect_.clear();
1744 }
1745 
IsAppWindowsEmpty() const1746 bool WindowNodeContainer::IsAppWindowsEmpty() const
1747 {
1748     return appWindowNode_->children_.empty();
1749 }
1750 
MinimizeAppNodeExceptOptions(MinimizeReason reason,const std::vector<uint32_t> & exceptionalIds,const std::vector<WindowMode> & exceptionalModes)1751 WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(MinimizeReason reason,
1752     const std::vector<uint32_t> &exceptionalIds, const std::vector<WindowMode> &exceptionalModes)
1753 {
1754     if (appWindowNode_->children_.empty()) {
1755         return WMError::WM_OK;
1756     }
1757     for (auto& appNode : appWindowNode_->children_) {
1758         // exclude exceptional window
1759         if (std::find(exceptionalIds.begin(), exceptionalIds.end(), appNode->GetWindowId()) != exceptionalIds.end() ||
1760             std::find(exceptionalModes.begin(), exceptionalModes.end(),
1761                 appNode->GetWindowMode()) != exceptionalModes.end() ||
1762                 appNode->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1763             continue;
1764         }
1765         MinimizeApp::AddNeedMinimizeApp(appNode, reason);
1766     }
1767     return WMError::WM_OK;
1768 }
1769 
MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode> & node)1770 WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)
1771 {
1772     std::vector<uint32_t> exceptionalIds = { node->GetWindowId() };
1773     std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
1774     return MinimizeAppNodeExceptOptions(MinimizeReason::OTHER_WINDOW, exceptionalIds, exceptionalModes);
1775 }
1776 
ResetLayoutPolicy()1777 void WindowNodeContainer::ResetLayoutPolicy()
1778 {
1779     layoutPolicy_->Reset();
1780 }
1781 
SwitchLayoutPolicy(WindowLayoutMode dstMode,DisplayId displayId,bool reorder)1782 WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder)
1783 {
1784     WLOGFD("SwitchLayoutPolicy src: %{public}d dst: %{public}d, reorder: %{public}d, displayId: %{public}" PRIu64"",
1785         static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder), displayId);
1786     if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) {
1787         WLOGFE("invalid layout mode");
1788         return WMError::WM_ERROR_INVALID_PARAM;
1789     }
1790     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1791     if (windowPair == nullptr) {
1792         WLOGFE("Window pair is nullptr");
1793         return WMError::WM_ERROR_NULLPTR;
1794     }
1795     if (layoutMode_ != dstMode) {
1796         if (layoutMode_ == WindowLayoutMode::CASCADE) {
1797             layoutPolicy_->Reset();
1798             windowPair->Clear();
1799         }
1800         layoutMode_ = dstMode;
1801         layoutPolicy_->Clean();
1802         layoutPolicy_ = layoutPolicies_[dstMode];
1803         layoutPolicy_->Launch();
1804         DumpScreenWindowTree();
1805     } else {
1806         WLOGFD("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
1807     }
1808     if (reorder) {
1809         windowPair->Clear();
1810         layoutPolicy_->Reorder();
1811         DumpScreenWindowTree();
1812     }
1813     NotifyIfSystemBarTintChanged(displayId);
1814     return WMError::WM_OK;
1815 }
1816 
UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode> & node,bool up)1817 void WindowNodeContainer::UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode>& node, bool up)
1818 {
1819     if (!WindowHelper::IsWindowModeSupported(node->GetWindowProperty()->GetRequestModeSupportInfo(),
1820                                              WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
1821         WLOGFD("window doesn't support split mode, winId: %{public}d", node->GetWindowId());
1822         return;
1823     }
1824     uint32_t modeSupportInfo;
1825     if (up) {
1826         modeSupportInfo = node->GetModeSupportInfo() & (~WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY);
1827     } else {
1828         modeSupportInfo = node->GetModeSupportInfo() | WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY;
1829     }
1830     node->SetModeSupportInfo(modeSupportInfo);
1831     if (node->GetWindowToken() != nullptr) {
1832         node->GetWindowToken()->UpdateWindowModeSupportInfo(modeSupportInfo);
1833     }
1834 }
1835 
RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode> & node) const1836 void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const
1837 {
1838     if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || !isScreenLocked_) {
1839         return;
1840     }
1841 
1842     WLOGFD("raise input method float window priority.");
1843     node->priority_ = zorderPolicy_->GetWindowPriority(
1844         WindowType::WINDOW_TYPE_KEYGUARD) + 2; // 2: higher than keyguard and show when locked window
1845 }
1846 
ReZOrderShowWhenLockedWindows(bool up)1847 void WindowNodeContainer::ReZOrderShowWhenLockedWindows(bool up)
1848 {
1849     WLOGFD("Keyguard change %{public}u, re-zorder showWhenLocked window", up);
1850     std::vector<sptr<WindowNode>> needReZOrderNodes;
1851     auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_;
1852     auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_;
1853 
1854     auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 :
1855         zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
1856 
1857     for (auto iter = srcRoot->children_.begin(); iter != srcRoot->children_.end();) {
1858         if ((*iter)->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
1859             needReZOrderNodes.emplace_back(*iter);
1860             iter = srcRoot->children_.erase(iter);
1861         } else {
1862             iter++;
1863         }
1864     }
1865 
1866     for (auto& needReZOrderNode : needReZOrderNodes) {
1867         needReZOrderNode->priority_ = dstPriority;
1868         needReZOrderNode->parent_ = dstRoot;
1869         auto parentNode = needReZOrderNode->parent_;
1870         auto position = parentNode->children_.end();
1871         for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
1872             if ((*iter)->priority_ > needReZOrderNode->priority_) {
1873                 position = iter;
1874                 break;
1875             }
1876         }
1877 
1878         UpdateModeSupportInfoWhenKeyguardChange(needReZOrderNode, up);
1879 
1880         parentNode->children_.insert(position, needReZOrderNode);
1881         if (up && WindowHelper::IsSplitWindowMode(needReZOrderNode->GetWindowMode())) {
1882             needReZOrderNode->GetWindowProperty()->ResumeLastWindowMode();
1883             if (needReZOrderNode->GetWindowToken() != nullptr) {
1884                 needReZOrderNode->GetWindowToken()->UpdateWindowMode(needReZOrderNode->GetWindowMode());
1885             }
1886             auto windowPair = displayGroupController_->GetWindowPairByDisplayId(needReZOrderNode->GetDisplayId());
1887             if (windowPair == nullptr) {
1888                 WLOGFE("Window pair is nullptr");
1889                 return;
1890             }
1891             windowPair->UpdateIfSplitRelated(needReZOrderNode);
1892         }
1893         WLOGFD("window %{public}u re-zorder when keyguard change %{public}u", needReZOrderNode->GetWindowId(), up);
1894     }
1895 }
1896 
ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1897 void WindowNodeContainer::ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1898 {
1899     if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
1900         !isScreenLocked_) {
1901         return;
1902     }
1903 
1904     WLOGFD("ShowWhenLocked window %{public}u re-zorder to up", node->GetWindowId());
1905     ReZOrderShowWhenLockedWindows(true);
1906 }
1907 
RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1908 void WindowNodeContainer::RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1909 {
1910     // if keyguard window show, raise show when locked windows
1911     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1912         ReZOrderShowWhenLockedWindows(true);
1913         return;
1914     }
1915 
1916     // if show when locked window show, raise itself when exist keyguard
1917     if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
1918         !isScreenLocked_) {
1919         return;
1920     }
1921 
1922     WLOGFD("ShowWhenLocked window %{public}u raise itself", node->GetWindowId());
1923     node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
1924     node->parent_ = aboveAppWindowNode_;
1925     if (WindowHelper::IsSplitWindowMode(node->GetWindowMode())) {
1926         node->GetWindowProperty()->ResumeLastWindowMode();
1927         if (node->GetWindowToken() != nullptr) {
1928             node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
1929         }
1930     }
1931 }
1932 
DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1933 void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1934 {
1935     // if keyguard window hide, drop show when locked windows
1936     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1937         ReZOrderShowWhenLockedWindows(false);
1938         AssignZOrder();
1939     }
1940 }
1941 
TraverseWindowTree(const WindowNodeOperationFunc & func,bool isFromTopToBottom) const1942 void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
1943 {
1944     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1945     if (isFromTopToBottom) {
1946         std::reverse(rootNodes.begin(), rootNodes.end());
1947     }
1948 
1949     for (const auto& node : rootNodes) {
1950         if (isFromTopToBottom) {
1951             for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
1952                 if (TraverseFromTopToBottom(*iter, func)) {
1953                     return;
1954                 }
1955             }
1956         } else {
1957             for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
1958                 if (TraverseFromBottomToTop(*iter, func)) {
1959                     return;
1960                 }
1961             }
1962         }
1963     }
1964 }
1965 
TraverseFromTopToBottom(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1966 bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1967 {
1968     if (node == nullptr) {
1969         return false;
1970     }
1971     auto iterBegin = node->children_.rbegin();
1972     for (; iterBegin != node->children_.rend(); ++iterBegin) {
1973         if ((*iterBegin)->priority_ <= 0) {
1974             break;
1975         }
1976         if (func(*iterBegin)) {
1977             return true;
1978         }
1979     }
1980     if (func(node)) {
1981         return true;
1982     }
1983     for (; iterBegin != node->children_.rend(); ++iterBegin) {
1984         if (func(*iterBegin)) {
1985             return true;
1986         }
1987     }
1988     return false;
1989 }
1990 
TraverseFromBottomToTop(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1991 bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1992 {
1993     if (node == nullptr) {
1994         return false;
1995     }
1996     auto iterBegin = node->children_.begin();
1997     for (; iterBegin != node->children_.end(); ++iterBegin) {
1998         if ((*iterBegin)->priority_ >= 0) {
1999             break;
2000         }
2001         if (func(*iterBegin)) {
2002             return true;
2003         }
2004     }
2005     if (func(node)) {
2006         return true;
2007     }
2008     for (; iterBegin != node->children_.end(); ++iterBegin) {
2009         if (func(*iterBegin)) {
2010             return true;
2011         }
2012     }
2013     return false;
2014 }
2015 
GetVirtualPixelRatio(DisplayId displayId) const2016 float WindowNodeContainer::GetVirtualPixelRatio(DisplayId displayId) const
2017 {
2018     return layoutPolicy_->GetVirtualPixelRatio(displayId);
2019 }
2020 
GetDisplayGroupRect() const2021 Rect WindowNodeContainer::GetDisplayGroupRect() const
2022 {
2023     return layoutPolicy_->GetDisplayGroupRect();
2024 }
2025 
SetWindowMode(sptr<WindowNode> & node,WindowMode dstMode)2026 WMError WindowNodeContainer::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
2027 {
2028     if (node == nullptr) {
2029         WLOGFE("could not find window");
2030         return WMError::WM_ERROR_NULLPTR;
2031     }
2032     WindowMode srcMode = node->GetWindowMode();
2033     if (srcMode == dstMode) {
2034         return WMError::WM_OK;
2035     }
2036 
2037     if (WindowHelper::IsSplitWindowMode(dstMode) && isScreenLocked_ &&
2038         (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2039         return WMError::WM_ERROR_INVALID_PARAM;
2040     }
2041 
2042     WMError res = WMError::WM_OK;
2043     if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) {
2044         node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER);
2045     } else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2046         node->SetWindowSizeChangeReason(WindowSizeChangeReason::MAXIMIZE);
2047         if (srcMode == WindowMode::WINDOW_MODE_FLOATING) {
2048             node->SetRequestRect(node->GetWindowRect());
2049         }
2050     } else {
2051         node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
2052     }
2053     node->SetWindowMode(dstMode);
2054     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
2055     if (windowPair == nullptr) {
2056         WLOGFE("Window pair is nullptr");
2057         return WMError::WM_ERROR_NULLPTR;
2058     }
2059     windowPair->UpdateIfSplitRelated(node);
2060     if (WindowHelper::IsMainWindow(node->GetWindowType())) {
2061         if (WindowHelper::IsFloatingWindow(node->GetWindowMode())) {
2062             NotifyDockWindowStateChanged(node, true);
2063         } else {
2064             NotifyDockWindowStateChanged(node, false);
2065         }
2066     }
2067 
2068     if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2069         WindowHelper::IsAppWindow(node->GetWindowType())) {
2070         // minimize other app window
2071         res = MinimizeStructuredAppWindowsExceptSelf(node);
2072         if (res != WMError::WM_OK) {
2073             return res;
2074         }
2075     }
2076     if (node->GetWindowToken() != nullptr) {
2077         node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2078     }
2079     res = UpdateWindowNode(node, WindowUpdateReason::UPDATE_MODE);
2080     if (res != WMError::WM_OK) {
2081         WLOGFE("Set window mode failed, update node failed");
2082         return res;
2083     }
2084     return WMError::WM_OK;
2085 }
2086 
GetModeChangeHotZones(DisplayId displayId,ModeChangeHotZones & hotZones,const ModeChangeHotZonesConfig & config)2087 void WindowNodeContainer::GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones,
2088     const ModeChangeHotZonesConfig& config)
2089 {
2090     const auto& displayRect = displayGroupInfo_->GetDisplayRect(displayId);
2091 
2092     hotZones.fullscreen_.width_ = displayRect.width_;
2093     hotZones.fullscreen_.height_ = config.fullscreenRange_;
2094 
2095     hotZones.primary_.width_ = config.primaryRange_;
2096     hotZones.primary_.height_ = displayRect.height_;
2097 
2098     hotZones.secondary_.posX_ = static_cast<int32_t>(displayRect.width_) - config.secondaryRange_;
2099     hotZones.secondary_.width_ = config.secondaryRange_;
2100     hotZones.secondary_.height_ = displayRect.height_;
2101 }
2102 
GetDisplayVirtualPixelRatio(DisplayId displayId) const2103 float WindowNodeContainer::GetDisplayVirtualPixelRatio(DisplayId displayId) const
2104 {
2105     return displayGroupInfo_->GetDisplayVirtualPixelRatio(displayId);
2106 }
2107 
GetDisplayInfo(DisplayId displayId)2108 sptr<DisplayInfo> WindowNodeContainer::GetDisplayInfo(DisplayId displayId)
2109 {
2110     return displayGroupInfo_->GetDisplayInfo(displayId);
2111 }
2112 
UpdateDisplayInfo(sptr<DisplayInfo> displayInfo)2113 void WindowNodeContainer::UpdateDisplayInfo(sptr<DisplayInfo> displayInfo)
2114 {
2115     displayGroupInfo_->UpdateDisplayInfo(displayInfo);
2116 }
2117 
GetAllDisplayInfo()2118 std::vector<sptr<DisplayInfo>> WindowNodeContainer::GetAllDisplayInfo()
2119 {
2120     return displayGroupInfo_->GetAllDisplayInfo();
2121 }
2122 
UpdateCameraFloatWindowStatus(const sptr<WindowNode> & node,bool isShowing)2123 void WindowNodeContainer::UpdateCameraFloatWindowStatus(const sptr<WindowNode>& node, bool isShowing)
2124 {
2125     if (node->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2126         WindowManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(node->GetAccessTokenId(), isShowing);
2127     }
2128 }
2129 
GetCurrentLayoutMode() const2130 WindowLayoutMode WindowNodeContainer::GetCurrentLayoutMode() const
2131 {
2132     return layoutMode_;
2133 }
2134 
RemoveSingleUserWindowNodes(int accountId)2135 void WindowNodeContainer::RemoveSingleUserWindowNodes(int accountId)
2136 {
2137     std::vector<sptr<WindowNode>> windowNodes;
2138     TraverseContainer(windowNodes);
2139     WLOGFD("%{public}d", accountId);
2140     for (auto& windowNode : windowNodes) {
2141         int windowAccountId = windowNode->GetCallingUid() / UID_TRANSFROM_DIVISOR;
2142         if (windowAccountId < UID_MIN || windowAccountId == accountId) {
2143             WLOGFD("skiped window %{public}s, windowId %{public}d uid %{public}d",
2144                 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2145             continue;
2146         }
2147         WLOGFD("remove window %{public}s, windowId %{public}d uid %{public}d",
2148             windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2149         windowNode->GetWindowProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
2150         if (windowNode->GetWindowToken()) {
2151             if (windowNode->surfaceNode_ != nullptr) {
2152                 windowNode->surfaceNode_->SetVisible(true);
2153             }
2154             windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_HIDDEN);
2155         }
2156     }
2157 }
2158 
TakeWindowPairSnapshot(DisplayId displayId)2159 bool WindowNodeContainer::TakeWindowPairSnapshot(DisplayId displayId)
2160 {
2161     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2162     return windowPair == nullptr ? false : windowPair->TakePairSnapshot();
2163 }
2164 
ClearWindowPairSnapshot(DisplayId displayId)2165 void WindowNodeContainer::ClearWindowPairSnapshot(DisplayId displayId)
2166 {
2167     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2168     if (windowPair == nullptr) {
2169         WLOGFE("Window pair is nullptr");
2170         return;
2171     }
2172     windowPair->ClearPairSnapshot();
2173 }
2174 
IsScreenLocked()2175 bool WindowNodeContainer::IsScreenLocked()
2176 {
2177     return isScreenLocked_;
2178 }
2179 } // namespace Rosen
2180 } // namespace OHOS
2181