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