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