• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 <hitrace_meter.h>
24 #include <limits>
25 #include <transaction/rs_interfaces.h>
26 #include <transaction/rs_transaction.h>
27 #include <transaction/rs_sync_transaction_controller.h>
28 
29 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
30 #include <display_power_mgr_client.h>
31 #endif
32 
33 #ifdef POWER_MANAGER_ENABLE
34 #include <power_mgr_client.h>
35 #endif
36 
37 #include "common_event_manager.h"
38 #include "dm_common.h"
39 #include "remote_animation.h"
40 #include "starting_window.h"
41 #include "window_helper.h"
42 #include "window_inner_manager.h"
43 #include "window_layout_policy_cascade.h"
44 #include "window_layout_policy_tile.h"
45 #include "window_manager_agent_controller.h"
46 #include "window_manager_hilog.h"
47 #include "window_manager_service.h"
48 #include "window_manager_service_utils.h"
49 #include "window_system_effect.h"
50 #include "wm_common.h"
51 #include "wm_common_inner.h"
52 
53 namespace OHOS {
54 namespace Rosen {
55 namespace {
56 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "Container"};
57 constexpr int WINDOW_NAME_MAX_LENGTH = 10;
58 constexpr uint32_t MAX_BRIGHTNESS = 255;
59 constexpr uint32_t SPLIT_WINDOWS_CNT = 2;
60 constexpr uint32_t EXIT_SPLIT_POINTS_NUMBER = 2;
61 constexpr int UID_TRANSFROM_DIVISOR = 200000;
62 constexpr int UID_MIN = 100;
63 }
64 AnimationConfig WindowNodeContainer::animationConfig_;
65 bool WindowNodeContainer::isFloatWindowAboveFullWindow_ = false;
66 uint32_t WindowNodeContainer::maxMainFloatingWindowNumber_ = 100;
67 bool WindowNodeContainer::isAnimateTransactionEnabled_ = false;
68 WindowUIType WindowNodeContainer::windowUIType_ = WindowUIType::INVALID_WINDOW;
69 
WindowNodeContainer(const sptr<DisplayInfo> & displayInfo,ScreenId displayGroupId)70 WindowNodeContainer::WindowNodeContainer(const sptr<DisplayInfo>& displayInfo, ScreenId displayGroupId)
71 {
72     DisplayId displayId = displayInfo->GetDisplayId();
73 
74     // create and displayGroupInfo and displayGroupController
75     DisplayGroupInfo::GetInstance().Init(displayGroupId, displayInfo);
76     displayGroupController_ = new DisplayGroupController(this);
77     displayGroupController_->InitNewDisplay(displayId);
78 
79     // init layout policy
80     layoutPolicies_[WindowLayoutMode::CASCADE] = new WindowLayoutPolicyCascade(
81             displayGroupController_->displayGroupWindowTree_);
82     layoutPolicies_[WindowLayoutMode::TILE] = new WindowLayoutPolicyTile(
83         displayGroupController_->displayGroupWindowTree_);
84     layoutPolicy_ = layoutPolicies_[WindowLayoutMode::CASCADE];
85     layoutPolicy_->Launch();
86 
87     // set initial divider rect in windowPair
88     Rect initialDivRect = layoutPolicies_[WindowLayoutMode::CASCADE]->GetDividerRect(displayId);
89     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
90     if (windowPair != nullptr) {
91         windowPair->SetDividerRect(initialDivRect);
92     }
93 
94     // init avoidAreaController
95     avoidController_ = new AvoidAreaController(focusedWindow_);
96     WindowInnerManager::GetInstance().NotifyDisplayLimitRectChange(
97         DisplayGroupInfo::GetInstance().GetAllDisplayRects());
98     isAnimateTransactionEnabled_ = system::GetParameter("persist.window.animateTransaction.enabled", "1")  == "1";
99 }
100 
~WindowNodeContainer()101 WindowNodeContainer::~WindowNodeContainer()
102 {
103     Destroy();
104 }
105 
GetWindowCountByType(WindowType windowType)106 uint32_t WindowNodeContainer::GetWindowCountByType(WindowType windowType)
107 {
108     uint32_t windowNumber = 0;
109     auto counter = [&windowNumber, &windowType](sptr<WindowNode>& windowNode) {
110         if (windowNode->GetWindowType() == windowType && !windowNode->startingWindowShown_) {
111             ++windowNumber;
112         }
113     };
114     std::for_each(belowAppWindowNode_->children_.begin(), belowAppWindowNode_->children_.end(), counter);
115     std::for_each(appWindowNode_->children_.begin(), appWindowNode_->children_.end(), counter);
116     std::for_each(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(), counter);
117     return windowNumber;
118 }
119 
GetMainFloatingWindowCount()120 uint32_t WindowNodeContainer::GetMainFloatingWindowCount()
121 {
122     uint32_t windowNumber = 0;
123     auto counter = [&windowNumber](sptr<WindowNode>& windowNode) {
124         WindowType windowType = windowNode->GetWindowType();
125         WindowMode windowMode = windowNode->GetWindowMode();
126         if (WindowHelper::IsMainFloatingWindow(windowType, windowMode) &&
127             !windowNode->startingWindowShown_) {
128             ++windowNumber;
129         }
130     };
131     std::for_each(appWindowNode_->children_.begin(), appWindowNode_->children_.end(), counter);
132     std::for_each(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(), counter);
133     return windowNumber;
134 }
135 
AddWindowNodeOnWindowTree(sptr<WindowNode> & node,const sptr<WindowNode> & parentNode)136 WMError WindowNodeContainer::AddWindowNodeOnWindowTree(sptr<WindowNode>& node, const sptr<WindowNode>& parentNode)
137 {
138     sptr<WindowNode> root = FindRoot(node->GetWindowType());
139     if (root == nullptr && !(WindowHelper::IsSystemSubWindow(node->GetWindowType()) &&
140         parentNode != nullptr)) {
141         WLOGFE("root is nullptr!");
142         return WMError::WM_ERROR_NULLPTR;
143     }
144     node->requestedVisibility_ = true;
145     if (parentNode != nullptr) { // subwindow
146         if (WindowHelper::IsSystemSubWindow(node->GetWindowType()) ||
147             node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
148             if (WindowHelper::IsSubWindow(parentNode->GetWindowType()) ||
149                 WindowHelper::IsSystemSubWindow(parentNode->GetWindowType()) ||
150                 parentNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT ||
151                 parentNode->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
152                 // some times, dialog is a child window, so exclude
153                 WLOGFE("the parent of window cannot be any sub window");
154                 return WMError::WM_ERROR_INVALID_PARAM;
155             }
156         } else {
157             if (parentNode->parent_ != root &&
158                 !((parentNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) &&
159                 (parentNode->parent_ == aboveAppWindowNode_))) {
160                 WLOGFE("window type and parent window not match \
161                     or try to add subwindow to subwindow, which is forbidden");
162                 return WMError::WM_ERROR_INVALID_PARAM;
163             }
164         }
165         node->currentVisibility_ = parentNode->currentVisibility_;
166         node->parent_ = parentNode;
167     } else { // mainwindow
168         node->parent_ = root;
169         node->currentVisibility_ = true;
170         for (auto& child : node->children_) {
171             child->currentVisibility_ = child->requestedVisibility_;
172         }
173         if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
174             displayGroupController_->sysBarNodeMaps_[node->GetDisplayId()][node->GetWindowType()] = node;
175         }
176     }
177     return WMError::WM_OK;
178 }
179 
ShowStartingWindow(sptr<WindowNode> & node)180 WMError WindowNodeContainer::ShowStartingWindow(sptr<WindowNode>& node)
181 {
182     if (node->currentVisibility_) {
183         TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "current window is visible, windowId: %{public}u",
184             node->GetWindowId());
185         return WMError::WM_ERROR_INVALID_OPERATION;
186     }
187 
188     WMError res = AddWindowNodeOnWindowTree(node, nullptr);
189     if (res != WMError::WM_OK) {
190         return res;
191     }
192     UpdateWindowTree(node);
193     displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
194     StartingWindow::AddNodeOnRSTree(node, layoutPolicy_->IsMultiDisplay());
195     AssignZOrder();
196     layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
197     TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "windowId: %{public}u end", node->GetWindowId());
198     return WMError::WM_OK;
199 }
200 
IsTileRectSatisfiedWithSizeLimits(sptr<WindowNode> & node)201 WMError WindowNodeContainer::IsTileRectSatisfiedWithSizeLimits(sptr<WindowNode>& node)
202 {
203     if (layoutMode_ == WindowLayoutMode::TILE &&
204         !layoutPolicy_->IsTileRectSatisfiedWithSizeLimits(node)) {
205         WLOGFE("layoutMode is tile, default rect is not satisfied with size limits of window, windowId: %{public}u",
206             node->GetWindowId());
207         return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
208     }
209     return WMError::WM_OK;
210 }
211 
GetAnimationConfigRef()212 AnimationConfig& WindowNodeContainer::GetAnimationConfigRef()
213 {
214     return animationConfig_;
215 }
216 
LayoutWhenAddWindowNode(sptr<WindowNode> & node,bool afterAnimation)217 void WindowNodeContainer::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool afterAnimation)
218 {
219     if (afterAnimation) {
220         layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
221         return;
222     }
223     WLOGFD("AddWindowNode Id:%{public}u, currState:%{public}u",
224         node->GetWindowId(), static_cast<uint32_t>(node->stateMachine_.GetCurrentState()));
225     if (WindowHelper::IsMainWindow(node->GetWindowType()) &&
226         RemoteAnimation::IsRemoteAnimationEnabledAndFirst(node->GetDisplayId()) &&
227         node->stateMachine_.IsShowAnimationPlaying()) {
228         // for first frame callback
229         auto winRect = node->GetWindowRect();
230         if (node->surfaceNode_) {
231             node->surfaceNode_->SetBounds(0, 0, winRect.width_, winRect.height_);
232             WLOGI("SetBounds id:%{public}u, rect:[%{public}d, %{public}d, %{public}u, %{public}u]",
233                 node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
234             layoutPolicy_->NotifyClientAndAnimation(node, winRect, WindowSizeChangeReason::UNDEFINED);
235         }
236     } else {
237         if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) &&
238             WindowHelper::IsSystemWindow(node->GetWindowType())) {
239                 node->SetWindowSizeChangeReason(WindowSizeChangeReason::CUSTOM_ANIMATION_SHOW);
240         }
241         layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
242     }
243 }
244 
AddWindowNode(sptr<WindowNode> & node,sptr<WindowNode> & parentNode,bool afterAnimation)245 WMError WindowNodeContainer::AddWindowNode(sptr<WindowNode>& node, sptr<WindowNode>& parentNode, bool afterAnimation)
246 {
247     if (!node->startingWindowShown_) { // window except main Window
248         WMError res = AddWindowNodeOnWindowTree(node, parentNode);
249         if (res != WMError::WM_OK) {
250             return res;
251         }
252         UpdateWindowTree(node);
253         displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
254         // add node on RSTree
255         for (auto& displayId : node->GetShowingDisplays()) {
256             AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ADDED,
257                 node->isPlayAnimationShow_);
258         }
259     } else { // only main app window has starting window
260         node->isPlayAnimationShow_ = false;
261         node->startingWindowShown_ = false;
262         AddAppSurfaceNodeOnRSTree(node);
263         ReZOrderShowWhenLockedWindowIfNeeded(node);
264         RaiseZOrderForAppWindow(node, parentNode);
265     }
266     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
267     if (windowPair == nullptr) {
268         WLOGFE("Window pair is nullptr");
269         return WMError::WM_ERROR_NULLPTR;
270     }
271     windowPair->UpdateIfSplitRelated(node);
272     if (node->IsSplitMode()) {
273         // raise the z-order of window pair
274         RaiseSplitRelatedWindowToTop(node);
275         if (isFloatWindowAboveFullWindow_ && !windowPair->IsDuringSplit()) {
276             ResetAllMainFloatingWindowZOrder(appWindowNode_);
277         }
278     }
279     MinimizeOldestMainFloatingWindow(node->GetWindowId());
280     AssignZOrder();
281     LayoutWhenAddWindowNode(node, afterAnimation);
282     NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_ADD);
283     DumpScreenWindowTreeByWinId(node->GetWindowId());
284     UpdateCameraFloatWindowStatus(node, true);
285     if (WindowHelper::IsMainWindow(node->GetWindowType())) {
286         backupWindowIds_.clear();
287     }
288 
289     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
290         isScreenLocked_ = true;
291         SetBelowScreenlockVisible(node, false);
292     }
293     if (node->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) {
294         RemoteAnimation::NotifyAnimationUpdateWallpaper(node);
295     }
296     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
297         DisplayManagerServiceInner::GetInstance().SetGravitySensorSubscriptionEnabled();
298     }
299     WLOGI("AddWindowNode Id: %{public}u end", node->GetWindowId());
300     RSInterfaces::GetInstance().SetAppWindowNum(GetAppWindowNum());
301     // update private window count and notify dms private status changed
302     if (node->GetWindowProperty()->GetPrivacyMode()) {
303         UpdatePrivateStateAndNotify();
304     }
305     if (WindowHelper::IsMainWindow(node->GetWindowType())) {
306         WindowInfoReporter::GetInstance().InsertShowReportInfo(node->abilityInfo_.bundleName_);
307     }
308     return WMError::WM_OK;
309 }
310 
UpdateRSTreeWhenShowingDisplaysChange(sptr<WindowNode> & node,const std::vector<DisplayId> & lastShowingDisplays)311 void WindowNodeContainer::UpdateRSTreeWhenShowingDisplaysChange(sptr<WindowNode>& node,
312     const std::vector<DisplayId>& lastShowingDisplays)
313 {
314     if (!layoutPolicy_->IsMultiDisplay()) {
315         return;
316     }
317 
318     // Update RSTree
319     auto curShowingDisplays = node->GetShowingDisplays();
320     for (auto& displayId : lastShowingDisplays) {
321         if (std::find(curShowingDisplays.begin(), curShowingDisplays.end(), displayId) == curShowingDisplays.end()) {
322             RemoveNodeFromRSTree(node, displayId, *(curShowingDisplays.begin()),
323                 WindowUpdateType::WINDOW_UPDATE_ACTIVE);
324             WLOGI("remove from RSTree : %{public}" PRIu64"", displayId);
325         }
326     }
327 
328     for (auto& displayId : curShowingDisplays) {
329         if (std::find(lastShowingDisplays.begin(), lastShowingDisplays.end(), displayId) == lastShowingDisplays.end()) {
330             AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
331             WLOGI("add on RSTree : %{public}" PRIu64"", displayId);
332         }
333     }
334 }
335 
UpdateWindowNode(sptr<WindowNode> & node,WindowUpdateReason reason)336 WMError WindowNodeContainer::UpdateWindowNode(sptr<WindowNode>& node, WindowUpdateReason reason)
337 {
338     // Get last displayId and last showing displays before layout
339     auto lastShowingDisplays = node->GetShowingDisplays();
340 
341     // PreProcess window node and layout node
342     displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
343     if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) {
344         SwitchLayoutPolicy(WindowLayoutMode::CASCADE, node->GetDisplayId());
345     }
346     layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
347     displayGroupController_->PostProcessWindowNode(node);
348     // Get current displayId and showing displays, update RSTree and displayGroupWindowTree
349     UpdateRSTreeWhenShowingDisplaysChange(node, lastShowingDisplays);
350     NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_UPDATE);
351     WLOGD("UpdateNode Id: %{public}u end", node->GetWindowId());
352     return WMError::WM_OK;
353 }
354 
RemoveWindowNodeFromWindowTree(sptr<WindowNode> & node)355 void WindowNodeContainer::RemoveWindowNodeFromWindowTree(sptr<WindowNode>& node)
356 {
357     // remove this node from parent
358     auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node);
359     if (iter != node->parent_->children_.end()) {
360         node->parent_->children_.erase(iter);
361     } else {
362         WLOGFE("can't find this node in parent");
363     }
364     node->parent_ = nullptr;
365 }
366 
RemoveFromRsTreeWhenRemoveWindowNode(sptr<WindowNode> & node,bool fromAnimation)367 void WindowNodeContainer::RemoveFromRsTreeWhenRemoveWindowNode(sptr<WindowNode>& node, bool fromAnimation)
368 {
369     if (fromAnimation || (RemoteAnimation::IsRemoteAnimationEnabledAndFirst(node->GetDisplayId()) &&
370         node->stateMachine_.IsHideAnimationPlaying())) {
371             WLOGFD("not remove from rs tree id:%{public}u", node->GetWindowId());
372             return;
373     }
374     // When RemoteAnimation exists, remove node from rs tree after animation
375     WLOGFD("Id:%{public}u, isPlayAnimationHide_:%{public}u", node->GetWindowId(),
376         static_cast<uint32_t>(node->isPlayAnimationHide_));
377     // subwindow or no remote animation also exit with animation
378     for (auto& displayId : node->GetShowingDisplays()) {
379         RemoveNodeFromRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_REMOVED,
380             node->isPlayAnimationHide_);
381     }
382 }
383 
SetSurfaceNodeVisible(sptr<WindowNode> & node,int32_t topPriority,bool visible)384 void WindowNodeContainer::SetSurfaceNodeVisible(sptr<WindowNode>& node, int32_t topPriority, bool visible)
385 {
386     if (node == nullptr) {
387         return;
388     }
389     if (node->parent_ != nullptr && node->currentVisibility_) {
390         if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
391             !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
392             auto surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
393             if (surfaceNode) {
394                 surfaceNode->SetVisible(visible);
395             }
396         }
397     }
398     for (auto& childNode : node->children_) {
399         SetSurfaceNodeVisible(childNode, topPriority, visible);
400     }
401 }
402 
SetBelowScreenlockVisible(sptr<WindowNode> & node,bool visible)403 void WindowNodeContainer::SetBelowScreenlockVisible(sptr<WindowNode>& node, bool visible)
404 {
405     int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
406     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
407     for (auto& node : rootNodes) {
408         SetSurfaceNodeVisible(node, topPriority, visible);
409     }
410 }
411 
RemoveWindowNode(sptr<WindowNode> & node,bool fromAnimation)412 WMError WindowNodeContainer::RemoveWindowNode(sptr<WindowNode>& node, bool fromAnimation)
413 {
414     if (node == nullptr) {
415         WLOGFE("window node or surface node is nullptr, invalid");
416         return WMError::WM_ERROR_DESTROYED_OBJECT;
417     }
418     if (node->parent_ == nullptr) {
419         WLOGFW("can't find parent of this node");
420     } else {
421         RemoveWindowNodeFromWindowTree(node);
422     }
423 
424     node->requestedVisibility_ = false;
425     node->currentVisibility_ = false;
426     RemoveFromRsTreeWhenRemoveWindowNode(node, fromAnimation);
427     node->isPlayAnimationHide_ = false;
428     displayGroupController_->UpdateDisplayGroupWindowTree();
429     layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_REMOVED);
430     WindowMode lastMode = node->GetWindowMode();
431     if (HandleRemoveWindow(node) != WMError::WM_OK) {
432         return WMError::WM_ERROR_NULLPTR;
433     }
434     if (!WindowHelper::IsFloatingWindow(lastMode)) {
435         NotifyDockWindowStateChanged(node, true);
436     }
437     NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_REMOVE);
438     DumpScreenWindowTreeByWinId(node->GetWindowId());
439     UpdateCameraFloatWindowStatus(node, false);
440     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
441         isScreenLocked_ = false;
442         SetBelowScreenlockVisible(node, true);
443     }
444     WLOGI("Remove Id: %{public}u end", node->GetWindowId());
445     RSInterfaces::GetInstance().SetAppWindowNum(GetAppWindowNum());
446 
447     // update private window count and notify dms private status changed
448     if (node->GetWindowProperty()->GetPrivacyMode()) {
449         UpdatePrivateStateAndNotify();
450     }
451     if (WindowHelper::IsMainWindow(node->GetWindowType())) {
452         WindowInfoReporter::GetInstance().InsertHideReportInfo(node->abilityInfo_.bundleName_);
453     }
454     HandleRemoveWindowDisplayOrientation(node, fromAnimation);
455     return WMError::WM_OK;
456 }
457 
HandleRemoveWindowDisplayOrientation(sptr<WindowNode> & node,bool fromAnimation)458 void WindowNodeContainer::HandleRemoveWindowDisplayOrientation(sptr<WindowNode>& node, bool fromAnimation)
459 {
460     if (node->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
461         WLOGFD("[FixOrientation] not full screen window remove, do not update orientation");
462         return;
463     }
464     if (!FIX_ORIENTATION_ENABLE) {
465         auto nextRotatableWindow = GetNextRotatableWindow(node->GetWindowId());
466         if (nextRotatableWindow != nullptr) {
467             SetDisplayOrientationFromWindow(nextRotatableWindow, true);
468         }
469         return;
470     }
471     if (!fromAnimation) {
472         if (node->stateMachine_.IsHideAnimationPlaying()) {
473             WLOGFD("[FixOrientation] removing window is playing hide animation, do not update display orientation");
474             return;
475         }
476         auto nextRotatableWindow = GetNextRotatableWindow(node->GetWindowId());
477         if (nextRotatableWindow == nullptr) {
478             WLOGFD("[FixOrientation] no next window, do not update display orientation");
479             return;
480         }
481         WLOGFD("[FixOrientation] nexi rotatable window: %{public}u", nextRotatableWindow->GetWindowId());
482         if (nextRotatableWindow->stateMachine_.IsShowAnimationPlaying()) {
483             WLOGFD("[FixOrientation] next window is playing show animation, do not update display orientation");
484             return;
485         }
486         if (WmsUtils::IsFixedOrientation(nextRotatableWindow->GetRequestedOrientation(),
487             nextRotatableWindow->GetWindowMode(), nextRotatableWindow->GetWindowFlags())) {
488             WLOGFI("[FixOrientation] next rotatable window is fixed, do not animation");
489             SetDisplayOrientationFromWindow(nextRotatableWindow, false);
490         } else {
491             SetDisplayOrientationFromWindow(nextRotatableWindow, true);
492         }
493     }
494 }
495 
SetDisplayOrientationFromWindow(sptr<WindowNode> & node,bool withAnimation)496 void WindowNodeContainer::SetDisplayOrientationFromWindow(sptr<WindowNode>& node, bool withAnimation)
497 {
498     DisplayManagerServiceInner::GetInstance().SetOrientationFromWindow(node->GetDisplayId(),
499         node->GetRequestedOrientation(), withAnimation);
500 }
501 
UpdatePrivateStateAndNotify()502 void WindowNodeContainer::UpdatePrivateStateAndNotify()
503 {
504     uint32_t prePrivateWindowCount = privateWindowCount_;
505     WLOGFD("before update : privateWindow count: %{public}u", prePrivateWindowCount);
506     UpdatePrivateWindowCount();
507     if (prePrivateWindowCount == 0 && privateWindowCount_ == 1) {
508         DisplayManagerServiceInner::GetInstance().NotifyPrivateWindowStateChanged(true);
509     } else if (prePrivateWindowCount == 1 && privateWindowCount_ == 0) {
510         DisplayManagerServiceInner::GetInstance().NotifyPrivateWindowStateChanged(false);
511     }
512 }
513 
UpdatePrivateWindowCount()514 void WindowNodeContainer::UpdatePrivateWindowCount()
515 {
516     std::vector<sptr<WindowNode>> windowNodes;
517     TraverseContainer(windowNodes);
518     uint32_t count = 0;
519     for (const auto& node : windowNodes) {
520         if (node->GetWindowProperty()->GetPrivacyMode()) {
521             ++count;
522         }
523     }
524     privateWindowCount_ = count;
525     WLOGFD("after update : privateWindow count: %{public}u", privateWindowCount_);
526 }
527 
GetAppWindowNum()528 uint32_t WindowNodeContainer::GetAppWindowNum()
529 {
530     uint32_t num = 0;
531     for (auto& child : appWindowNode_->children_) {
532         if (WindowHelper::IsAppWindow(child->GetWindowType())) {
533             num++;
534         }
535     }
536     return num;
537 }
538 
SetConfigMainFloatingWindowAbove(bool isAbove)539 void WindowNodeContainer::SetConfigMainFloatingWindowAbove(bool isAbove)
540 {
541     isFloatWindowAboveFullWindow_ = isAbove;
542 }
543 
SetMaxMainFloatingWindowNumber(uint32_t maxNumber)544 void WindowNodeContainer::SetMaxMainFloatingWindowNumber(uint32_t maxNumber)
545 {
546     maxMainFloatingWindowNumber_ = maxNumber;
547 }
548 
ResetMainFloatingWindowPriorityIfNeeded(sptr<WindowNode> & windowNode)549 void WindowNodeContainer::ResetMainFloatingWindowPriorityIfNeeded(sptr<WindowNode>& windowNode)
550 {
551     if (!isFloatWindowAboveFullWindow_) {
552         return;
553     }
554     const WindowType& windowType = windowNode->GetWindowType();
555     const WindowMode& windowMode = windowNode->GetWindowMode();
556     if (!WindowHelper::IsMainFloatingWindow(windowType, windowMode)) {
557         return;
558     }
559     const int32_t priorityOffset = 1;
560     auto baseZOrderPolicy = zorderPolicy_->GetWindowPriority(windowType);
561     if (isScreenLocked_ &&
562         (windowNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
563         // if window show when lock, priority should bigger than KEYGUARD.
564         baseZOrderPolicy = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
565     }
566 
567     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(windowNode->GetDisplayId());
568     if (windowPair != nullptr && windowPair->IsDuringSplit()) {
569         windowNode->priority_ = baseZOrderPolicy - priorityOffset;
570         WLOGFD("Reset floating main window zorder priority.[windowId: %{public}u, priority: %{public}d] ",
571             windowNode->GetWindowId(), windowNode->priority_);
572         return;
573     }
574 
575     windowNode->priority_ = baseZOrderPolicy + priorityOffset;
576     WLOGFD("Reset floating main window zorder priority.[windowId: %{public}u, priority: %{public}d] ",
577         windowNode->GetWindowId(), windowNode->priority_);
578 }
579 
ResetAllMainFloatingWindowZOrder(sptr<WindowNode> & rootNode)580 void WindowNodeContainer::ResetAllMainFloatingWindowZOrder(sptr<WindowNode>& rootNode)
581 {
582     if (!isFloatWindowAboveFullWindow_) {
583         WLOGFD("The free window level above full screen window feature is turned off");
584         return;
585     }
586     if (rootNode != appWindowNode_ && rootNode != aboveAppWindowNode_) {
587         return;
588     }
589     /*
590      * update all mainFloatingWindow position on window tree with
591      * the same raleative position between mainFloatingWindows.
592      */
593     std::vector<sptr<WindowNode>> tempWindows;
594     auto itor = rootNode->children_.begin();
595     while (itor != rootNode->children_.end()) {
596         const WindowType& windowType = (*itor)->GetWindowType();
597         const WindowMode& windowMode = (*itor)->GetWindowMode();
598         if (WindowHelper::IsMainFloatingWindow(windowType, windowMode)) {
599             tempWindows.push_back(*itor);
600             itor = rootNode->children_.erase(itor);
601         } else {
602             itor++;
603         }
604     }
605 
606     for (auto& node : tempWindows) {
607         UpdateWindowTree(node);
608     }
609 }
610 
HandleRemoveWindow(sptr<WindowNode> & node)611 WMError WindowNodeContainer::HandleRemoveWindow(sptr<WindowNode>& node)
612 {
613     WLOGFD("start");
614     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
615     if (windowPair == nullptr) {
616         WLOGFE("Window pair is nullptr");
617         return WMError::WM_ERROR_NULLPTR;
618     }
619     windowPair->HandleRemoveWindow(node);
620     auto dividerWindow = windowPair->GetDividerWindow();
621     auto type = node->GetWindowType();
622     if ((type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) &&
623         dividerWindow != nullptr) {
624         UpdateWindowNode(dividerWindow, WindowUpdateReason::UPDATE_RECT);
625     }
626     WLOGFD("end");
627     return WMError::WM_OK;
628 }
629 
DestroyWindowNode(sptr<WindowNode> & node,std::vector<uint32_t> & windowIds)630 WMError WindowNodeContainer::DestroyWindowNode(sptr<WindowNode>& node, std::vector<uint32_t>& windowIds)
631 {
632     WMError ret = RemoveWindowNode(node);
633     if (ret != WMError::WM_OK) {
634         WLOGFE("RemoveWindowNode failed");
635         return ret;
636     }
637     StartingWindow::ReleaseStartWinSurfaceNode(node);
638     node->surfaceNode_ = nullptr;
639     windowIds.push_back(node->GetWindowId());
640     for (auto& child : node->children_) { // destroy sub window if exists
641         windowIds.push_back(child->GetWindowId());
642         child->parent_ = nullptr;
643         if (child->surfaceNode_ != nullptr) {
644             WLOGI("child surfaceNode set nullptr");
645             child->surfaceNode_ = nullptr;
646         }
647     }
648 
649     // clear vector cache completely, swap with empty vector
650     auto emptyVector = std::vector<sptr<WindowNode>>();
651     node->children_.swap(emptyVector);
652     if (node->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) {
653         RemoteAnimation::NotifyAnimationUpdateWallpaper(nullptr);
654     }
655     if (WindowHelper::IsMainWindow(node->GetWindowType())) {
656         WindowInfoReporter::GetInstance().InsertDestroyReportInfo(node->abilityInfo_.bundleName_);
657     }
658 
659     UpdateAvoidAreaListener(node, false);
660     WLOGI("DestroyNode Id: %{public}u end", node->GetWindowId());
661     return WMError::WM_OK;
662 }
663 
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowSizeChangeReason reason)664 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowSizeChangeReason reason)
665 {
666     if (!node->GetWindowToken()) {
667         WLOGFE("windowToken is null");
668         return;
669     }
670     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
671         for (auto& child : appWindowNode_->children_) {
672             if (child->IsSplitMode() && child->GetWindowToken()) {
673                 layoutPolicy_->NotifyClientAndAnimation(child, child->GetWindowRect(), reason);
674                 WLOGI("Notify split window that drag is start or end, Id: "
675                     "%{public}d, reason: %{public}u", child->GetWindowId(), reason);
676             }
677         }
678     } else {
679         layoutPolicy_->NotifyClientAndAnimation(node, node->GetWindowRect(), reason);
680         WLOGI("Notify window that drag is start or end, windowId: %{public}d, "
681             "reason: %{public}u", node->GetWindowId(), reason);
682     }
683 }
684 
UpdateWindowTree(sptr<WindowNode> & node)685 void WindowNodeContainer::UpdateWindowTree(sptr<WindowNode>& node)
686 {
687     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
688     node->priority_ = zorderPolicy_->GetWindowPriority(node->GetWindowType());
689     RaiseInputMethodWindowPriorityIfNeeded(node);
690     RaiseShowWhenLockedWindowIfNeeded(node);
691     ResetMainFloatingWindowPriorityIfNeeded(node);
692     auto parentNode = node->parent_;
693     if (parentNode == nullptr) {
694         WLOGI("Current window node has no parent: %{public}u", node->GetWindowId());
695         return;
696     }
697     auto iter = std::find(parentNode->children_.begin(), parentNode->children_.end(), node);
698     if (iter != parentNode->children_.end()) {
699         WLOGI("node %{public}u already on window tree, not update!", node->GetWindowId());
700         return;
701     }
702     auto position = parentNode->children_.end();
703     int splitWindowCnt = 0;
704     for (auto child = parentNode->children_.begin(); child < parentNode->children_.end(); ++child) {
705         if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && splitWindowCnt == SPLIT_WINDOWS_CNT) {
706             position = child;
707             break;
708         }
709         if (WindowHelper::IsSplitWindowMode((*child)->GetWindowMode())) {
710             splitWindowCnt++;
711         }
712         if ((*child)->priority_ > node->priority_) {
713             position = child;
714             break;
715         }
716     }
717     parentNode->children_.insert(position, node);
718 }
719 
AddAppSurfaceNodeOnRSTree(sptr<WindowNode> & node)720 bool WindowNodeContainer::AddAppSurfaceNodeOnRSTree(sptr<WindowNode>& node)
721 {
722     /*
723      * App main window must has starting window, and show after starting window
724      * Starting Window has already update leashWindowSurfaceNode and starting window surfaceNode on RSTree
725      * Just need add appSurface Node as child of leashWindowSurfaceNode
726      */
727     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AddAppSurfaceNodeOnRSTree(%u)", node->GetWindowId());
728     if (!WindowHelper::IsMainWindow(node->GetWindowType())) {
729         TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "id:%{public}u not main app window but has start window",
730             node->GetWindowId());
731         return false;
732     }
733     if (!node->leashWinSurfaceNode_ || !node->surfaceNode_) {
734         TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "id:%{public}u leashWinSurfaceNode or surfaceNode is null "
735             "but has start window!", node->GetWindowId());
736         return false;
737     }
738     TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "Id: %{public}d", node->GetWindowId());
739     if (!node->currentVisibility_) {
740         TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "id: %{public}d is invisible, no need update RS tree",
741             node->GetWindowId());
742         return false;
743     }
744     node->leashWinSurfaceNode_->AddChild(node->surfaceNode_, -1);
745     return true;
746 }
747 
OpenInputMethodSyncTransaction()748 void WindowNodeContainer::OpenInputMethodSyncTransaction()
749 {
750     if (!isAnimateTransactionEnabled_) {
751         WLOGD("InputMethodSyncTransaction is not enabled");
752         return;
753     }
754     // Before open transaction, it must flush first.
755     auto transactionProxy = RSTransactionProxy::GetInstance();
756     if (!transactionProxy) {
757         return;
758     }
759     transactionProxy->FlushImplicitTransaction();
760     auto syncTransactionController = RSSyncTransactionController::GetInstance();
761     if (syncTransactionController) {
762         syncTransactionController->OpenSyncTransaction();
763     }
764     WLOGD("OpenInputMethodSyncTransaction");
765 }
766 
CloseInputMethodSyncTransaction()767 void WindowNodeContainer::CloseInputMethodSyncTransaction()
768 {
769     if (!isAnimateTransactionEnabled_) {
770         WLOGD("InputMethodSyncTransaction is not enabled while close");
771         return;
772     }
773     auto syncTransactionController = RSSyncTransactionController::GetInstance();
774     if (syncTransactionController) {
775         syncTransactionController->CloseSyncTransaction();
776     }
777     WLOGD("CloseInputMethodSyncTransaction");
778 }
779 
IsWindowFollowParent(WindowType type)780 bool WindowNodeContainer::IsWindowFollowParent(WindowType type)
781 {
782     if (windowUIType_ != WindowUIType::PHONE_WINDOW) {
783         return false;
784     }
785     return WindowHelper::IsWindowFollowParent(type);
786 }
787 
AddNodeOnRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)788 bool WindowNodeContainer::AddNodeOnRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
789     WindowUpdateType type, bool animationPlayed)
790 {
791     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
792     if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
793         node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
794         WLOGI("no need to update RSTree");
795         return true;
796     }
797     bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
798     WLOGFD("Id: %{public}d, displayId: %{public}" PRIu64", parentDisplayId: %{public}" PRIu64", "
799         "isMultiDisplay: %{public}d, animationPlayed: %{public}d",
800         node->GetWindowId(), displayId, parentDisplayId, isMultiDisplay, animationPlayed);
801     auto updateRSTreeFunc = [&]() {
802         if (!node->currentVisibility_) {
803             WLOGI("id: %{public}d invisible, no need update RS tree", node->GetWindowId());
804             return;
805         }
806 
807         if (IsWindowFollowParent(node->GetWindowType())) {
808             auto& parentNode = node->parent_;
809             if (parentNode != nullptr && parentNode->surfaceNode_ != nullptr &&
810                 node->surfaceNode_ != nullptr) {
811                 node->surfaceNode_->SetTranslateX(node->GetWindowRect().posX_ - parentNode->GetWindowRect().posX_);
812                 node->surfaceNode_->SetTranslateY(node->GetWindowRect().posY_ - parentNode->GetWindowRect().posY_);
813                 node->surfaceNode_->SetVisible(true);
814                 parentNode->surfaceNode_->AddChild(node->surfaceNode_, -1);
815                 WLOGFD("Add surfaceNode to parent surfaceNode succeed.");
816                 return;
817             }
818         }
819         auto& dms = DisplayManagerServiceInner::GetInstance();
820         auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
821         dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, true, isMultiDisplay);
822         for (auto& child : node->children_) {
823             if (child->currentVisibility_ && !IsWindowFollowParent(child->GetWindowType())) {
824                 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, true, isMultiDisplay);
825             }
826         }
827     };
828 
829     if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
830         updateRSTreeFunc();
831         return true;
832     }
833 
834     WindowGravity windowGravity;
835     uint32_t percent;
836     node->GetWindowGravity(windowGravity, percent);
837     if (node->EnableDefaultAnimation(animationPlayed)) {
838         WLOGFD("Add node with animation");
839         StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
840         RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
841             animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc);
842         FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
843     } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
844         windowGravity != WindowGravity::WINDOW_GRAVITY_FLOAT &&
845         !animationPlayed) { // add keyboard with animation
846         auto timingProtocol = animationConfig_.keyboardAnimationIn_.duration_;
847         OpenInputMethodSyncTransaction();
848         RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationIn_.curve_, updateRSTreeFunc);
849         CloseInputMethodSyncTransaction();
850     } else {
851         WLOGFD("add node without animation");
852         updateRSTreeFunc();
853     }
854     return true;
855 }
856 
RemoveNodeFromRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)857 bool WindowNodeContainer::RemoveNodeFromRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
858     WindowUpdateType type, bool animationPlayed)
859 {
860     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
861     if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
862         node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
863         WLOGI("no need to update RSTree");
864         return true;
865     }
866     bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
867     WLOGFD("Id: %{public}d, displayId: %{public}" PRIu64", isMultiDisplay: %{public}d, "
868         "parentDisplayId: %{public}" PRIu64", animationPlayed: %{public}d",
869         node->GetWindowId(), displayId, isMultiDisplay, parentDisplayId, animationPlayed);
870     auto updateRSTreeFunc = [&]() {
871         if (IsWindowFollowParent(node->GetWindowType())) {
872             const auto& parentNode = node->parent_;
873             if (parentNode != nullptr && parentNode->surfaceNode_ != nullptr &&
874                 node->surfaceNode_ != nullptr) {
875                 node->surfaceNode_->SetVisible(false);
876                 parentNode->surfaceNode_->RemoveChild(node->surfaceNode_);
877                 WLOGFD("Remove surfaceNode to parent surfaceNode succeed.");
878                 return;
879             }
880         }
881         auto& dms = DisplayManagerServiceInner::GetInstance();
882         auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
883         dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, false, isMultiDisplay);
884         for (auto& child : node->children_) {
885             if (child->currentVisibility_ && !IsWindowFollowParent(child->GetWindowType())) {
886                 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, false, isMultiDisplay);
887             }
888         }
889     };
890 
891     if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
892         updateRSTreeFunc();
893         return true;
894     }
895 
896     WindowGravity windowGravity;
897     uint32_t percent;
898     node->GetWindowGravity(windowGravity, percent);
899     if (node->EnableDefaultAnimation(animationPlayed)) {
900         WLOGFD("remove with animation");
901         StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
902         if (node->surfaceNode_) {
903             node->surfaceNode_->SetFreeze(true);
904         }
905         wptr<WindowNode> weakNode(node);
906         RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
907             animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc, [weakNode]() {
908             auto weakWindow = weakNode.promote();
909             if (weakWindow && weakWindow->surfaceNode_) {
910                 weakWindow->surfaceNode_->SetFreeze(false);
911             }
912         });
913         FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
914     } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
915         windowGravity != WindowGravity::WINDOW_GRAVITY_FLOAT && !animationPlayed) {
916         // remove keyboard with animation
917         OpenInputMethodSyncTransaction();
918         auto timingProtocol = animationConfig_.keyboardAnimationOut_.duration_;
919         RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationOut_.curve_, updateRSTreeFunc);
920         CloseInputMethodSyncTransaction();
921     } else {
922         updateRSTreeFunc();
923     }
924     return true;
925 }
926 
Destroy()927 const std::vector<uint32_t>& WindowNodeContainer::Destroy()
928 {
929     // clear vector cache completely, swap with empty vector
930     auto emptyVector = std::vector<uint32_t>();
931     removedIds_.swap(emptyVector);
932     for (auto& node : belowAppWindowNode_->children_) {
933         DestroyWindowNode(node, removedIds_);
934     }
935     for (auto& node : appWindowNode_->children_) {
936         DestroyWindowNode(node, removedIds_);
937     }
938     for (auto& node : aboveAppWindowNode_->children_) {
939         DestroyWindowNode(node, removedIds_);
940     }
941     return removedIds_;
942 }
943 
FindRoot(WindowType type) const944 sptr<WindowNode> WindowNodeContainer::FindRoot(WindowType type) const
945 {
946     if (WindowHelper::IsAppWindow(type) || type == WindowType::WINDOW_TYPE_DOCK_SLICE ||
947         type == WindowType::WINDOW_TYPE_APP_COMPONENT || type == WindowType::WINDOW_TYPE_PLACEHOLDER ||
948         type == WindowType::WINDOW_TYPE_DIALOG) {
949         return appWindowNode_;
950     }
951     if (WindowHelper::IsBelowSystemWindow(type)) {
952         return belowAppWindowNode_;
953     }
954     if (WindowHelper::IsAboveSystemWindow(type)) {
955         return aboveAppWindowNode_;
956     }
957     return nullptr;
958 }
959 
FindWindowNodeById(uint32_t id) const960 sptr<WindowNode> WindowNodeContainer::FindWindowNodeById(uint32_t id) const
961 {
962     std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
963     for (const auto& rootNode : rootNodes) {
964         for (auto& node : rootNode->children_) {
965             if (node->GetWindowId() == id) {
966                 return node;
967             }
968             for (auto& subNode : node->children_) {
969                 if (subNode->GetWindowId() == id) {
970                     return subNode;
971                 }
972             }
973         }
974     }
975     return nullptr;
976 }
977 
UpdateFocusStatus(uint32_t id,bool focused)978 void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused)
979 {
980     auto node = FindWindowNodeById(id);
981     if (node == nullptr) {
982         WLOGFW("cannot find focused window id:%{public}d", id);
983         return;
984     }
985     if (focused) {
986         focusedPid_ = node->GetCallingPid();
987     }
988     node->isFocused_ = focused;
989     // change focus window shadow
990     WindowSystemEffect::SetWindowShadow(node);
991     if (node->GetCallingPid() == 0) {
992         WLOGFW("focused window is starting window, no need notify");
993         return;
994     }
995 
996     if (focused && node->GetWindowProperty() != nullptr) {
997         AbilityInfo info = node->GetWindowProperty()->GetAbilityInfo();
998         WLOGFD("current focus window: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
999             " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", id,
1000             node->GetWindowProperty()->GetWindowName().c_str(), info.bundleName_.c_str(), info.abilityName_.c_str(),
1001             node->GetCallingPid(), node->GetCallingUid());
1002         uint64_t focusNodeId = 0; // 0 means invalid
1003         if (node->surfaceNode_ == nullptr) {
1004             WLOGFW("focused window surfaceNode is null");
1005         } else {
1006             focusNodeId = node->surfaceNode_->GetId();
1007         }
1008         FocusAppInfo appInfo =
1009             { node->GetCallingPid(), node->GetCallingUid(), info.bundleName_, info.abilityName_, focusNodeId };
1010         RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
1011     }
1012     if (node->GetWindowToken()) {
1013         node->GetWindowToken()->UpdateFocusStatus(focused);
1014     }
1015     if (node->abilityToken_ == nullptr) {
1016         WLOGW("AbilityToken is null, window : %{public}d", id);
1017     }
1018     sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(node->GetWindowId(), node->GetDisplayId(),
1019         node->GetCallingPid(), node->GetCallingUid(), node->GetWindowType(), node->abilityToken_);
1020     WindowManagerAgentController::GetInstance().UpdateFocusChangeInfo(
1021         focusChangeInfo, focused);
1022 }
1023 
UpdateActiveStatus(uint32_t id,bool isActive)1024 void WindowNodeContainer::UpdateActiveStatus(uint32_t id, bool isActive)
1025 {
1026     auto node = FindWindowNodeById(id);
1027     if (node == nullptr) {
1028         WLOGFE("cannot find active window id: %{public}d", id);
1029         return;
1030     }
1031     if (isActive) {
1032         activePid_ = node->GetCallingPid();
1033     }
1034     if (node->GetWindowToken()) {
1035         node->GetWindowToken()->UpdateActiveStatus(isActive);
1036     }
1037 }
1038 
UpdateBrightness(uint32_t id,bool byRemoved)1039 void WindowNodeContainer::UpdateBrightness(uint32_t id, bool byRemoved)
1040 {
1041     auto node = FindWindowNodeById(id);
1042     if (node == nullptr) {
1043         WLOGFE("cannot find active window id: %{public}d", id);
1044         return;
1045     }
1046 
1047     if (!byRemoved) {
1048         if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
1049             return;
1050         }
1051     }
1052     WLOGI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), node->GetBrightness());
1053     if (std::fabs(node->GetBrightness() - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
1054         if (GetDisplayBrightness() != node->GetBrightness()) {
1055             WLOGI("adjust brightness with default value");
1056 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
1057             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
1058 #endif
1059             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
1060         }
1061         SetBrightnessWindow(INVALID_WINDOW_ID);
1062     } else {
1063         if (GetDisplayBrightness() != node->GetBrightness()) {
1064             WLOGI("adjust brightness with value: %{public}u", ToOverrideBrightness(node->GetBrightness()));
1065 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
1066             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
1067                 ToOverrideBrightness(node->GetBrightness()));
1068 #endif
1069             SetDisplayBrightness(node->GetBrightness());
1070         }
1071         SetBrightnessWindow(node->GetWindowId());
1072     }
1073 }
1074 
AssignZOrder()1075 void WindowNodeContainer::AssignZOrder()
1076 {
1077     zOrder_ = 0;
1078     WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
1079         if (!node->leashWinSurfaceNode_ && !node->surfaceNode_ && !node->startingWinSurfaceNode_) {
1080             ++zOrder_;
1081             WLOGFE("Id: %{public}u has no surface nodes", node->GetWindowId());
1082             return false;
1083         }
1084         if (node->leashWinSurfaceNode_ != nullptr) {
1085             ++zOrder_;
1086             node->leashWinSurfaceNode_->SetPositionZ(zOrder_);
1087         }
1088 
1089         if (node->surfaceNode_ != nullptr) {
1090             ++zOrder_;
1091             node->surfaceNode_->SetPositionZ(zOrder_);
1092             node->zOrder_ = zOrder_;
1093         }
1094         // make sure starting window above app
1095         if (node->startingWinSurfaceNode_ != nullptr) {
1096             ++zOrder_;
1097             node->startingWinSurfaceNode_->SetPositionZ(zOrder_);
1098         }
1099         return false;
1100     };
1101     TraverseWindowTree(func, false);
1102     displayGroupController_->UpdateDisplayGroupWindowTree();
1103 }
1104 
SetFocusWindow(uint32_t windowId)1105 WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
1106 {
1107     if (focusedWindow_ == windowId) {
1108         WLOGI("Focus window not change, id: %{public}u, %{public}d", windowId, focusedPid_);
1109         // StartingWindow can be focused and this pid is 0, then notify info in UpdateFocusStatus.
1110         // This info is invalid, so we must notify again when first frame callback.
1111         if (focusedPid_ == 0) {
1112             UpdateFocusStatus(windowId, true);
1113         }
1114         return WMError::WM_DO_NOTHING;
1115     }
1116     UpdateFocusStatus(focusedWindow_, false);
1117     focusedWindow_ = windowId;
1118     UpdateFocusStatus(focusedWindow_, true);
1119     return WMError::WM_OK;
1120 }
1121 
GetFocusWindow() const1122 uint32_t WindowNodeContainer::GetFocusWindow() const
1123 {
1124     return focusedWindow_;
1125 }
1126 
SetActiveWindow(uint32_t windowId,bool byRemoved)1127 WMError WindowNodeContainer::SetActiveWindow(uint32_t windowId, bool byRemoved)
1128 {
1129     if (activeWindow_ == windowId) {
1130         WLOGI("Active window not change, id: %{public}u, %{public}d", windowId, activePid_);
1131         if (activePid_ == 0) {
1132             UpdateActiveStatus(windowId, true);
1133         }
1134         return WMError::WM_DO_NOTHING;
1135     }
1136     UpdateActiveStatus(activeWindow_, false);
1137     activeWindow_ = windowId;
1138     UpdateActiveStatus(activeWindow_, true);
1139     UpdateBrightness(activeWindow_, byRemoved);
1140     return WMError::WM_OK;
1141 }
1142 
SetDisplayBrightness(float brightness)1143 void WindowNodeContainer::SetDisplayBrightness(float brightness)
1144 {
1145     displayBrightness_ = brightness;
1146 }
1147 
GetDisplayBrightness() const1148 float WindowNodeContainer::GetDisplayBrightness() const
1149 {
1150     return displayBrightness_;
1151 }
1152 
SetBrightnessWindow(uint32_t windowId)1153 void WindowNodeContainer::SetBrightnessWindow(uint32_t windowId)
1154 {
1155     brightnessWindow_ = windowId;
1156 }
1157 
GetBrightnessWindow() const1158 uint32_t WindowNodeContainer::GetBrightnessWindow() const
1159 {
1160     return brightnessWindow_;
1161 }
1162 
ToOverrideBrightness(float brightness)1163 uint32_t WindowNodeContainer::ToOverrideBrightness(float brightness)
1164 {
1165     return static_cast<uint32_t>(brightness * MAX_BRIGHTNESS);
1166 }
1167 
GetActiveWindow() const1168 uint32_t WindowNodeContainer::GetActiveWindow() const
1169 {
1170     return activeWindow_;
1171 }
1172 
GetLayoutPolicy() const1173 sptr<WindowLayoutPolicy> WindowNodeContainer::GetLayoutPolicy() const
1174 {
1175     return layoutPolicy_;
1176 }
1177 
GetAvoidController() const1178 sptr<AvoidAreaController> WindowNodeContainer::GetAvoidController() const
1179 {
1180     return avoidController_;
1181 }
1182 
GetDisplayGroupController() const1183 sptr<DisplayGroupController> WindowNodeContainer::GetDisplayGroupController() const
1184 {
1185     return displayGroupController_;
1186 }
1187 
GetRootNode(WindowRootNodeType type) const1188 sptr<WindowNode> WindowNodeContainer::GetRootNode(WindowRootNodeType type) const
1189 {
1190     if (type == WindowRootNodeType::ABOVE_WINDOW_NODE) {
1191         return aboveAppWindowNode_;
1192     } else if (type == WindowRootNodeType::APP_WINDOW_NODE) {
1193         return appWindowNode_;
1194     } else if (type == WindowRootNodeType::BELOW_WINDOW_NODE) {
1195         return belowAppWindowNode_;
1196     }
1197     return nullptr;
1198 }
1199 
HandleKeepScreenOn(const sptr<WindowNode> & node,bool requireLock)1200 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)
1201 {
1202 #ifdef POWER_MANAGER_ENABLE
1203     if (requireLock && node->keepScreenLock_ == nullptr) {
1204         // reset ipc identity
1205         std::string identity = IPCSkeleton::ResetCallingIdentity();
1206         node->keepScreenLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(node->GetWindowName(),
1207             PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
1208         // set ipc identity to raw
1209         IPCSkeleton::SetCallingIdentity(identity);
1210     }
1211     if (node->keepScreenLock_ == nullptr) {
1212         return;
1213     }
1214     WLOGI("keep screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), requireLock);
1215     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "container:HandleKeepScreenOn(%s, %d)",
1216         node->GetWindowName().c_str(), requireLock);
1217     ErrCode res;
1218     // reset ipc identity
1219     std::string identity = IPCSkeleton::ResetCallingIdentity();
1220     if (requireLock) {
1221         res = node->keepScreenLock_->Lock();
1222     } else {
1223         res = node->keepScreenLock_->UnLock();
1224     }
1225     // set ipc identity to raw
1226     IPCSkeleton::SetCallingIdentity(identity);
1227     if (res != ERR_OK) {
1228         WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]", requireLock, res);
1229     }
1230 #endif
1231 }
1232 
IsAboveSystemBarNode(sptr<WindowNode> node) const1233 bool WindowNodeContainer::IsAboveSystemBarNode(sptr<WindowNode> node) const
1234 {
1235     int32_t curPriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
1236     if ((curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_STATUS_BAR)) &&
1237         (curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_NAVIGATION_BAR))) {
1238         return true;
1239     }
1240     return false;
1241 }
1242 
IsSplitImmersiveNode(sptr<WindowNode> node) const1243 bool WindowNodeContainer::IsSplitImmersiveNode(sptr<WindowNode> node) const
1244 {
1245     auto type = node->GetWindowType();
1246     return node->IsSplitMode() || type == WindowType::WINDOW_TYPE_DOCK_SLICE;
1247 }
1248 
GetExpectImmersiveProperty(DisplayId id,sptr<WindowNode> & triggerWindow) const1249 std::unordered_map<WindowType, SystemBarProperty> WindowNodeContainer::GetExpectImmersiveProperty(DisplayId id,
1250     sptr<WindowNode>& triggerWindow) const
1251 {
1252     std::unordered_map<WindowType, SystemBarProperty> sysBarPropMap {
1253         { WindowType::WINDOW_TYPE_STATUS_BAR,     SystemBarProperty() },
1254         { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() },
1255     };
1256 
1257     std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
1258     if (layoutMode_ == WindowLayoutMode::TILE) {
1259         rootNodes = { aboveAppWindowNode_, belowAppWindowNode_ };
1260     }
1261 
1262     for (const auto& node : rootNodes) {
1263         for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); ++iter) {
1264             auto& sysBarPropMapNode = (*iter)->GetSystemBarProperty();
1265             if (IsAboveSystemBarNode(*iter)) {
1266                 continue;
1267             }
1268             if (WindowHelper::IsFullScreenWindow((*iter)->GetWindowMode())
1269                 && (*iter)->GetWindowType() != WindowType::WINDOW_TYPE_PANEL) {
1270                 auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(id);
1271                 if (displayInfo && WmsUtils::IsExpectedRotateLandscapeWindow((*iter)->GetRequestedOrientation(),
1272                     displayInfo->GetDisplayOrientation(), (*iter)->GetWindowFlags())) {
1273                     WLOGFI("Horizontal window id: %{public}d make it immersive", (*iter)->GetWindowId());
1274                     for (auto it : sysBarPropMap) {
1275                         sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1276                         sysBarPropMap[it.first].enable_ = false;
1277                     }
1278                 } else {
1279                     WLOGFD("Top immersive window id: %{public}d. Use full immersive prop", (*iter)->GetWindowId());
1280                     for (auto it : sysBarPropMap) {
1281                         sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1282                     }
1283                     triggerWindow = (*iter);
1284                 }
1285                 return sysBarPropMap;
1286             } else if (IsSplitImmersiveNode(*iter)) {
1287                 WLOGFD("Top split window id: %{public}d. Use split immersive prop", (*iter)->GetWindowId());
1288                 for (auto it : sysBarPropMap) {
1289                     sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1290                     sysBarPropMap[it.first].enable_ = false;
1291                 }
1292                 return sysBarPropMap;
1293             }
1294         }
1295     }
1296 
1297     WLOGFD("No immersive window on top. Use default systembar Property");
1298     return sysBarPropMap;
1299 }
1300 
NotifyIfAvoidAreaChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1301 void WindowNodeContainer::NotifyIfAvoidAreaChanged(const sptr<WindowNode>& node,
1302     const AvoidControlType avoidType) const
1303 {
1304     auto checkFunc = [this](sptr<WindowNode> node) {
1305         return CheckWindowNodeWhetherInWindowTree(node);
1306     };
1307     avoidController_->ProcessWindowChange(node, avoidType, checkFunc);
1308     if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
1309         NotifyIfSystemBarRegionChanged(node->GetDisplayId());
1310     } else {
1311         NotifyIfSystemBarTintChanged(node->GetDisplayId());
1312     }
1313 
1314     NotifyIfKeyboardRegionChanged(node, avoidType);
1315 }
1316 
BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const1317 void WindowNodeContainer::BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const
1318 {
1319     avoidController_->SetFlagForProcessWindowChange(true);
1320 }
1321 
ProcessWindowAvoidAreaChangeWhenDisplayChange() const1322 void WindowNodeContainer::ProcessWindowAvoidAreaChangeWhenDisplayChange() const
1323 {
1324     avoidController_->SetFlagForProcessWindowChange(false);
1325     auto checkFunc = [this](sptr<WindowNode> node) {
1326         return CheckWindowNodeWhetherInWindowTree(node);
1327     };
1328     WindowNodeOperationFunc func = [avoidController = avoidController_, &checkFunc](sptr<WindowNode> node) {
1329         avoidController->ProcessWindowChange(node, AvoidControlType::AVOID_NODE_UPDATE, checkFunc);
1330         return false;
1331     };
1332     TraverseWindowTree(func, true);
1333 }
1334 
NotifyIfSystemBarTintChanged(DisplayId displayId) const1335 void WindowNodeContainer::NotifyIfSystemBarTintChanged(DisplayId displayId) const
1336 {
1337     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1338     sptr<WindowNode> triggerWindow = nullptr;
1339     auto expectSystemBarProp = GetExpectImmersiveProperty(displayId, triggerWindow);
1340     JudgeToReportSystemBarInfo(triggerWindow, expectSystemBarProp);
1341     SystemBarRegionTints tints;
1342     SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1343     for (auto it : sysBarTintMap) {
1344         auto expectProp = expectSystemBarProp.find(it.first)->second;
1345         if (it.second.prop_ == expectProp) {
1346             continue;
1347         }
1348         WLOGFD("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x",
1349             static_cast<int32_t>(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_);
1350         sysBarTintMap[it.first].prop_ = expectProp;
1351         sysBarTintMap[it.first].type_ = it.first;
1352         tints.emplace_back(sysBarTintMap[it.first]);
1353     }
1354     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1355 }
1356 
JudgeToReportSystemBarInfo(const sptr<WindowNode> window,const std::unordered_map<WindowType,SystemBarProperty> & systemBarPropInfo) const1357 void WindowNodeContainer::JudgeToReportSystemBarInfo(const sptr<WindowNode> window,
1358     const std::unordered_map<WindowType, SystemBarProperty>& systemBarPropInfo) const
1359 {
1360     if (window == nullptr || !WindowHelper::IsMainWindow(window->GetWindowType())) {
1361         WLOGFD("No need to report");
1362         return;
1363     }
1364 
1365     // 2 means the must size of systemBarPropInfo.
1366     if (systemBarPropInfo.size() != 2) {
1367         return;
1368     }
1369 
1370     auto bundleName = window->abilityInfo_.bundleName_;
1371     auto abilityName = window->abilityInfo_.abilityName_;
1372     auto navigationItor = systemBarPropInfo.find(WindowType::WINDOW_TYPE_NAVIGATION_BAR);
1373     if (navigationItor != systemBarPropInfo.end() && !navigationItor->second.enable_) {
1374         WindowInfoReporter::GetInstance().InsertNavigationBarReportInfo(bundleName, abilityName);
1375         WLOGFD("the navigation bar is disabled by window. windowId:[%{public}u]", window->GetWindowId());
1376     }
1377 }
1378 
NotifyIfSystemBarRegionChanged(DisplayId displayId) const1379 void WindowNodeContainer::NotifyIfSystemBarRegionChanged(DisplayId displayId) const
1380 {
1381     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1382     SystemBarRegionTints tints;
1383     SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1384     SysBarNodeMap& sysBarNodeMap = displayGroupController_->sysBarNodeMaps_[displayId];
1385     for (auto it : sysBarTintMap) { // split screen mode not support yet
1386         auto sysNode = sysBarNodeMap[it.first];
1387         if (sysNode == nullptr || it.second.region_ == sysNode->GetWindowRect()) {
1388             continue;
1389         }
1390         const Rect& newRegion = sysNode->GetWindowRect();
1391         sysBarTintMap[it.first].region_ = newRegion;
1392         sysBarTintMap[it.first].type_ = it.first;
1393         tints.emplace_back(sysBarTintMap[it.first]);
1394         WLOGD("system bar region update, type: %{public}d" \
1395             "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
1396             static_cast<int32_t>(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_);
1397     }
1398     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1399 }
1400 
NotifyIfKeyboardRegionChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1401 void WindowNodeContainer::NotifyIfKeyboardRegionChanged(const sptr<WindowNode>& node,
1402     const AvoidControlType avoidType) const
1403 {
1404     WindowGravity windowGravity;
1405     uint32_t percent;
1406     node->GetWindowGravity(windowGravity, percent);
1407     if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
1408         windowGravity == WindowGravity::WINDOW_GRAVITY_FLOAT) {
1409         WLOGFD("windowType: %{public}u", node->GetWindowType());
1410         return;
1411     }
1412 
1413     auto callingWindow = FindWindowNodeById(node->GetCallingWindow());
1414     if (callingWindow == nullptr) {
1415         WLOGD("callingWindow: %{public}u does not be set", node->GetCallingWindow());
1416         callingWindow = FindWindowNodeById(GetFocusWindow());
1417     }
1418     if (callingWindow == nullptr || callingWindow->GetWindowToken() == nullptr) {
1419         WLOGE("does not have correct callingWindow for input method window");
1420         return;
1421     }
1422     const WindowMode callingWindowMode = callingWindow->GetWindowMode();
1423     if (callingWindowMode == WindowMode::WINDOW_MODE_FULLSCREEN ||
1424         callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1425         callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
1426         const Rect keyRect = node->GetWindowRect();
1427         const Rect callingRect = callingWindow->GetWindowRect();
1428         if (WindowHelper::IsEmptyRect(WindowHelper::GetOverlap(callingRect, keyRect, 0, 0))) {
1429             WLOGFD("no overlap between two windows");
1430             return;
1431         }
1432         Rect overlapRect = { 0, 0, 0, 0 };
1433         if (avoidType == AvoidControlType::AVOID_NODE_ADD || avoidType == AvoidControlType::AVOID_NODE_UPDATE) {
1434             overlapRect = WindowHelper::GetOverlap(keyRect, callingRect, callingRect.posX_, callingRect.posY_);
1435         }
1436         double textFieldPositionY = 0.0;
1437         double textFieldHeight = 0.0;
1438         if (node->GetWindowProperty() != nullptr) {
1439             textFieldPositionY = node->GetWindowProperty()->GetTextFieldPositionY();
1440             textFieldHeight = node->GetWindowProperty()->GetTextFieldHeight();
1441         }
1442         sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT,
1443             overlapRect, textFieldPositionY, textFieldHeight);
1444         if (isAnimateTransactionEnabled_) {
1445             auto syncTransactionController = RSSyncTransactionController::GetInstance();
1446             if (syncTransactionController) {
1447                 callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info,
1448                     syncTransactionController->GetRSTransaction());
1449             }
1450         } else {
1451             callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info);
1452         }
1453 
1454         WLOGD("keyboard size change callingWindow: [%{public}s, %{public}u], "
1455             "overlap rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
1456             callingWindow->GetWindowName().c_str(), callingWindow->GetWindowId(),
1457             overlapRect.posX_, overlapRect.posY_, overlapRect.width_, overlapRect.height_);
1458         return;
1459     }
1460     WLOGFE("does not have correct callingWindowMode for input method window");
1461 }
1462 
NotifySystemBarTints(std::vector<DisplayId> displayIdVec)1463 void WindowNodeContainer::NotifySystemBarTints(std::vector<DisplayId> displayIdVec)
1464 {
1465     if (displayIdVec.size() != displayGroupController_->sysBarTintMaps_.size()) {
1466         WLOGE("[Immersive] the number of display is error");
1467     }
1468 
1469     for (auto displayId : displayIdVec) {
1470         SystemBarRegionTints tints;
1471         SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1472         for (auto it : sysBarTintMap) {
1473             WLOGI("[Immersive] systembar tints, T: %{public}d, " \
1474                 "V: %{public}d, C: %{public}x | %{public}x, " \
1475                 "R: [%{public}d, %{public}d, %{public}d, %{public}d]",
1476                 static_cast<int32_t>(it.first),
1477                 sysBarTintMap[it.first].prop_.enable_,
1478                 sysBarTintMap[it.first].prop_.backgroundColor_, sysBarTintMap[it.first].prop_.contentColor_,
1479                 sysBarTintMap[it.first].region_.posX_, sysBarTintMap[it.first].region_.posY_,
1480                 sysBarTintMap[it.first].region_.width_, sysBarTintMap[it.first].region_.height_);
1481             tints.push_back(sysBarTintMap[it.first]);
1482         }
1483         WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1484     }
1485 }
1486 
NotifyDockWindowStateChanged(sptr<WindowNode> & node,bool isEnable)1487 void WindowNodeContainer::NotifyDockWindowStateChanged(sptr<WindowNode>& node, bool isEnable)
1488 {
1489     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1490     WLOGFD("[Immersive] begin isEnable: %{public}d", isEnable);
1491     if (isEnable) {
1492         for (auto& windowNode : appWindowNode_->children_) {
1493             if (windowNode->GetWindowId() == node->GetWindowId()) {
1494                 continue;
1495             }
1496             if (!WindowHelper::IsFloatingWindow(windowNode->GetWindowMode())) {
1497                 return;
1498             }
1499         }
1500     }
1501     SystemBarProperty prop;
1502     prop.enable_ = isEnable;
1503     SystemBarRegionTint tint;
1504     tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1505     tint.prop_ = prop;
1506     SystemBarRegionTints tints;
1507     tints.push_back(tint);
1508     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(node->GetDisplayId(), tints);
1509 }
1510 
NotifyDockWindowStateChanged(DisplayId displayId)1511 void WindowNodeContainer::NotifyDockWindowStateChanged(DisplayId displayId)
1512 {
1513     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1514     bool isEnable = true;
1515     for (auto& windowNode : appWindowNode_->children_) {
1516         if (WindowHelper::IsSplitWindowMode(windowNode->GetWindowMode()) ||
1517             WindowHelper::IsFullScreenWindow(windowNode->GetWindowMode())) {
1518             isEnable = false;
1519             break;
1520         }
1521     }
1522     WLOGFD("[Immersive] display %{public}" PRIu64" begin isEnable: %{public}d", displayId, isEnable);
1523     SystemBarProperty prop;
1524     prop.enable_ = isEnable;
1525     SystemBarRegionTint tint;
1526     tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1527     tint.prop_ = prop;
1528     SystemBarRegionTints tints;
1529     tints.push_back(tint);
1530     WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1531 }
1532 
UpdateAvoidAreaListener(sptr<WindowNode> & windowNode,bool haveAvoidAreaListener)1533 void WindowNodeContainer::UpdateAvoidAreaListener(sptr<WindowNode>& windowNode, bool haveAvoidAreaListener)
1534 {
1535     avoidController_->UpdateAvoidAreaListener(windowNode, haveAvoidAreaListener);
1536 }
1537 
IsTopWindow(uint32_t windowId,sptr<WindowNode> & rootNode) const1538 bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const
1539 {
1540     if (rootNode->children_.empty()) {
1541         WLOGFE("root does not have any node");
1542         return false;
1543     }
1544     auto node = *(rootNode->children_.rbegin());
1545     if (node == nullptr) {
1546         WLOGFE("window tree does not have any node");
1547         return false;
1548     }
1549 
1550     for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); iter++) {
1551         if ((*iter)->priority_ > 0) {
1552             return (*iter)->GetWindowId() == windowId;
1553         } else {
1554             break;
1555         }
1556     }
1557     return node->GetWindowId() == windowId;
1558 }
1559 
RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>> & orderedNodes,std::vector<sptr<WindowNode>> & windowNodes)1560 void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes,
1561     std::vector<sptr<WindowNode>>& windowNodes)
1562 {
1563     for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
1564         uint32_t wid = (*iter)->GetWindowId();
1565         auto orderedIter = std::find_if(orderedNodes.begin(), orderedNodes.end(),
1566             [wid] (sptr<WindowNode> orderedNode) { return orderedNode->GetWindowId() == wid; });
1567         if (orderedIter != orderedNodes.end()) {
1568             iter = windowNodes.erase(iter);
1569         } else {
1570             iter++;
1571         }
1572     }
1573     for (auto iter = orderedNodes.begin(); iter != orderedNodes.end(); iter++) {
1574         UpdateWindowTree(*iter);
1575     }
1576     return;
1577 }
1578 
RaiseWindowToTop(uint32_t windowId,std::vector<sptr<WindowNode>> & windowNodes)1579 void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)
1580 {
1581     if (windowNodes.empty()) {
1582         WLOGFE("windowNodes is empty!");
1583         return;
1584     }
1585     auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
1586                              [windowId](sptr<WindowNode> node) {
1587                                  return node->GetWindowId() == windowId;
1588                              });
1589     // raise app node window to top
1590     if (iter != windowNodes.end()) {
1591         sptr<WindowNode> node = *iter;
1592         windowNodes.erase(iter);
1593         UpdateWindowTree(node);
1594         WLOGD("raise window to top %{public}u", node->GetWindowId());
1595     }
1596 }
1597 
TraverseContainer(std::vector<sptr<WindowNode>> & windowNodes) const1598 void WindowNodeContainer::TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const
1599 {
1600     for (auto& node : belowAppWindowNode_->children_) {
1601         TraverseWindowNode(node, windowNodes);
1602     }
1603     for (auto& node : appWindowNode_->children_) {
1604         TraverseWindowNode(node, windowNodes);
1605     }
1606     for (auto& node : aboveAppWindowNode_->children_) {
1607         TraverseWindowNode(node, windowNodes);
1608     }
1609     std::reverse(windowNodes.begin(), windowNodes.end());
1610 }
1611 
TraverseWindowNode(sptr<WindowNode> & node,std::vector<sptr<WindowNode>> & windowNodes) const1612 void WindowNodeContainer::TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const
1613 {
1614     if (node == nullptr) {
1615         return;
1616     }
1617     auto iter = node->children_.begin();
1618     for (; iter < node->children_.end(); ++iter) {
1619         if ((*iter)->priority_ < 0) {
1620             windowNodes.emplace_back(*iter);
1621         } else {
1622             break;
1623         }
1624     }
1625     windowNodes.emplace_back(node);
1626     for (; iter < node->children_.end(); ++iter) {
1627         windowNodes.emplace_back(*iter);
1628     }
1629 }
1630 
GetAvoidAreaByType(const sptr<WindowNode> & node,AvoidAreaType avoidAreaType,const Rect & rect) const1631 AvoidArea WindowNodeContainer::GetAvoidAreaByType(const sptr<WindowNode>& node, AvoidAreaType avoidAreaType,
1632     const Rect& rect) const
1633 {
1634     if (CheckWindowNodeWhetherInWindowTree(node)) {
1635         return avoidController_->GetAvoidAreaByType(node, avoidAreaType);
1636     }
1637     return {};
1638 }
1639 
CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode> & node) const1640 bool WindowNodeContainer::CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode>& node) const
1641 {
1642     bool isInWindowTree = false;
1643     WindowNodeOperationFunc func = [&node, &isInWindowTree](sptr<WindowNode> windowNode) {
1644         if (node->GetWindowId() == windowNode->GetWindowId()) {
1645             isInWindowTree = true;
1646             return true;
1647         }
1648         return false;
1649     };
1650     TraverseWindowTree(func, true);
1651     return isInWindowTree;
1652 }
1653 
DumpScreenWindowTreeByWinId(uint32_t winid)1654 void WindowNodeContainer::DumpScreenWindowTreeByWinId(uint32_t winid)
1655 {
1656     WLOGFD("------ dump window info begin -------");
1657     WLOGFD("WindowName WinId Type Mode ZOrd [   x    y    w    h]");
1658     uint32_t zOrder = zOrder_;
1659     WindowNodeOperationFunc func = [&zOrder, &winid](sptr<WindowNode> node) {
1660         Rect rect = node->GetWindowRect();
1661         uint32_t windowId = node->GetWindowId();
1662         const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1663             node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1664         if (winid == windowId) {
1665             WLOGD("DumpScreenWindowTree: %{public}10s  %{public}5u %{public}4u %{public}4u "
1666                 "%{public}4u [%{public}4d %{public}4d %{public}4u %{public}4u]",
1667                 windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1668                 --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_);
1669         } else {
1670             WLOGD("DumpScreenWindowTree: %{public}10s  %{public}5u %{public}4u %{public}4u "
1671                 "%{public}4u [%{public}4d %{public}4d %{public}4u %{public}4u]",
1672                 windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1673                 --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_);
1674         }
1675         return false;
1676     };
1677     TraverseWindowTree(func, true);
1678     WLOGFD("------ dump window info end -------");
1679 }
1680 
DumpScreenWindowTree()1681 void WindowNodeContainer::DumpScreenWindowTree()
1682 {
1683     WLOGI("------ dump window info begin -------");
1684     WLOGI("WindowName DisplayId WinId Type Mode Flag ZOrd Orientation firstFrameCallback [   x    y    w    h]");
1685     uint32_t zOrder = zOrder_;
1686     WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
1687         Rect rect = node->GetWindowRect();
1688         const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1689             node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1690         WLOGI("DumpScreenWindowTree: %{public}10s %{public}9" PRIu64" %{public}5u %{public}4u %{public}4u %{public}4u "
1691             "%{public}4u %{public}11u %{public}12d [%{public}4d %{public}4d %{public}4u %{public}4u]",
1692             windowName.c_str(), node->GetDisplayId(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1693             node->GetWindowFlags(), --zOrder, static_cast<uint32_t>(node->GetRequestedOrientation()),
1694             node->firstFrameAvailable_, rect.posX_, rect.posY_, rect.width_, rect.height_);
1695         return false;
1696     };
1697     TraverseWindowTree(func, true);
1698     WLOGI("------ dump window info end -------");
1699 }
1700 
IsVerticalDisplay(DisplayId displayId) const1701 bool WindowNodeContainer::IsVerticalDisplay(DisplayId displayId) const
1702 {
1703     return DisplayGroupInfo::GetInstance().GetDisplayRect(displayId).width_ <
1704         DisplayGroupInfo::GetInstance().GetDisplayRect(displayId).height_;
1705 }
1706 
ProcessWindowStateChange(WindowState state,WindowStateChangeReason reason)1707 void WindowNodeContainer::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)
1708 {
1709     switch (reason) {
1710         case WindowStateChangeReason::KEYGUARD: {
1711             int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
1712             TraverseAndUpdateWindowState(state, topPriority);
1713             break;
1714         }
1715         default:
1716             return;
1717     }
1718 }
1719 
TraverseAndUpdateWindowState(WindowState state,int32_t topPriority)1720 void WindowNodeContainer::TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)
1721 {
1722     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1723     for (auto& node : rootNodes) {
1724         UpdateWindowState(node, topPriority, state);
1725     }
1726 }
1727 
UpdateWindowState(sptr<WindowNode> node,int32_t topPriority,WindowState state)1728 void WindowNodeContainer::UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)
1729 {
1730     if (node == nullptr) {
1731         return;
1732     }
1733     if (node->parent_ != nullptr && node->currentVisibility_) {
1734         if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
1735             !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
1736             if (node->GetWindowToken()) {
1737                 node->GetWindowToken()->UpdateWindowState(state);
1738             }
1739             HandleKeepScreenOn(node, state);
1740         }
1741     }
1742     for (auto& childNode : node->children_) {
1743         UpdateWindowState(childNode, topPriority, state);
1744     }
1745 }
1746 
HandleKeepScreenOn(const sptr<WindowNode> & node,WindowState state)1747 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)
1748 {
1749     if (node == nullptr) {
1750         WLOGFE("window is invalid");
1751         return;
1752     }
1753     if (state == WindowState::STATE_FROZEN) {
1754         HandleKeepScreenOn(node, false);
1755     } else if (state == WindowState::STATE_UNFROZEN) {
1756         HandleKeepScreenOn(node, node->IsKeepScreenOn());
1757     } else {
1758         // do nothing
1759     }
1760 }
1761 
FindDividerNode() const1762 sptr<WindowNode> WindowNodeContainer::FindDividerNode() const
1763 {
1764     for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) {
1765         if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1766             return *iter;
1767         }
1768     }
1769     return nullptr;
1770 }
1771 
RaiseSplitRelatedWindowToTop(sptr<WindowNode> & node)1772 void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
1773 {
1774     if (node == nullptr) {
1775         return;
1776     }
1777     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
1778     if (windowPair == nullptr) {
1779         WLOGFE("Window pair is nullptr");
1780         return;
1781     }
1782     std::vector<sptr<WindowNode>> orderedPair = windowPair->GetOrderedPair(node);
1783     RaiseOrderedWindowToTop(orderedPair, appWindowNode_->children_);
1784     AssignZOrder();
1785     return;
1786 }
1787 
RaiseZOrderForAppWindow(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)1788 WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
1789 {
1790     if (node == nullptr) {
1791         return WMError::WM_ERROR_NULLPTR;
1792     }
1793     if (IsTopWindow(node->GetWindowId(), appWindowNode_) || IsTopWindow(node->GetWindowId(), aboveAppWindowNode_)) {
1794         WLOGE("Window %{public}u is already at top", node->GetWindowId());
1795         return WMError::WM_ERROR_INVALID_TYPE;
1796     }
1797 
1798     if (WindowHelper::IsSubWindow(node->GetWindowType()) ||
1799         (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1800         if (parentNode == nullptr) {
1801             WLOGFE("window type is invalid");
1802             return WMError::WM_ERROR_NULLPTR;
1803         }
1804         RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself
1805         if (parentNode->IsSplitMode()) {
1806             RaiseSplitRelatedWindowToTop(parentNode);
1807         } else if (parentNode->parent_ != nullptr) {
1808             RaiseWindowToTop(parentNode->GetWindowId(), parentNode->parent_->children_); // raise parent window
1809         }
1810     } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
1811         if (node->IsSplitMode()) {
1812             RaiseSplitRelatedWindowToTop(node);
1813         } else {
1814             // remote animation continuous start and exit allow parent is nullptr
1815             if (node->parent_ == nullptr) {
1816                 WLOGFW("node parent is nullptr");
1817                 return WMError::WM_OK;
1818             }
1819             RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
1820         }
1821     } else {
1822         // do nothing
1823     }
1824 
1825     AssignZOrder();
1826     WLOGI("Raise app window zorder");
1827     DumpScreenWindowTreeByWinId(node->GetWindowId());
1828     return WMError::WM_OK;
1829 }
1830 
GetNextFocusableWindow(uint32_t windowId) const1831 sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
1832 {
1833     sptr<WindowNode> nextFocusableWindow;
1834     bool previousFocusedWindowFound = false;
1835     WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
1836         sptr<WindowNode> node) {
1837         if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable() && node->currentVisibility_) {
1838             nextFocusableWindow = node;
1839             return true;
1840         }
1841         if (node->GetWindowId() == windowId) {
1842             previousFocusedWindowFound = true;
1843         }
1844         return false;
1845     };
1846     TraverseWindowTree(func, true);
1847     return nextFocusableWindow;
1848 }
1849 
GetNextRotatableWindow(uint32_t windowId) const1850 sptr<WindowNode> WindowNodeContainer::GetNextRotatableWindow(uint32_t windowId) const
1851 {
1852     sptr<WindowNode> nextRotatableWindow;
1853     WindowNodeOperationFunc func = [windowId, &nextRotatableWindow](
1854         sptr<WindowNode> node) {
1855         if (windowId != node->GetWindowId() &&
1856             WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
1857             nextRotatableWindow = node;
1858             return true;
1859         }
1860         return false;
1861     };
1862     TraverseWindowTree(func, true);
1863     return nextRotatableWindow;
1864 }
1865 
GetNextActiveWindow(uint32_t windowId) const1866 sptr<WindowNode> WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) const
1867 {
1868     auto currentNode = FindWindowNodeById(windowId);
1869     if (currentNode == nullptr) {
1870         WLOGFE("cannot find window id: %{public}u by tree", windowId);
1871         return nullptr;
1872     }
1873     WLOGFD("current window: [%{public}u, %{public}u]", windowId, static_cast<uint32_t>(currentNode->GetWindowType()));
1874     if (WindowHelper::IsSystemWindow(currentNode->GetWindowType())) {
1875         for (auto& node : appWindowNode_->children_) {
1876             if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1877                 continue;
1878             }
1879             return node;
1880         }
1881         for (auto& node : belowAppWindowNode_->children_) {
1882             if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1883                 return node;
1884             }
1885         }
1886     } else if (WindowHelper::IsAppWindow(currentNode->GetWindowType())) {
1887         std::vector<sptr<WindowNode>> windowNodes;
1888         TraverseContainer(windowNodes);
1889         auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), [windowId](sptr<WindowNode>& node) {
1890             return node->GetWindowId() == windowId;
1891             });
1892         if (iter == windowNodes.end()) {
1893             WLOGFE("could not find this window");
1894             return nullptr;
1895         }
1896         int index = std::distance(windowNodes.begin(), iter);
1897         for (size_t i = static_cast<size_t>(index) + 1; i < windowNodes.size(); i++) {
1898             if (windowNodes[i]->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE
1899                 || !windowNodes[i]->currentVisibility_) {
1900                 continue;
1901             }
1902             return windowNodes[i];
1903         }
1904     } else {
1905         // do nothing
1906     }
1907     WLOGFE("could not get next active window");
1908     return nullptr;
1909 }
1910 
IsForbidDockSliceMove(DisplayId displayId) const1911 bool WindowNodeContainer::IsForbidDockSliceMove(DisplayId displayId) const
1912 {
1913     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1914     if (windowPair == nullptr) {
1915         WLOGFE("window pair is nullptr");
1916         return true;
1917     }
1918     if (windowPair->IsForbidDockSliceMove()) {
1919         return true;
1920     }
1921     return false;
1922 }
1923 
IsDockSliceInExitSplitModeArea(DisplayId displayId) const1924 bool WindowNodeContainer::IsDockSliceInExitSplitModeArea(DisplayId displayId) const
1925 {
1926     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1927     if (windowPair == nullptr) {
1928         WLOGFE("window pair is nullptr");
1929         return false;
1930     }
1931     std::vector<int32_t> exitSplitPoints = windowPair->GetExitSplitPoints();
1932     if (exitSplitPoints.size() != EXIT_SPLIT_POINTS_NUMBER) {
1933         return false;
1934     }
1935     return windowPair->IsDockSliceInExitSplitModeArea(exitSplitPoints);
1936 }
1937 
ExitSplitMode(DisplayId displayId)1938 void WindowNodeContainer::ExitSplitMode(DisplayId displayId)
1939 {
1940     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1941     if (windowPair == nullptr) {
1942         WLOGFE("window pair is nullptr");
1943         return;
1944     }
1945     windowPair->ExitSplitMode();
1946 }
1947 
MinimizeAllAppWindows(DisplayId displayId)1948 void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId)
1949 {
1950     WMError ret = MinimizeAppNodeExceptOptions(MinimizeReason::MINIMIZE_ALL);
1951     SwitchLayoutPolicy(WindowLayoutMode::CASCADE, displayId);
1952     if (ret != WMError::WM_OK) {
1953         WLOGFE("Minimize all app window failed");
1954     }
1955     return;
1956 }
1957 
GetDeskTopWindow()1958 sptr<WindowNode> WindowNodeContainer::GetDeskTopWindow()
1959 {
1960     sptr<WindowNode> deskTop;
1961     WindowNodeOperationFunc findDeskTopFunc = [this, &deskTop](sptr<WindowNode> node) {
1962         if (node->GetWindowProperty()->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1963             deskTop = node;
1964             return true;
1965         }
1966         return false;
1967     };
1968     TraverseWindowTree(findDeskTopFunc, false);
1969     return deskTop;
1970 }
1971 
HasPrivateWindow()1972 bool WindowNodeContainer::HasPrivateWindow()
1973 {
1974     std::vector<sptr<WindowNode>> windowNodes;
1975     TraverseContainer(windowNodes);
1976     for (const auto& node : windowNodes) {
1977         if (node && node->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION &&
1978             node->GetWindowProperty()->GetPrivacyMode()) {
1979             WLOGI("window name %{public}s", node->GetWindowName().c_str());
1980             return true;
1981         }
1982     }
1983     return false;
1984 }
1985 
HasMainFullScreenWindowShown()1986 bool WindowNodeContainer::HasMainFullScreenWindowShown()
1987 {
1988     std::vector<sptr<WindowNode>> windowNodes;
1989     for (auto& node : appWindowNode_->children_) {
1990         TraverseWindowNode(node, windowNodes);
1991     }
1992     for (const auto& node : windowNodes) {
1993         if (node->currentVisibility_ &&
1994             WindowHelper::IsMainFullScreenWindow(node->GetWindowType(), node->GetWindowMode())) {
1995             return true;
1996         }
1997     }
1998     return false;
1999 }
2000 
MinimizeOldestAppWindow()2001 void WindowNodeContainer::MinimizeOldestAppWindow()
2002 {
2003     for (auto& appNode : appWindowNode_->children_) {
2004         if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2005             MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
2006             return;
2007         }
2008     }
2009     for (auto& appNode : aboveAppWindowNode_->children_) {
2010         if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2011             MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
2012             return;
2013         }
2014     }
2015     WLOGD("no window needs to minimize");
2016 }
2017 
MinimizeOldestMainFloatingWindow(uint32_t windowId)2018 void WindowNodeContainer::MinimizeOldestMainFloatingWindow(uint32_t windowId)
2019 {
2020     if (maxMainFloatingWindowNumber_ <= 0) {
2021         WLOGD("There is no limit at The number of floating window");
2022         return;
2023     }
2024 
2025     auto windowNumber = GetMainFloatingWindowCount();
2026     if (windowNumber <= maxMainFloatingWindowNumber_) {
2027         WLOGD("The number of floating window is less then MaxFloatAppMainWindowNumber");
2028         return;
2029     }
2030     std::vector<sptr<WindowNode>> rootNodes = {
2031         appWindowNode_, aboveAppWindowNode_,
2032     };
2033     for (auto& root : rootNodes) {
2034         for (auto& appNode : root->children_) {
2035             WindowType windowType = appNode->GetWindowType();
2036             WindowMode windowMode = appNode->GetWindowMode();
2037             uint32_t winId = appNode->GetWindowId();
2038             if (windowId != winId && WindowHelper::IsMainFloatingWindow(windowType, windowMode)) {
2039                 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
2040                 return;
2041             }
2042         }
2043     }
2044     WLOGD("no window needs to minimize");
2045 }
2046 
ToggleShownStateForAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc,bool restore)2047 WMError WindowNodeContainer::ToggleShownStateForAllAppWindows(
2048     std::function<bool(uint32_t, WindowMode)> restoreFunc, bool restore)
2049 {
2050     for (auto node : aboveAppWindowNode_->children_) {
2051         if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT &&
2052             node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && restore) {
2053             return WMError::WM_DO_NOTHING;
2054         }
2055     }
2056     // to do, backup reentry: 1.ToggleShownStateForAllAppWindows fast; 2.this display should reset backupWindowIds_.
2057     if (!restore && appWindowNode_->children_.empty() && !backupWindowIds_.empty()) {
2058         backupWindowIds_.clear();
2059         backupWindowMode_.clear();
2060         backupDisplaySplitWindowMode_.clear();
2061         backupDividerWindowRect_.clear();
2062     }
2063     if (!restore && !appWindowNode_->children_.empty() && backupWindowIds_.empty()) {
2064         WLOGD("backup");
2065         BackUpAllAppWindows();
2066     } else if (restore && !backupWindowIds_.empty()) {
2067         WLOGD("restore");
2068         RestoreAllAppWindows(restoreFunc);
2069     } else {
2070         WLOGD("do nothing because shown app windows is empty or backup windows is empty.");
2071     }
2072     WLOGD("ToggleShownStateForAllAppWindows");
2073     return WMError::WM_OK;
2074 }
2075 
BackUpAllAppWindows()2076 void WindowNodeContainer::BackUpAllAppWindows()
2077 {
2078     std::set<DisplayId> displayIdSet;
2079     backupWindowMode_.clear();
2080     backupDisplaySplitWindowMode_.clear();
2081     std::vector<sptr<WindowNode>> children = appWindowNode_->children_;
2082     for (auto& appNode : children) {
2083         if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
2084             continue;
2085         }
2086         auto windowMode = appNode->GetWindowMode();
2087         backupWindowMode_[appNode->GetWindowId()] = windowMode;
2088         if (WindowHelper::IsSplitWindowMode(windowMode)) {
2089             backupDisplaySplitWindowMode_[appNode->GetDisplayId()].insert(windowMode);
2090         }
2091         displayIdSet.insert(appNode->GetDisplayId());
2092     }
2093     for (auto& appNode : children) {
2094         // exclude exceptional window
2095         if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
2096             WLOGFE("is not main window, windowId:%{public}u", appNode->GetWindowId());
2097             continue;
2098         }
2099         // minimize window
2100         WLOGFD("minimize window, windowId:%{public}u", appNode->GetWindowId());
2101         backupWindowIds_.emplace_back(appNode->GetWindowId());
2102         WindowManagerService::GetInstance().RemoveWindow(appNode->GetWindowId(), true);
2103         wptr<IRemoteObject> abilityToken = appNode->abilityToken_;
2104         auto task = [abilityToken]() {
2105             auto token = abilityToken.promote();
2106             if (token == nullptr) {
2107                 WLOGFW("Ability token is null");
2108                 return;
2109             }
2110             AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(token,
2111                 static_cast<uint32_t>(WindowStateChangeReason::TOGGLING));
2112         };
2113         WindowInnerManager::GetInstance().PostTask(task, "DoAbilityBackground");
2114     }
2115     backupDividerWindowRect_.clear();
2116     for (auto displayId : displayIdSet) {
2117         auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2118         if (windowPair == nullptr || windowPair->GetDividerWindow() == nullptr) {
2119             continue;
2120         }
2121         backupDividerWindowRect_[displayId] = windowPair->GetDividerWindow()->GetWindowRect();
2122     }
2123 }
2124 
RestoreAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc)2125 void WindowNodeContainer::RestoreAllAppWindows(std::function<bool(uint32_t, WindowMode)> restoreFunc)
2126 {
2127     std::vector<uint32_t> backupWindowIds(backupWindowIds_);
2128     auto displayIds = DisplayGroupInfo::GetInstance().GetAllDisplayIds();
2129     std::vector<sptr<WindowPair>> windowPairs;
2130     for (auto displayId : displayIds) {
2131         auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2132         if (windowPair != nullptr) {
2133             if (backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_PRIMARY) > 0 &&
2134                 backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_SECONDARY) > 0) {
2135                 windowPair->SetAllSplitAppWindowsRestoring(true);
2136             }
2137             windowPairs.emplace_back(windowPair);
2138         }
2139     }
2140     for (auto windowId: backupWindowIds) {
2141         if (!restoreFunc(windowId, backupWindowMode_[windowId])) {
2142             WLOGFE("restore %{public}u failed", windowId);
2143             continue;
2144         }
2145         WLOGFD("restore %{public}u", windowId);
2146     }
2147     for (auto windowPair : windowPairs) {
2148         windowPair->SetAllSplitAppWindowsRestoring(false);
2149     }
2150     layoutPolicy_->SetSplitDividerWindowRects(backupDividerWindowRect_);
2151     backupWindowIds_.clear();
2152     backupWindowMode_.clear();
2153     backupDividerWindowRect_.clear();
2154 }
2155 
IsAppWindowsEmpty() const2156 bool WindowNodeContainer::IsAppWindowsEmpty() const
2157 {
2158     return appWindowNode_->children_.empty();
2159 }
2160 
MinimizeAppNodeExceptOptions(MinimizeReason reason,const std::vector<uint32_t> & exceptionalIds,const std::vector<WindowMode> & exceptionalModes)2161 WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(MinimizeReason reason,
2162     const std::vector<uint32_t>& exceptionalIds, const std::vector<WindowMode>& exceptionalModes)
2163 {
2164     if (appWindowNode_->children_.empty()) {
2165         return WMError::WM_OK;
2166     }
2167     for (auto& appNode : appWindowNode_->children_) {
2168         // exclude exceptional window
2169         if (std::find(exceptionalIds.begin(), exceptionalIds.end(), appNode->GetWindowId()) != exceptionalIds.end() ||
2170             std::find(exceptionalModes.begin(), exceptionalModes.end(),
2171                 appNode->GetWindowMode()) != exceptionalModes.end() ||
2172                 appNode->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2173             continue;
2174         }
2175         MinimizeApp::AddNeedMinimizeApp(appNode, reason);
2176     }
2177     return WMError::WM_OK;
2178 }
2179 
MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode> & node)2180 WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)
2181 {
2182     std::vector<uint32_t> exceptionalIds = { node->GetWindowId() };
2183     std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
2184     return MinimizeAppNodeExceptOptions(MinimizeReason::OTHER_WINDOW, exceptionalIds, exceptionalModes);
2185 }
2186 
SwitchLayoutPolicy(WindowLayoutMode dstMode,DisplayId displayId,bool reorder)2187 WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder)
2188 {
2189     WLOGD("SwitchLayoutPolicy src: %{public}d dst: %{public}d, reorder: %{public}d, displayId: %{public}" PRIu64"",
2190         static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder), displayId);
2191     if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) {
2192         WLOGFE("invalid layout mode");
2193         return WMError::WM_ERROR_INVALID_PARAM;
2194     }
2195     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2196     if (windowPair == nullptr) {
2197         WLOGFE("Window pair is nullptr");
2198         return WMError::WM_ERROR_NULLPTR;
2199     }
2200     if (layoutMode_ != dstMode) {
2201         if (layoutMode_ == WindowLayoutMode::CASCADE) {
2202             windowPair->Clear();
2203         }
2204         layoutMode_ = dstMode;
2205         layoutPolicy_ = layoutPolicies_[dstMode];
2206         layoutPolicy_->Launch();
2207         DumpScreenWindowTree();
2208     } else {
2209         WLOGI("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
2210     }
2211     if (reorder) {
2212         windowPair->Clear();
2213         layoutPolicy_->Reorder();
2214         DumpScreenWindowTree();
2215     }
2216     NotifyIfSystemBarTintChanged(displayId);
2217     NotifyDockWindowStateChanged(displayId);
2218     return WMError::WM_OK;
2219 }
2220 
UpdateWindowModeSupportTypeWhenKeyguardChange(const sptr<WindowNode> & node,bool up)2221 void WindowNodeContainer::UpdateWindowModeSupportTypeWhenKeyguardChange(const sptr<WindowNode>& node, bool up)
2222 {
2223     if (!WindowHelper::IsWindowModeSupported(node->GetWindowProperty()->GetRequestWindowModeSupportType(),
2224                                              WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
2225         WLOGFD("window doesn't support split mode, winId: %{public}d", node->GetWindowId());
2226         return;
2227     }
2228     uint32_t windowModeSupportType;
2229     if (up) {
2230         windowModeSupportType = node->GetWindowModeSupportType() &
2231             (~WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY);
2232     } else {
2233         windowModeSupportType = node->GetWindowModeSupportType() | WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY;
2234     }
2235     node->SetWindowModeSupportType(windowModeSupportType);
2236     if (node->GetWindowToken() != nullptr) {
2237         node->GetWindowToken()->UpdateWindowModeSupportType(windowModeSupportType);
2238     }
2239 }
2240 
RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode> & node) const2241 void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const
2242 {
2243     if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2244         return;
2245     }
2246 
2247     if (isScreenLocked_) {
2248         node->priority_ = zorderPolicy_->GetWindowPriority(
2249             WindowType::WINDOW_TYPE_KEYGUARD) + 2; // 2: higher than keyguard and show when locked window
2250         WLOGD("Raise input method float window priority when screen locked.");
2251         return;
2252     }
2253 
2254     auto callingWindowId = node->GetCallingWindow();
2255     auto callingWindow = FindWindowNodeById(callingWindowId);
2256     if (callingWindowId == focusedWindow_ && callingWindow != nullptr) {
2257         auto callingWindowType = callingWindow->GetWindowType();
2258         auto callingWindowPriority = zorderPolicy_->GetWindowPriority(callingWindowType);
2259         auto inputMethodPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
2260 
2261         node->priority_ = (inputMethodPriority < callingWindowPriority) ?
2262             (callingWindowPriority + 1) : inputMethodPriority;
2263         WLOGFD("Reset input method float window priority to %{public}d.", node->priority_);
2264         return;
2265     }
2266 
2267     auto focusWindow = FindWindowNodeById(focusedWindow_);
2268     if (focusWindow != nullptr && focusWindow->GetWindowType() == WindowType::WINDOW_TYPE_PANEL) {
2269         node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_PANEL) + 1;
2270         WLOGFD("The input method float window should be higher than panel");
2271     }
2272 }
2273 
ReZOrderShowWhenLockedWindows(bool up)2274 void WindowNodeContainer::ReZOrderShowWhenLockedWindows(bool up)
2275 {
2276     WLOGD("Keyguard change %{public}u, re-zorder showWhenLocked window", up);
2277     std::vector<sptr<WindowNode>> needReZOrderNodes;
2278     auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_;
2279     auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_;
2280 
2281     auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 :
2282         zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
2283 
2284     for (auto iter = srcRoot->children_.begin(); iter != srcRoot->children_.end();) {
2285         if ((*iter)->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
2286             needReZOrderNodes.emplace_back(*iter);
2287             iter = srcRoot->children_.erase(iter);
2288         } else {
2289             iter++;
2290         }
2291     }
2292     const int32_t floatingPriorityOffset = 1;
2293     for (auto& needReZOrderNode : needReZOrderNodes) {
2294         needReZOrderNode->priority_ = dstPriority;
2295         needReZOrderNode->parent_ = dstRoot;
2296         if (WindowHelper::IsMainFloatingWindow(needReZOrderNode->GetWindowType(),
2297             needReZOrderNode->GetWindowMode()) && isFloatWindowAboveFullWindow_) {
2298             needReZOrderNode->priority_ = dstPriority + floatingPriorityOffset;
2299         }
2300         auto parentNode = needReZOrderNode->parent_;
2301         auto position = parentNode->children_.end();
2302         for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
2303             if ((*iter)->priority_ > needReZOrderNode->priority_) {
2304                 position = iter;
2305                 break;
2306             }
2307         }
2308 
2309         UpdateWindowModeSupportTypeWhenKeyguardChange(needReZOrderNode, up);
2310 
2311         parentNode->children_.insert(position, needReZOrderNode);
2312         if (up && WindowHelper::IsSplitWindowMode(needReZOrderNode->GetWindowMode())) {
2313             needReZOrderNode->GetWindowProperty()->ResumeLastWindowMode();
2314             // when change mode, need to reset shadow and radius
2315             WindowSystemEffect::SetWindowEffect(needReZOrderNode);
2316             if (needReZOrderNode->GetWindowToken() != nullptr) {
2317                 needReZOrderNode->GetWindowToken()->UpdateWindowMode(needReZOrderNode->GetWindowMode());
2318             }
2319             auto windowPair = displayGroupController_->GetWindowPairByDisplayId(needReZOrderNode->GetDisplayId());
2320             if (windowPair == nullptr) {
2321                 WLOGFE("Window pair is nullptr");
2322                 return;
2323             }
2324             windowPair->UpdateIfSplitRelated(needReZOrderNode);
2325         }
2326         WLOGD("window %{public}u re-zorder when keyguard change %{public}u", needReZOrderNode->GetWindowId(), up);
2327     }
2328 }
2329 
ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)2330 void WindowNodeContainer::ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
2331 {
2332     if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
2333         !isScreenLocked_) {
2334         return;
2335     }
2336 
2337     ReZOrderShowWhenLockedWindows(true);
2338     WLOGI("ShowWhenLocked window %{public}u re-zorder to up", node->GetWindowId());
2339 }
2340 
RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)2341 void WindowNodeContainer::RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
2342 {
2343     // if keyguard window show, raise show when locked windows
2344     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
2345         ReZOrderShowWhenLockedWindows(true);
2346         return;
2347     }
2348 
2349     // if show when locked window show, raise itself when exist keyguard
2350     if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
2351         !isScreenLocked_) {
2352         return;
2353     }
2354 
2355     node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
2356     node->parent_ = aboveAppWindowNode_;
2357     if (WindowHelper::IsSplitWindowMode(node->GetWindowMode())) {
2358         node->GetWindowProperty()->ResumeLastWindowMode();
2359         // when change mode, need to reset shadow and radius
2360         WindowSystemEffect::SetWindowEffect(node);
2361         if (node->GetWindowToken() != nullptr) {
2362             node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2363         }
2364     }
2365     WLOGI("ShowWhenLocked window %{public}u raise itself", node->GetWindowId());
2366 }
2367 
DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)2368 void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
2369 {
2370     // if keyguard window hide, drop show when locked windows
2371     if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
2372         ReZOrderShowWhenLockedWindows(false);
2373         AssignZOrder();
2374     }
2375 }
2376 
TraverseWindowTree(const WindowNodeOperationFunc & func,bool isFromTopToBottom) const2377 void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
2378 {
2379     std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
2380     if (isFromTopToBottom) {
2381         std::reverse(rootNodes.begin(), rootNodes.end());
2382     }
2383 
2384     for (const auto& node : rootNodes) {
2385         if (isFromTopToBottom) {
2386             for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
2387                 if (TraverseFromTopToBottom(*iter, func)) {
2388                     return;
2389                 }
2390             }
2391         } else {
2392             for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
2393                 if (TraverseFromBottomToTop(*iter, func)) {
2394                     return;
2395                 }
2396             }
2397         }
2398     }
2399 }
2400 
TraverseFromTopToBottom(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const2401 bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
2402 {
2403     if (node == nullptr) {
2404         return false;
2405     }
2406     auto iterBegin = node->children_.rbegin();
2407     for (; iterBegin != node->children_.rend(); ++iterBegin) {
2408         if ((*iterBegin)->priority_ <= 0) {
2409             break;
2410         }
2411         if (func(*iterBegin)) {
2412             return true;
2413         }
2414     }
2415     if (func(node)) {
2416         return true;
2417     }
2418     for (; iterBegin != node->children_.rend(); ++iterBegin) {
2419         if (func(*iterBegin)) {
2420             return true;
2421         }
2422     }
2423     return false;
2424 }
2425 
TraverseFromBottomToTop(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const2426 bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
2427 {
2428     if (node == nullptr) {
2429         return false;
2430     }
2431     auto iterBegin = node->children_.begin();
2432     for (; iterBegin != node->children_.end(); ++iterBegin) {
2433         if ((*iterBegin)->priority_ >= 0) {
2434             break;
2435         }
2436         if (func(*iterBegin)) {
2437             return true;
2438         }
2439     }
2440     if (func(node)) {
2441         return true;
2442     }
2443     for (; iterBegin != node->children_.end(); ++iterBegin) {
2444         if (func(*iterBegin)) {
2445             return true;
2446         }
2447     }
2448     return false;
2449 }
2450 
GetDisplayGroupRect() const2451 Rect WindowNodeContainer::GetDisplayGroupRect() const
2452 {
2453     return layoutPolicy_->GetDisplayGroupRect();
2454 }
2455 
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowMode srcMode,WindowMode dstMode)2456 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowMode srcMode, WindowMode dstMode)
2457 {
2458     if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) {
2459         node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER);
2460     } else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2461         node->SetWindowSizeChangeReason(WindowSizeChangeReason::MAXIMIZE);
2462         if (srcMode == WindowMode::WINDOW_MODE_FLOATING) {
2463             node->SetRequestRect(node->GetWindowRect());
2464         }
2465     } else if (WindowHelper::IsFullScreenWindow(srcMode) && WindowHelper::IsSplitWindowMode(dstMode)) {
2466         node->SetWindowSizeChangeReason(WindowSizeChangeReason::FULL_TO_SPLIT);
2467     } else if (WindowHelper::IsSplitWindowMode(srcMode) && WindowHelper::IsFullScreenWindow(dstMode)) {
2468         node->SetWindowSizeChangeReason(WindowSizeChangeReason::SPLIT_TO_FULL);
2469     } else {
2470         node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
2471     }
2472 }
2473 
SetWindowMode(sptr<WindowNode> & node,WindowMode dstMode)2474 WMError WindowNodeContainer::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
2475 {
2476     if (node == nullptr) {
2477         WLOGFE("could not find window");
2478         return WMError::WM_ERROR_NULLPTR;
2479     }
2480     WindowMode srcMode = node->GetWindowMode();
2481     if (WindowHelper::IsSplitWindowMode(dstMode) && isScreenLocked_ &&
2482         (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2483         return WMError::WM_ERROR_INVALID_PARAM;
2484     }
2485 
2486     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
2487     if (windowPair == nullptr) {
2488         WLOGFE("Window pair is nullptr");
2489         return WMError::WM_ERROR_NULLPTR;
2490     }
2491 
2492     WindowPairStatus status = windowPair->GetPairStatus();
2493     // when status is single primary or single secondary, split node is abandoned to set mode
2494     if (node->IsSplitMode() && (status == WindowPairStatus::SINGLE_PRIMARY ||
2495         status == WindowPairStatus::SINGLE_SECONDARY)) {
2496         return WMError::WM_ERROR_INVALID_OPERATION;
2497     }
2498     WMError res = WMError::WM_OK;
2499     UpdateSizeChangeReason(node, srcMode, dstMode);
2500     node->SetWindowMode(dstMode);
2501     windowPair->UpdateIfSplitRelated(node);
2502 
2503     if (WindowHelper::IsMainWindow(node->GetWindowType())) {
2504         if (WindowHelper::IsFloatingWindow(node->GetWindowMode())) {
2505             NotifyDockWindowStateChanged(node, true);
2506         } else {
2507             NotifyDockWindowStateChanged(node, false);
2508         }
2509     }
2510 
2511     if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2512         WindowHelper::IsAppWindow(node->GetWindowType())) {
2513         // minimize other app window.
2514         res = MinimizeStructuredAppWindowsExceptSelf(node);
2515         if (res != WMError::WM_OK) {
2516             return res;
2517         }
2518     }
2519     // when change mode, need to reset shadow and radius.
2520     WindowSystemEffect::SetWindowEffect(node);
2521 
2522     // when change mode, need to reset MainFloatingWindow ZOrder.
2523     ResetWindowZOrderPriorityWhenSetMode(node, dstMode, srcMode);
2524     MinimizeOldestMainFloatingWindow(node->GetWindowId());
2525 
2526     if (node->GetWindowToken() != nullptr) {
2527         node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2528     }
2529     res = UpdateWindowNode(node, WindowUpdateReason::UPDATE_MODE);
2530     if (res != WMError::WM_OK) {
2531         WLOGFE("Set window mode failed, update node failed");
2532         return res;
2533     }
2534     return WMError::WM_OK;
2535 }
2536 
ResetWindowZOrderPriorityWhenSetMode(sptr<WindowNode> & node,const WindowMode & dstMode,const WindowMode & srcMode)2537 void WindowNodeContainer::ResetWindowZOrderPriorityWhenSetMode(sptr<WindowNode>& node,
2538     const WindowMode& dstMode, const WindowMode& srcMode)
2539 {
2540     if (!isFloatWindowAboveFullWindow_) {
2541         return;
2542     }
2543 
2544     // reset node zorder priority.
2545     if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), srcMode)) {
2546         auto basePriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
2547         if (isScreenLocked_ &&
2548             (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2549             basePriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
2550         }
2551         node->priority_ = basePriority;
2552     }
2553 
2554     if (!WindowHelper::IsMainFloatingWindow(node->GetWindowType(), srcMode) &&
2555         !WindowHelper::IsMainFloatingWindow(node->GetWindowType(), dstMode) &&
2556         !WindowHelper::IsSplitWindowMode(srcMode) &&
2557         !WindowHelper::IsSplitWindowMode(dstMode)) {
2558         return;
2559     }
2560 
2561     // When set mode, all floating window should be checked and raise
2562     ResetAllMainFloatingWindowZOrder(node->parent_);
2563     if (node->parent_ != nullptr && node->GetWindowId() == focusedWindow_ &&
2564         WindowHelper::IsMainFloatingWindow(node->GetWindowType(), dstMode)) {
2565         // if current node is mainFloatingWIndow and foucsedWindow, it should be raised to top.
2566         RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
2567     }
2568     AssignZOrder();
2569 }
2570 
GetModeChangeHotZones(DisplayId displayId,ModeChangeHotZones & hotZones,const ModeChangeHotZonesConfig & config)2571 void WindowNodeContainer::GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones,
2572     const ModeChangeHotZonesConfig& config)
2573 {
2574     const auto& displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId);
2575 
2576     hotZones.fullscreen_.width_ = displayRect.width_;
2577     hotZones.fullscreen_.height_ = config.fullscreenRange_;
2578 
2579     hotZones.primary_.width_ = config.primaryRange_;
2580     hotZones.primary_.height_ = displayRect.height_;
2581 
2582     hotZones.secondary_.posX_ = static_cast<int32_t>(displayRect.width_) - config.secondaryRange_;
2583     hotZones.secondary_.width_ = config.secondaryRange_;
2584     hotZones.secondary_.height_ = displayRect.height_;
2585 }
2586 
UpdateCameraFloatWindowStatus(const sptr<WindowNode> & node,bool isShowing)2587 void WindowNodeContainer::UpdateCameraFloatWindowStatus(const sptr<WindowNode>& node, bool isShowing)
2588 {
2589     if (node->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2590         WindowManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(node->GetAccessTokenId(), isShowing);
2591     }
2592 }
2593 
GetCurrentLayoutMode() const2594 WindowLayoutMode WindowNodeContainer::GetCurrentLayoutMode() const
2595 {
2596     return layoutMode_;
2597 }
2598 
RemoveSingleUserWindowNodes(int accountId)2599 void WindowNodeContainer::RemoveSingleUserWindowNodes(int accountId)
2600 {
2601     std::vector<sptr<WindowNode>> windowNodes;
2602     TraverseContainer(windowNodes);
2603     WLOGI("%{public}d", accountId);
2604     for (auto& windowNode : windowNodes) {
2605         int windowAccountId = windowNode->GetCallingUid() / UID_TRANSFROM_DIVISOR;
2606         if (windowAccountId < UID_MIN || windowAccountId == accountId) {
2607             WLOGD("skiped window %{public}s, windowId %{public}d uid %{public}d",
2608                 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2609             continue;
2610         }
2611         WLOGD("remove window %{public}s, windowId %{public}d uid %{public}d",
2612             windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2613         windowNode->GetWindowProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
2614         if (windowNode->GetWindowToken()) {
2615             if (windowNode->surfaceNode_ != nullptr) {
2616                 windowNode->surfaceNode_->SetVisible(true);
2617             }
2618             windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_HIDDEN);
2619         }
2620     }
2621 }
2622 
TakeWindowPairSnapshot(DisplayId displayId)2623 bool WindowNodeContainer::TakeWindowPairSnapshot(DisplayId displayId)
2624 {
2625     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2626     return windowPair == nullptr ? false : windowPair->TakePairSnapshot();
2627 }
2628 
ClearWindowPairSnapshot(DisplayId displayId)2629 void WindowNodeContainer::ClearWindowPairSnapshot(DisplayId displayId)
2630 {
2631     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2632     if (windowPair == nullptr) {
2633         WLOGFE("Window pair is nullptr");
2634         return;
2635     }
2636     windowPair->ClearPairSnapshot();
2637 }
2638 
SetWindowPairFrameGravity(DisplayId displayId,Gravity gravity)2639 void WindowNodeContainer::SetWindowPairFrameGravity(DisplayId displayId, Gravity gravity)
2640 {
2641     auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2642     if (windowPair == nullptr) {
2643         WLOGFE("Window pair is nullptr");
2644         return;
2645     }
2646     std::vector<sptr<WindowNode>> windowNodes = windowPair->GetPairedWindows();
2647     for (auto& windowNode : windowNodes) {
2648         if (windowNode->surfaceNode_) {
2649             windowNode->surfaceNode_->SetFrameGravity(gravity);
2650         }
2651     }
2652 }
2653 
IsScreenLocked()2654 bool WindowNodeContainer::IsScreenLocked()
2655 {
2656     return isScreenLocked_;
2657 }
2658 
GetAnimateTransactionEnabled()2659 bool WindowNodeContainer::GetAnimateTransactionEnabled()
2660 {
2661     return isAnimateTransactionEnabled_;
2662 }
2663 } // namespace Rosen
2664 } // namespace OHOS
2665