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