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