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