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_root.h" 17#include <ability_manager_client.h> 18#include <cinttypes> 19#include <hisysevent.h> 20#include <hitrace_meter.h> 21#include <transaction/rs_transaction.h> 22 23#ifdef POWERMGR_DISPLAY_MANAGER_ENABLE 24#include <display_power_mgr_client.h> 25#endif 26 27#include "display_manager_service_inner.h" 28#include "permission.h" 29#include "window_helper.h" 30#include "window_inner_manager.h" 31#include "window_manager_hilog.h" 32#include "window_manager_service.h" 33#include "window_manager_service_utils.h" 34#include "window_manager_agent_controller.h" 35#include "window_system_effect.h" 36#ifdef MEMMGR_WINDOW_ENABLE 37#include "mem_mgr_client.h" 38#include "mem_mgr_window_info.h" 39#endif 40namespace OHOS { 41namespace Rosen { 42namespace { 43constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "Root"}; 44int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b) 45{ 46 return a.first < b.first; 47} 48} 49 50uint32_t WindowRoot::GetTotalWindowNum() const 51{ 52 return static_cast<uint32_t>(windowNodeMap_.size()); 53} 54 55sptr<WindowNode> WindowRoot::GetWindowForDumpAceHelpInfo() const 56{ 57 for (auto& iter : windowNodeMap_) { 58 if (iter.second->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP || 59 iter.second->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR || 60 iter.second->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || 61 iter.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) { 62 return iter.second; 63 } 64 } 65 return nullptr; 66} 67 68ScreenId WindowRoot::GetScreenGroupId(DisplayId displayId, bool& isRecordedDisplay) 69{ 70 for (auto iter : displayIdMap_) { 71 auto displayIdVec = iter.second; 72 if (std::find(displayIdVec.begin(), displayIdVec.end(), displayId) != displayIdVec.end()) { 73 isRecordedDisplay = true; 74 return iter.first; 75 } 76 } 77 isRecordedDisplay = false; 78 WLOGFE("Current display is not be recorded, displayId: %{public}" PRIu64 "", displayId); 79 return DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); 80} 81 82sptr<WindowNodeContainer> WindowRoot::GetOrCreateWindowNodeContainer(DisplayId displayId) 83{ 84 auto container = GetWindowNodeContainer(displayId); 85 if (container != nullptr) { 86 return container; 87 } 88 89 // In case of have no container for default display, create container 90 WLOGI("Create container for current display, displayId: %{public}" PRIu64 "", displayId); 91 sptr<DisplayInfo> displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); 92 DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); 93 return CreateWindowNodeContainer(defaultDisplayId, displayInfo); 94} 95 96sptr<WindowNodeContainer> WindowRoot::GetWindowNodeContainer(DisplayId displayId) 97{ 98 bool isRecordedDisplay; 99 ScreenId displayGroupId = GetScreenGroupId(displayId, isRecordedDisplay); 100 auto iter = windowNodeContainerMap_.find(displayGroupId); 101 if (iter != windowNodeContainerMap_.end()) { 102 // if container exist for screenGroup and display is not be recorded, process expand display 103 if (!isRecordedDisplay) { 104 sptr<DisplayInfo> displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); 105 // add displayId in displayId vector 106 displayIdMap_[displayGroupId].push_back(displayId); 107 auto displayRectMap = GetAllDisplayRectsByDMS(displayInfo); 108 DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); 109 ProcessExpandDisplayCreate(defaultDisplayId, displayInfo, displayRectMap); 110 } 111 return iter->second; 112 } 113 return nullptr; 114} 115 116sptr<WindowNodeContainer> WindowRoot::CreateWindowNodeContainer(DisplayId defaultDisplayId, 117 sptr<DisplayInfo> displayInfo) 118{ 119 if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) { 120 WLOGFE("get display failed or get invalid display info"); 121 return nullptr; 122 } 123 124 DisplayGroupInfo::GetInstance().SetDefaultDisplayId(defaultDisplayId); 125 DisplayId displayId = displayInfo->GetDisplayId(); 126 ScreenId displayGroupId = displayInfo->GetScreenGroupId(); 127 WLOGI("create new container for display, width: %{public}d, height: %{public}d, " 128 "displayGroupId:%{public}" PRIu64", displayId:%{public}" PRIu64"", displayInfo->GetWidth(), 129 displayInfo->GetHeight(), displayGroupId, displayId); 130 sptr<WindowNodeContainer> container = new WindowNodeContainer(displayInfo, displayGroupId); 131 windowNodeContainerMap_.insert(std::make_pair(displayGroupId, container)); 132 std::vector<DisplayId> displayVec = { displayId }; 133 displayIdMap_.insert(std::make_pair(displayGroupId, displayVec)); 134 if (container == nullptr) { 135 WLOGFE("create container failed, displayId :%{public}" PRIu64 "", displayId); 136 return nullptr; 137 } 138 container->GetDisplayGroupController()->SetSplitRatioConfig(splitRatioConfig_); 139 return container; 140} 141 142bool WindowRoot::CheckDisplayInfo(const sptr<DisplayInfo>& display) 143{ 144 const int32_t minWidth = 50; 145 const int32_t minHeight = 50; 146 const int32_t maxWidth = 7680; 147 const int32_t maxHeight = 7680; // 8k resolution 148 if (display->GetWidth() < minWidth || display->GetWidth() > maxWidth || 149 display->GetHeight() < minHeight || display->GetHeight() > maxHeight) { 150 return false; 151 } 152 return true; 153} 154 155sptr<WindowNode> WindowRoot::GetWindowNode(uint32_t windowId) const 156{ 157 auto iter = windowNodeMap_.find(windowId); 158 if (iter == windowNodeMap_.end()) { 159 return nullptr; 160 } 161 return iter->second; 162} 163 164sptr<WindowNode> WindowRoot::GetWindowNodeByMissionId(uint32_t missionId) const 165{ 166 using ValueType = const std::map<uint32_t, sptr<WindowNode>>::value_type&; 167 auto it = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(), [missionId] (ValueType item) { 168 return item.second && item.second->abilityInfo_.missionId_ == static_cast<int32_t>(missionId); 169 }); 170 return it == windowNodeMap_.end() ? nullptr : it->second; 171} 172 173void WindowRoot::GetBackgroundNodesByScreenId(ScreenId screenGroupId, std::vector<sptr<WindowNode>>& windowNodes) 174{ 175 for (const auto& it : windowNodeMap_) { 176 if (it.second == nullptr) { 177 continue; 178 } 179 wptr<WindowNodeContainer> container = GetWindowNodeContainer(it.second->GetDisplayId()); 180 if (container == nullptr) { 181 continue; 182 } 183 auto iter = std::find_if(windowNodeContainerMap_.begin(), windowNodeContainerMap_.end(), 184 [container](const std::map<uint64_t, sptr<WindowNodeContainer>>::value_type& containerPair) { 185 return container.promote() == containerPair.second; 186 }); 187 ScreenId screenGroupIdOfNode = INVALID_SCREEN_ID; 188 if (iter != windowNodeContainerMap_.end()) { 189 screenGroupIdOfNode = iter->first; 190 } 191 if (screenGroupId == screenGroupIdOfNode && !it.second->currentVisibility_) { 192 windowNodes.push_back(it.second); 193 } 194 } 195} 196 197void WindowRoot::GetForegroundNodes(std::vector<sptr<WindowNode>>& windowNodes) 198{ 199 for (const auto& it : windowNodeMap_) { 200 if (it.second == nullptr) { 201 continue; 202 } 203 if (it.second->currentVisibility_) { 204 windowNodes.push_back(it.second); 205 } 206 } 207} 208 209sptr<WindowNode> WindowRoot::FindWindowNodeWithToken(const sptr<IRemoteObject>& token) const 210{ 211 if (token == nullptr) { 212 WLOGFE("token is null"); 213 return nullptr; 214 } 215 auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(), 216 [token](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) { 217 if ((WindowHelper::IsMainWindow(pair.second->GetWindowType())) || 218 (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP)) { 219 return pair.second->abilityToken_ == token; 220 } 221 return false; 222 }); 223 if (iter == windowNodeMap_.end()) { 224 WLOGE("cannot find windowNode"); 225 return nullptr; 226 } 227 return iter->second; 228} 229 230void WindowRoot::AddDeathRecipient(sptr<WindowNode> node) 231{ 232 if (node == nullptr || node->GetWindowToken() == nullptr) { 233 WLOGFE("failed, node is nullptr"); 234 return; 235 } 236 WLOGFD("Add for window: %{public}u", node->GetWindowId()); 237 238 auto remoteObject = node->GetWindowToken()->AsObject(); 239 windowIdMap_.insert(std::make_pair(remoteObject, node->GetWindowId())); 240 241 if (windowDeath_ == nullptr) { 242 WLOGE("failed to create death Recipient ptr WindowDeathRecipient"); 243 return; 244 } 245 if (!remoteObject->AddDeathRecipient(windowDeath_)) { 246 WLOGE("failed to add death recipient"); 247 } 248} 249 250WMError WindowRoot::SaveWindow(const sptr<WindowNode>& node) 251{ 252 if (node == nullptr) { 253 WLOGFE("add window failed, node is nullptr"); 254 return WMError::WM_ERROR_NULLPTR; 255 } 256 257 WLOGFD("save windowId %{public}u", node->GetWindowId()); 258 windowNodeMap_.insert(std::make_pair(node->GetWindowId(), node)); 259 if (node->surfaceNode_ != nullptr) { 260 surfaceIdWindowNodeMap_.insert(std::make_pair(node->surfaceNode_->GetId(), node)); 261 if (WindowHelper::IsMainWindow(node->GetWindowType())) { 262 // Register FirstFrame Callback to rs, inform ability to get snapshot 263 wptr<WindowNode> weak = node; 264 auto firstFrameCompleteCallback = [weak]() { 265 auto weakNode = weak.promote(); 266 if (weakNode == nullptr) { 267 WLOGFE("windowNode is nullptr"); 268 return; 269 } 270 WindowInnerManager::GetInstance().CompleteFirstFrameDrawing(weakNode); 271 }; 272 node->surfaceNode_->SetBufferAvailableCallback(firstFrameCompleteCallback); 273 } 274 } 275 AddDeathRecipient(node); 276 if (WindowHelper::IsMainWindow(node->GetWindowType())) { 277 WindowInfoReporter::GetInstance().InsertCreateReportInfo(node->abilityInfo_.bundleName_); 278 } 279 return WMError::WM_OK; 280} 281 282WMError WindowRoot::MinimizeStructuredAppWindowsExceptSelf(sptr<WindowNode>& node) 283{ 284 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "root:MinimizeStructuredAppWindowsExceptSelf"); 285 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 286 if (container == nullptr) { 287 WLOGFE("MinimizeAbility failed, window container could not be found"); 288 return WMError::WM_ERROR_NULLPTR; 289 } 290 return container->MinimizeStructuredAppWindowsExceptSelf(node); 291} 292 293void WindowRoot::MinimizeTargetWindows(std::vector<uint32_t>& windowIds) 294{ 295 for (auto& windowId : windowIds) { 296 if (windowNodeMap_.count(windowId) != 0) { 297 auto windowNode = windowNodeMap_[windowId]; 298 if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) { 299 MinimizeApp::AddNeedMinimizeApp(windowNode, MinimizeReason::GESTURE_ANIMATION); 300 } else { 301 WLOGFE("Minimize window failed id: %{public}u, type: %{public}u", 302 windowNode->GetWindowId(), static_cast<uint32_t>(windowNode->GetWindowType())); 303 } 304 } else { 305 WLOGFW("Cannot find window with id: %{public}u", windowId); 306 } 307 } 308} 309 310std::vector<sptr<WindowNode>> WindowRoot::GetSplitScreenWindowNodes(DisplayId displayId) 311{ 312 auto container = GetOrCreateWindowNodeContainer(displayId); 313 if (container == nullptr) { 314 return {}; 315 } 316 auto displayGroupController = container->GetDisplayGroupController(); 317 if (displayGroupController == nullptr) { 318 return {}; 319 } 320 auto windowPair = displayGroupController->GetWindowPairByDisplayId(displayId); 321 if (windowPair == nullptr) { 322 return {}; 323 } 324 return windowPair->GetPairedWindows(); 325} 326 327bool WindowRoot::IsForbidDockSliceMove(DisplayId displayId) const 328{ 329 auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId); 330 if (container == nullptr) { 331 WLOGFE("can't find container"); 332 return true; 333 } 334 return container->IsForbidDockSliceMove(displayId); 335} 336 337bool WindowRoot::IsDockSliceInExitSplitModeArea(DisplayId displayId) const 338{ 339 auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId); 340 if (container == nullptr) { 341 WLOGFE("can't find container"); 342 return false; 343 } 344 return container->IsDockSliceInExitSplitModeArea(displayId); 345} 346 347void WindowRoot::ExitSplitMode(DisplayId displayId) 348{ 349 auto container = GetOrCreateWindowNodeContainer(displayId); 350 if (container == nullptr) { 351 WLOGFE("can't find container"); 352 return; 353 } 354 container->ExitSplitMode(displayId); 355} 356 357void WindowRoot::AddSurfaceNodeIdWindowNodePair(uint64_t surfaceNodeId, sptr<WindowNode> node) 358{ 359 surfaceIdWindowNodeMap_.insert(std::make_pair(surfaceNodeId, node)); 360} 361 362static void FillUnreliableWindowInfo(const sptr<WindowNode>& windowNode, 363 std::vector<sptr<UnreliableWindowInfo>>& infos) 364{ 365 if (windowNode == nullptr) { 366 WLOGFW("null window node."); 367 return; 368 } 369 sptr<UnreliableWindowInfo> info = new (std::nothrow) UnreliableWindowInfo(); 370 if (info == nullptr) { 371 WLOGFE("null info."); 372 return; 373 } 374 info->windowId_ = static_cast<int32_t>(windowNode->GetWindowId()); 375 info->windowRect_ = windowNode->GetWindowRect(); 376 info->zOrder_ = windowNode->zOrder_; 377 infos.emplace_back(info); 378 WLOGFI("windowId = %{public}d", info->windowId_); 379} 380 381static bool CheckUnreliableWindowType(WindowType windowType) 382{ 383 if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW || 384 windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || 385 windowType == WindowType::WINDOW_TYPE_TOAST) { 386 return true; 387 } 388 WLOGFI("false, WindowType = %{public}d", windowType); 389 return false; 390} 391 392void WindowRoot::GetUnreliableWindowInfo(int32_t windowId, std::vector<sptr<UnreliableWindowInfo>>& infos) const 393{ 394 WLOGFD("Called."); 395 for (const auto& [winId, windowNode] : windowNodeMap_) { 396 if (windowNode == nullptr) { 397 WLOGFW("null window node"); 398 continue; 399 } 400 int32_t curWindowId = static_cast<int32_t>(winId); 401 if (curWindowId == windowId) { 402 WLOGFI("windowId: %{public}d is parameter chosen", curWindowId); 403 FillUnreliableWindowInfo(windowNode, infos); 404 continue; 405 } 406 if (!windowNode->currentVisibility_) { 407 WLOGFD("windowId: %{public}d is not visible", curWindowId); 408 continue; 409 } 410 WLOGFD("name = %{public}s, windowId = %{public}d, winType = %{public}d, " 411 "visible = %{public}d", windowNode->GetWindowName().c_str(), 412 curWindowId, windowNode->GetWindowType(), windowNode->currentVisibility_); 413 if (CheckUnreliableWindowType(windowNode->GetWindowType())) { 414 WLOGFI("windowId = %{public}d, WindowType = %{public}d", curWindowId, windowNode->GetWindowType()); 415 FillUnreliableWindowInfo(windowNode, infos); 416 } 417 } 418} 419 420void WindowRoot::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos) const 421{ 422 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) { 423 WLOGFE("Get Visible Window Permission Denied"); 424 } 425 for (auto [surfaceId, _] : lastVisibleData_) { 426 auto iter = surfaceIdWindowNodeMap_.find(surfaceId); 427 if (iter == surfaceIdWindowNodeMap_.end()) { 428 continue; 429 } 430 sptr<WindowNode> node = iter->second; 431 if (node == nullptr) { 432 continue; 433 } 434 infos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(), 435 node->GetCallingUid(), node->GetVisibilityState(), node->GetWindowType())); 436 } 437} 438 439std::vector<std::pair<uint64_t, WindowVisibilityState>> WindowRoot::GetWindowVisibilityChangeInfo( 440 std::shared_ptr<RSOcclusionData> occlusionData) 441{ 442 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo; 443 VisibleData& rsVisibleData = occlusionData->GetVisibleData(); 444 std::vector<std::pair<uint64_t, WindowVisibilityState> > currVisibleData; 445 for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) { 446 if (static_cast<WindowLayerState>(iter->second) < WINDOW_LAYER_DRAWING) { 447 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second)); 448 } 449 } 450 std::sort(currVisibleData.begin(), currVisibleData.end(), Comp); 451 uint32_t i, j; 452 i = j = 0; 453 for (; i < lastVisibleData_.size() && j < currVisibleData.size();) { 454 if (lastVisibleData_[i].first < currVisibleData[j].first) { 455 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION); 456 i++; 457 } else if (lastVisibleData_[i].first > currVisibleData[j].first) { 458 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second); 459 j++; 460 } else { 461 if (lastVisibleData_[i].second != currVisibleData[j].second) { 462 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second); 463 } 464 i++; 465 j++; 466 } 467 } 468 for (; i < lastVisibleData_.size(); ++i) { 469 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION); 470 } 471 for (; j < currVisibleData.size(); ++j) { 472 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second); 473 } 474 lastVisibleData_ = currVisibleData; 475 return visibilityChangeInfo; 476} 477 478void WindowRoot::NotifyWindowVisibilityChange(std::shared_ptr<RSOcclusionData> occlusionData) 479{ 480 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo = 481 GetWindowVisibilityChangeInfo(occlusionData); 482 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos; 483#ifdef MEMMGR_WINDOW_ENABLE 484 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos; 485#endif 486 for (const auto& elem : visibilityChangeInfo) { 487 uint64_t surfaceId = elem.first; 488 WindowVisibilityState visibilityState = elem.second; 489 bool isVisible = visibilityState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION; 490 auto iter = surfaceIdWindowNodeMap_.find(surfaceId); 491 if (iter == surfaceIdWindowNodeMap_.end()) { 492 continue; 493 } 494 sptr<WindowNode> node = iter->second; 495 if (node == nullptr) { 496 continue; 497 } 498 node->SetVisibilityState(visibilityState); 499 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(), 500 node->GetCallingUid(), visibilityState, node->GetWindowType())); 501#ifdef MEMMGR_WINDOW_ENABLE 502 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(node->GetWindowId(), node->GetCallingPid(), 503 node->GetCallingUid(), isVisible)); 504#endif 505 WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, visibilityState:%{public}d", 506 node->GetWindowId(), visibilityState); 507 } 508 CheckAndNotifyWaterMarkChangedResult(); 509 if (windowVisibilityInfos.size() != 0) { 510 WLOGI("Notify windowvisibilityinfo changed start"); 511 WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos); 512 } 513#ifdef MEMMGR_WINDOW_ENABLE 514 if (memMgrWindowInfos.size() != 0) { 515 WLOGI("Notify memMgrWindowInfos changed start"); 516 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos); 517 } 518#endif 519} 520 521AvoidArea WindowRoot::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType avoidAreaType) 522{ 523 AvoidArea avoidArea; 524 sptr<WindowNode> node = GetWindowNode(windowId); 525 if (node == nullptr) { 526 WLOGFE("could not find window"); 527 return avoidArea; 528 } 529 sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 530 if (container == nullptr) { 531 WLOGFE("add window failed, window container could not be found"); 532 return avoidArea; 533 } 534 return container->GetAvoidAreaByType(node, avoidAreaType); 535} 536 537void WindowRoot::MinimizeAllAppWindows(DisplayId displayId) 538{ 539 auto container = GetOrCreateWindowNodeContainer(displayId); 540 if (container == nullptr) { 541 WLOGFE("can't find window node container, failed!"); 542 return; 543 } 544 return container->MinimizeAllAppWindows(displayId); 545} 546 547WMError WindowRoot::ToggleShownStateForAllAppWindows() 548{ 549 std::vector<DisplayId> displays = DisplayGroupInfo::GetInstance().GetAllDisplayIds(); 550 std::vector<sptr<WindowNodeContainer>> containers; 551 bool isAllAppWindowsEmpty = true; 552 for (auto displayId : displays) { 553 auto container = GetOrCreateWindowNodeContainer(displayId); 554 if (container == nullptr) { 555 WLOGFE("can't find window node container, failed!"); 556 continue; 557 } 558 containers.emplace_back(container); 559 isAllAppWindowsEmpty = isAllAppWindowsEmpty && container->IsAppWindowsEmpty(); 560 } 561 WMError res = WMError::WM_OK; 562 std::for_each(containers.begin(), containers.end(), 563 [this, isAllAppWindowsEmpty, &res] (sptr<WindowNodeContainer> container) { 564 auto restoreFunc = [this](uint32_t windowId, WindowMode mode) { 565 auto windowNode = GetWindowNode(windowId); 566 if (windowNode == nullptr) { 567 return false; 568 } 569 if (!windowNode->GetWindowToken()) { 570 return false; 571 } 572 auto property = windowNode->GetWindowToken()->GetWindowProperty(); 573 if (property == nullptr) { 574 return false; 575 } 576 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || 577 mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { 578 property->SetWindowMode(mode); 579 // when change mode, need to reset shadow and radius 580 windowNode->SetWindowMode(mode); 581 WindowSystemEffect::SetWindowEffect(windowNode); 582 windowNode->GetWindowToken()->RestoreSplitWindowMode(static_cast<uint32_t>(mode)); 583 } 584 windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_SHOWN); 585 WindowManagerService::GetInstance().AddWindow(property); 586 return true; 587 }; 588 WMError tmpRes = container->ToggleShownStateForAllAppWindows(restoreFunc, isAllAppWindowsEmpty); 589 res = (res == WMError::WM_OK) ? tmpRes : res; 590 }); 591 return res; 592} 593 594void WindowRoot::DestroyLeakStartingWindow() 595{ 596 WLOGFD("DestroyLeakStartingWindow is called"); 597 std::vector<uint32_t> destroyIds; 598 for (auto& iter : windowNodeMap_) { 599 if (iter.second->startingWindowShown_ && !iter.second->GetWindowToken()) { 600 destroyIds.push_back(iter.second->GetWindowId()); 601 } 602 } 603 for (auto& id : destroyIds) { 604 WLOGFD("Id:%{public}u", id); 605 DestroyWindow(id, false); 606 } 607} 608 609WMError WindowRoot::PostProcessAddWindowNode(sptr<WindowNode>& node, sptr<WindowNode>& parentNode, 610 sptr<WindowNodeContainer>& container) 611{ 612 if (!node->currentVisibility_) { 613 WLOGW("window is invisible, do not need process"); 614 return WMError::WM_DO_NOTHING; 615 } 616 if (WindowHelper::IsSubWindow(node->GetWindowType())) { 617 if (parentNode == nullptr) { 618 WLOGFE("window type is invalid"); 619 return WMError::WM_ERROR_INVALID_TYPE; 620 } 621 sptr<WindowNode> parent = nullptr; 622 container->RaiseZOrderForAppWindow(parentNode, parent); 623 } 624 if (node->GetWindowProperty()->GetFocusable()) { 625 // when launcher reboot, the focus window should not change with showing a full screen window. 626 sptr<WindowNode> focusWin = GetWindowNode(container->GetFocusWindow()); 627 if (focusWin == nullptr || 628 !(WindowHelper::IsFullScreenWindow(focusWin->GetWindowMode()) && focusWin->zOrder_ > node->zOrder_)) { 629 WLOGFI("set focus window on id:%{public}d", node->GetWindowId()); 630 container->SetFocusWindow(node->GetWindowId()); 631 container->DumpScreenWindowTree(); 632 needCheckFocusWindow = true; 633 } 634 } 635 if (!WindowHelper::IsSystemBarWindow(node->GetWindowType())) { 636 container->SetActiveWindow(node->GetWindowId(), false); 637 } 638 639 for (auto& child : node->children_) { 640 if (child == nullptr || !child->currentVisibility_) { 641 break; 642 } 643 HandleKeepScreenOn(child->GetWindowId(), child->IsKeepScreenOn()); 644 } 645 HandleKeepScreenOn(node->GetWindowId(), node->IsKeepScreenOn()); 646 WLOGFD("windowId:%{public}u, name:%{public}s, orientation:%{public}u, type:%{public}u, isMainWindow:%{public}d", 647 node->GetWindowId(), node->GetWindowName().c_str(), static_cast<uint32_t>(node->GetRequestedOrientation()), 648 node->GetWindowType(), WindowHelper::IsMainWindow(node->GetWindowType())); 649 if (WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) { 650 if (node->stateMachine_.IsShowAnimationPlaying()) { 651 WLOGFD("[FixOrientation] window is playing show animation, do not update display orientation"); 652 return WMError::WM_OK; 653 } 654 auto topRotatableWindow = container->GetNextRotatableWindow(INVALID_WINDOW_ID); 655 if (topRotatableWindow == node) { 656 container->SetDisplayOrientationFromWindow(node, true); 657 } 658 } 659 660 if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) { 661 std::vector<sptr<WindowNode>> windowNodes; 662 container->TraverseContainer(windowNodes); 663 for (auto& winNode : windowNodes) { 664 if (winNode && WindowHelper::IsMainWindow(winNode->GetWindowType()) && 665 winNode->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION && 666 winNode->GetWindowToken()) { 667 winNode->GetWindowToken()->NotifyForegroundInteractiveStatus(false); 668 } 669 } 670 } 671 672 return WMError::WM_OK; 673} 674 675bool WindowRoot::CheckAddingModeAndSize(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container) 676{ 677 if (!WindowHelper::IsMainWindow(node->GetWindowType())) { 678 return true; 679 } 680 // intercept the node which doesn't support floating mode at tile mode 681 if (WindowHelper::IsInvalidWindowInTileLayoutMode(node->GetModeSupportInfo(), container->GetCurrentLayoutMode())) { 682 WLOGFE("window doesn't support floating mode in tile, windowId: %{public}u", node->GetWindowId()); 683 return false; 684 } 685 // intercept the node that the tile rect can't be applied to 686 WMError res = container->IsTileRectSatisfiedWithSizeLimits(node); 687 if (res != WMError::WM_OK) { 688 return false; 689 } 690 return true; 691} 692 693Rect WindowRoot::GetDisplayRectWithoutSystemBarAreas(const sptr<WindowNode> dstNode) 694{ 695 DisplayId displayId = dstNode->GetDisplayId(); 696 std::map<WindowType, std::pair<bool, Rect>> systemBarRects; 697 for (const auto& it : windowNodeMap_) { 698 auto& node = it.second; 699 if (node && (node->GetDisplayId() == displayId) && 700 WindowHelper::IsSystemBarWindow(node->GetWindowType())) { 701 systemBarRects[node->GetWindowType()] = std::make_pair(node->currentVisibility_, node->GetWindowRect()); 702 } 703 } 704 auto container = GetOrCreateWindowNodeContainer(displayId); 705 if (container == nullptr) { 706 WLOGFE("failed, window container could not be found"); 707 return {0, 0, 0, 0}; // empty rect 708 } 709 auto displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId); 710 Rect targetRect = displayRect; 711 auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(displayId); 712 if (displayInfo && WmsUtils::IsExpectedRotatableWindow(dstNode->GetRequestedOrientation(), 713 displayInfo->GetDisplayOrientation(), dstNode->GetWindowMode(), dstNode->GetWindowFlags())) { 714 WLOGFD("[FixOrientation] the window is expected rotatable, pre-calculated"); 715 targetRect.height_ = displayRect.width_; 716 targetRect.width_ = displayRect.height_; 717 return targetRect; 718 } 719 720 bool isStatusShow = true; 721 if (systemBarRects.count(WindowType::WINDOW_TYPE_STATUS_BAR)) { 722 isStatusShow = systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].first; 723 targetRect.posY_ = displayRect.posY_ + static_cast<int32_t>( 724 systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].second.height_); 725 targetRect.height_ -= systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].second.height_; 726 WLOGFD("after status bar winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]", 727 targetRect.posX_, targetRect.posY_, targetRect.width_, targetRect.height_); 728 } 729 if (systemBarRects.count(WindowType::WINDOW_TYPE_NAVIGATION_BAR)) { 730 if (isStatusShow && !(systemBarRects[WindowType::WINDOW_TYPE_NAVIGATION_BAR].first)) { 731 return targetRect; 732 } 733 targetRect.height_ -= systemBarRects[WindowType::WINDOW_TYPE_NAVIGATION_BAR].second.height_; 734 WLOGFD("after navi bar winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]", 735 targetRect.posX_, targetRect.posY_, targetRect.width_, targetRect.height_); 736 } 737 return targetRect; 738} 739 740void WindowRoot::GetAllAnimationPlayingNodes(std::vector<wptr<WindowNode>>& windowNodes) 741{ 742 for (const auto& it : windowNodeMap_) { 743 if (it.second) { 744 if (!WindowHelper::IsMainWindow(it.second->GetWindowType())) { 745 continue; 746 } 747 WLOGFD("id:%{public}u state:%{public}u", 748 it.second->GetWindowId(), static_cast<uint32_t>(it.second->stateMachine_.GetCurrentState())); 749 if (it.second->stateMachine_.IsRemoteAnimationPlaying() || 750 it.second->stateMachine_.GetAnimationCount() > 0) { 751 windowNodes.emplace_back(it.second); 752 } 753 } 754 } 755} 756 757void WindowRoot::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool afterAnimation) 758{ 759 if (node == nullptr) { 760 WLOGFE("failed, node is nullptr"); 761 return; 762 } 763 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 764 if (container == nullptr) { 765 WLOGFE("add window failed, window container could not be found"); 766 return; 767 } 768 769 if (!CheckAddingModeAndSize(node, container)) { // true means stop adding 770 WLOGFE("Invalid mode or size in tile mode, windowId: %{public}u", node->GetWindowId()); 771 return; 772 } 773 774 container->LayoutWhenAddWindowNode(node, afterAnimation); 775 return; 776} 777 778WMError WindowRoot::BindDialogToParent(sptr<WindowNode>& node, sptr<WindowNode>& parentNode) 779{ 780 if (node->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) { 781 return WMError::WM_OK; 782 } 783 sptr<WindowNode> callerNode = FindMainWindowWithToken(node->dialogTargetToken_); 784 parentNode = (callerNode != nullptr) ? callerNode : nullptr; 785 if (parentNode == nullptr) { 786 node->GetWindowToken()->NotifyDestroy(); 787 return WMError::WM_ERROR_INVALID_PARAM; 788 } 789 return WMError::WM_OK; 790} 791 792WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr<WindowNode>& node, bool fromStartingWin) 793{ 794 if (node == nullptr) { 795 return WMError::WM_ERROR_NULLPTR; 796 } 797 798 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 799 if (container == nullptr) { 800 return WMError::WM_ERROR_INVALID_DISPLAY; 801 } 802 803 if (!CheckAddingModeAndSize(node, container)) { // true means stop adding 804 /* 805 * Starting Window has no windowToken, which should be destroied if mode or size is invalid 806 */ 807 if (node->GetWindowToken() == nullptr) { 808 (void)DestroyWindow(node->GetWindowId(), false); 809 } 810 WLOGFE("Invalid mode or size in tile mode, windowId: %{public}u", node->GetWindowId()); 811 return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE; 812 } 813 814 if (fromStartingWin) { 815 if (WindowHelper::IsFullScreenWindow(node->GetWindowMode()) && 816 WindowHelper::IsAppWindow(node->GetWindowType()) && !node->isPlayAnimationShow_) { 817 WMError res = MinimizeStructuredAppWindowsExceptSelf(node); 818 if (res != WMError::WM_OK) { 819 WLOGFE("Minimize other structured window failed"); 820 MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW); 821 return res; 822 } 823 } 824 WMError res = container->ShowStartingWindow(node); 825 if (res != WMError::WM_OK) { 826 MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW); 827 } 828 return res; 829 } 830 if (WindowHelper::IsAppFullOrSplitWindow(node->GetWindowType(), node->GetWindowMode())) { 831 container->NotifyDockWindowStateChanged(node, false); 832 } 833 // limit number of main window 834 uint32_t mainWindowNumber = container->GetWindowCountByType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); 835 if (mainWindowNumber >= maxAppWindowNumber_ && node->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) { 836 container->MinimizeOldestAppWindow(); 837 } 838 839 auto parentNode = GetWindowNode(parentId); 840 841 WMError res = BindDialogToParent(node, parentNode); 842 if (res != WMError::WM_OK) { 843 return res; 844 } 845 846 res = container->AddWindowNode(node, parentNode); 847 if (res != WMError::WM_OK) { 848 WLOGFE("failed with ret: %{public}u", static_cast<uint32_t>(res)); 849 return res; 850 } 851 return PostProcessAddWindowNode(node, parentNode, container); 852} 853 854WMError WindowRoot::RemoveWindowNode(uint32_t windowId, bool fromAnimation) 855{ 856 WLOGFD("begin"); 857 auto node = GetWindowNode(windowId); 858 if (node == nullptr) { 859 WLOGFE("could not find window"); 860 return WMError::WM_ERROR_NULLPTR; 861 } 862 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 863 if (container == nullptr) { 864 WLOGFE("failed, window container could not be found"); 865 return WMError::WM_ERROR_INVALID_DISPLAY; 866 } 867 container->DropShowWhenLockedWindowIfNeeded(node); 868 UpdateFocusWindowWithWindowRemoved(node, container); 869 UpdateActiveWindowWithWindowRemoved(node, container); 870 UpdateBrightnessWithWindowRemoved(windowId, container); 871 WMError res = container->RemoveWindowNode(node, fromAnimation); 872 if (res == WMError::WM_OK) { 873 for (auto& child : node->children_) { 874 if (child == nullptr) { 875 break; 876 } 877 HandleKeepScreenOn(child->GetWindowId(), false); 878 } 879 HandleKeepScreenOn(windowId, false); 880 } 881 882 if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) { 883 std::vector<sptr<WindowNode>> windowNodes; 884 container->TraverseContainer(windowNodes); 885 for (auto& winNode : windowNodes) { 886 if (winNode && WindowHelper::IsMainWindow(winNode->GetWindowType()) && 887 winNode->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION && 888 winNode->GetWindowToken()) { 889 winNode->GetWindowToken()->NotifyForegroundInteractiveStatus(true); 890 } 891 } 892 } 893 894 return res; 895} 896 897void WindowRoot::UpdateDisplayOrientationWhenHideWindow(sptr<WindowNode>& node) 898{ 899 if (!FIX_ORIENTATION_ENABLE) { 900 return; 901 } 902 WLOGFD("[FixOrientation] begin"); 903 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 904 if (container == nullptr) { 905 WLOGFE("[FixOrientation] failed, window container could not be found"); 906 return; 907 } 908 auto nextRotatableWindow = container->GetNextRotatableWindow(node->GetWindowId()); 909 if (nextRotatableWindow != nullptr) { 910 WLOGFD("[FixOrientation] next rotatable window: %{public}u", nextRotatableWindow->GetWindowId()); 911 container->SetDisplayOrientationFromWindow(nextRotatableWindow, false); 912 } 913} 914 915WMError WindowRoot::SetGestureNavigationEnabled(bool enable) 916{ 917 if (lastGestureNativeEnabled_ == enable) { 918 WLOGFW("Do not set gesture navigation too much times as same value and the value is %{public}d", enable); 919 return WMError::WM_DO_NOTHING; 920 } 921 WindowManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable); 922 lastGestureNativeEnabled_ = enable; 923 WLOGFD("Set gesture navigation enabled succeeded and notify result of %{public}d", enable); 924 return WMError::WM_OK; 925} 926 927WMError WindowRoot::UpdateWindowNode(uint32_t windowId, WindowUpdateReason reason) 928{ 929 auto node = GetWindowNode(windowId); 930 if (node == nullptr) { 931 WLOGFE("could not find window"); 932 return WMError::WM_ERROR_NULLPTR; 933 } 934 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 935 if (container == nullptr) { 936 WLOGFE("update window failed, window container could not be found"); 937 return WMError::WM_ERROR_INVALID_DISPLAY; 938 } 939 940 auto ret = container->UpdateWindowNode(node, reason); 941 if (ret == WMError::WM_OK && reason == WindowUpdateReason::UPDATE_FLAGS) { 942 CheckAndNotifyWaterMarkChangedResult(); 943 } 944 return ret; 945} 946 947WMError WindowRoot::UpdateSizeChangeReason(uint32_t windowId, WindowSizeChangeReason reason) 948{ 949 auto node = GetWindowNode(windowId); 950 if (node == nullptr) { 951 WLOGFE("could not find window"); 952 return WMError::WM_ERROR_NULLPTR; 953 } 954 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 955 if (container == nullptr) { 956 WLOGFE("failed, window container could not be found"); 957 return WMError::WM_ERROR_INVALID_DISPLAY; 958 } 959 container->UpdateSizeChangeReason(node, reason); 960 return WMError::WM_OK; 961} 962 963void WindowRoot::SetBrightness(uint32_t windowId, float brightness) 964{ 965 auto node = GetWindowNode(windowId); 966 if (node == nullptr) { 967 WLOGFE("could not find window"); 968 return; 969 } 970 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 971 if (container == nullptr) { 972 WLOGFE("failed, window container could not be found"); 973 return; 974 } 975 if (!WindowHelper::IsAppWindow(node->GetWindowType())) { 976 WLOGW("Only app window support set brightness"); 977 return; 978 } 979 if (windowId != container->GetActiveWindow()) { 980 WLOGE("Window is not active with windowId:%{public}d", windowId); 981 return; 982 } 983 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) <= std::numeric_limits<float>::min()) { 984 if (std::fabs(container->GetDisplayBrightness() - brightness) > std::numeric_limits<float>::min()) { 985 WLOGFI("value: %{public}f to restore brightness", brightness); 986#ifdef POWERMGR_DISPLAY_MANAGER_ENABLE 987 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness(); 988#endif 989 container->SetDisplayBrightness(brightness); 990 } 991 } else { 992 if (std::fabs(container->GetDisplayBrightness() - brightness) > std::numeric_limits<float>::min()) { 993 WLOGFI("value: %{public}u", container->ToOverrideBrightness(brightness)); 994#ifdef POWERMGR_DISPLAY_MANAGER_ENABLE 995 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness( 996 container->ToOverrideBrightness(brightness)); 997#endif 998 container->SetDisplayBrightness(brightness); 999 } 1000 } 1001 container->SetBrightnessWindow(windowId); 1002} 1003 1004void WindowRoot::HandleKeepScreenOn(uint32_t windowId, bool requireLock) 1005{ 1006 auto node = GetWindowNode(windowId); 1007 if (node == nullptr) { 1008 WLOGFE("could not find window"); 1009 return; 1010 } 1011 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1012 if (container == nullptr) { 1013 WLOGFE("failed, window container could not be found"); 1014 return; 1015 } 1016 container->HandleKeepScreenOn(node, requireLock); 1017} 1018 1019void WindowRoot::UpdateFocusableProperty(uint32_t windowId) 1020{ 1021 auto node = GetWindowNode(windowId); 1022 if (node == nullptr) { 1023 WLOGFE("could not find window"); 1024 return; 1025 } 1026 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1027 if (container == nullptr) { 1028 WLOGFE("failed, window container could not be found"); 1029 return; 1030 } 1031 1032 if (windowId != container->GetFocusWindow() || node->GetWindowProperty()->GetFocusable()) { 1033 return; 1034 } 1035 auto nextFocusableWindow = container->GetNextFocusableWindow(windowId); 1036 if (nextFocusableWindow != nullptr) { 1037 WLOGI("Next focus window id: %{public}u", nextFocusableWindow->GetWindowId()); 1038 container->SetFocusWindow(nextFocusableWindow->GetWindowId()); 1039 } 1040} 1041 1042WMError WindowRoot::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode) 1043{ 1044 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1045 if (container == nullptr) { 1046 WLOGFE("failed, window container could not be found"); 1047 return WMError::WM_ERROR_INVALID_DISPLAY; 1048 } 1049 WindowMode curWinMode = node->GetWindowMode(); 1050 if (curWinMode == dstMode) { 1051 return WMError::WM_OK; 1052 } 1053 auto res = container->SetWindowMode(node, dstMode); 1054 auto nextRotatableWindow = container->GetNextRotatableWindow(0); 1055 if (nextRotatableWindow != nullptr) { 1056 DisplayManagerServiceInner::GetInstance().SetOrientationFromWindow(nextRotatableWindow->GetDisplayId(), 1057 nextRotatableWindow->GetRequestedOrientation()); 1058 } 1059 return res; 1060} 1061 1062WMError WindowRoot::DestroyWindowSelf(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container) 1063{ 1064 for (auto& child : node->children_) { 1065 if (child == nullptr) { 1066 continue; 1067 } 1068 child->parent_ = nullptr; 1069 if ((child->GetWindowToken() != nullptr) && (child->abilityToken_ != node->abilityToken_) && 1070 (child->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) { 1071 child->GetWindowToken()->NotifyDestroy(); 1072 } 1073 } 1074 std::vector<uint32_t> windowIds; 1075 WMError res = container->DestroyWindowNode(node, windowIds); 1076 if (res != WMError::WM_OK) { 1077 WLOGFE("RemoveWindowNode failed"); 1078 } 1079 return DestroyWindowInner(node); 1080} 1081 1082WMError WindowRoot::DestroyWindowWithChild(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container) 1083{ 1084 auto token = node->abilityToken_; 1085 std::vector<uint32_t> windowIds; 1086 WMError res = container->DestroyWindowNode(node, windowIds); 1087 for (auto id : windowIds) { 1088 node = GetWindowNode(id); 1089 if (!node) { 1090 continue; 1091 } 1092 HandleKeepScreenOn(id, false); 1093 DestroyWindowInner(node); 1094 if ((node->GetWindowToken() != nullptr) && (node->abilityToken_ != token) && 1095 (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) { 1096 node->GetWindowToken()->NotifyDestroy(); 1097 } 1098 } 1099 return res; 1100} 1101 1102WMError WindowRoot::DestroyWindow(uint32_t windowId, bool onlySelf) 1103{ 1104 auto node = GetWindowNode(windowId); 1105 if (node == nullptr) { 1106 WLOGFE("failed, because window node is not exist."); 1107 return WMError::WM_ERROR_NULLPTR; 1108 } 1109 WLOGI("windowId %{public}u, onlySelf:%{public}u.", windowId, onlySelf); 1110 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1111 if (!container) { 1112 WLOGFW("failed, window container could not be found"); 1113 return DestroyWindowInner(node); 1114 } 1115 1116 UpdateFocusWindowWithWindowRemoved(node, container); 1117 UpdateActiveWindowWithWindowRemoved(node, container); 1118 UpdateBrightnessWithWindowRemoved(windowId, container); 1119 HandleKeepScreenOn(windowId, false); 1120 if (onlySelf) { 1121 return DestroyWindowSelf(node, container); 1122 } else { 1123 return DestroyWindowWithChild(node, container); 1124 } 1125} 1126 1127WMError WindowRoot::DestroyWindowInner(sptr<WindowNode>& node) 1128{ 1129 if (node == nullptr) { 1130 WLOGFE("window has been destroyed"); 1131 return WMError::WM_ERROR_DESTROYED_OBJECT; 1132 } 1133 1134 if (node->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) { 1135 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos; 1136 node->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION); 1137 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(), 1138 node->GetCallingUid(), node->GetVisibilityState(), node->GetWindowType())); 1139 WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, visibilityState:%{public}d", 1140 node->GetWindowId(), node->GetVisibilityState()); 1141 WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos); 1142 1143 CheckAndNotifyWaterMarkChangedResult(); 1144 } 1145 1146 auto cmpFunc = [node](const std::map<uint64_t, sptr<WindowNode>>::value_type& pair) { 1147 if (pair.second == nullptr) { 1148 return false; 1149 } 1150 if (pair.second->GetWindowId() == node->GetWindowId()) { 1151 return true; 1152 } 1153 return false; 1154 }; 1155 auto iter = std::find_if(surfaceIdWindowNodeMap_.begin(), surfaceIdWindowNodeMap_.end(), cmpFunc); 1156 if (iter != surfaceIdWindowNodeMap_.end()) { 1157 surfaceIdWindowNodeMap_.erase(iter); 1158 } 1159 1160 sptr<IWindow> window = node->GetWindowToken(); 1161 if ((window != nullptr) && (window->AsObject() != nullptr)) { 1162 if (windowIdMap_.count(window->AsObject()) == 0) { 1163 WLOGE("window remote object has been destroyed"); 1164 return WMError::WM_ERROR_DESTROYED_OBJECT; 1165 } 1166 1167 if (window->AsObject() != nullptr) { 1168 window->AsObject()->RemoveDeathRecipient(windowDeath_); 1169 } 1170 windowIdMap_.erase(window->AsObject()); 1171 } 1172 windowNodeMap_.erase(node->GetWindowId()); 1173 WLOGI("destroy window use_count:%{public}d", node->GetSptrRefCount()); 1174 return WMError::WM_OK; 1175} 1176 1177void WindowRoot::UpdateFocusWindowWithWindowRemoved(const sptr<WindowNode>& node, 1178 const sptr<WindowNodeContainer>& container) const 1179{ 1180 if (node == nullptr || container == nullptr) { 1181 WLOGFE("window is invalid"); 1182 return; 1183 } 1184 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { 1185 WLOGI("window is divider, do not get next focus window."); 1186 return; 1187 } 1188 uint32_t windowId = node->GetWindowId(); 1189 uint32_t focusedWindowId = container->GetFocusWindow(); 1190 WLOGFI("current window: %{public}u, focus window: %{public}u", windowId, focusedWindowId); 1191 container->DumpScreenWindowTree(); 1192 if (windowId != focusedWindowId) { 1193 auto iter = std::find_if(node->children_.begin(), node->children_.end(), 1194 [focusedWindowId](sptr<WindowNode> node) { 1195 return node->GetWindowId() == focusedWindowId; 1196 }); 1197 if (iter == node->children_.end()) { 1198 return; 1199 } 1200 } 1201 if (!node->children_.empty()) { 1202 auto firstChild = node->children_.front(); 1203 if (firstChild->priority_ < 0) { 1204 windowId = firstChild->GetWindowId(); 1205 } 1206 } 1207 1208 auto nextFocusableWindow = container->GetNextFocusableWindow(windowId); 1209 if (nextFocusableWindow != nullptr) { 1210 WLOGFI("adjust focus window, next focus window id: %{public}u", nextFocusableWindow->GetWindowId()); 1211 container->SetFocusWindow(nextFocusableWindow->GetWindowId()); 1212 } else { 1213 WLOGFW("next focus window is invalid"); 1214 container->SetFocusWindow(INVALID_WINDOW_ID); 1215 } 1216} 1217 1218void WindowRoot::UpdateActiveWindowWithWindowRemoved(const sptr<WindowNode>& node, 1219 const sptr<WindowNodeContainer>& container) const 1220{ 1221 if (node == nullptr || container == nullptr) { 1222 WLOGFE("window is invalid"); 1223 return; 1224 } 1225 uint32_t windowId = node->GetWindowId(); 1226 uint32_t activeWindowId = container->GetActiveWindow(); 1227 WLOGFD("current window: %{public}u, active window: %{public}u", windowId, activeWindowId); 1228 if (windowId != activeWindowId) { 1229 auto iter = std::find_if(node->children_.begin(), node->children_.end(), 1230 [activeWindowId](sptr<WindowNode> node) { 1231 return node->GetWindowId() == activeWindowId; 1232 }); 1233 if (iter == node->children_.end()) { 1234 return; 1235 } 1236 } 1237 if (!node->children_.empty()) { 1238 auto firstChild = node->children_.front(); 1239 if (firstChild->priority_ < 0) { 1240 windowId = firstChild->GetWindowId(); 1241 } 1242 } 1243 1244 auto nextActiveWindow = container->GetNextActiveWindow(windowId); 1245 if (nextActiveWindow != nullptr) { 1246 WLOGI("Next active window id: %{public}u", nextActiveWindow->GetWindowId()); 1247 container->SetActiveWindow(nextActiveWindow->GetWindowId(), true); 1248 } 1249} 1250 1251void WindowRoot::UpdateBrightnessWithWindowRemoved(uint32_t windowId, const sptr<WindowNodeContainer>& container) const 1252{ 1253 if (container == nullptr) { 1254 WLOGFE("window container could not be found"); 1255 return; 1256 } 1257 if (windowId == container->GetBrightnessWindow()) { 1258 WLOGFD("winId: %{public}u", container->GetActiveWindow()); 1259 container->UpdateBrightness(container->GetActiveWindow(), true); 1260 } 1261} 1262 1263bool WindowRoot::IsVerticalDisplay(sptr<WindowNode>& node) const 1264{ 1265 auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1266 if (container == nullptr) { 1267 WLOGFE("get display direction failed, window container could not be found"); 1268 return false; 1269 } 1270 return container->IsVerticalDisplay(node->GetDisplayId()); 1271} 1272 1273WMError WindowRoot::RequestFocus(uint32_t windowId) 1274{ 1275 auto node = GetWindowNode(windowId); 1276 if (node == nullptr) { 1277 WLOGFE("could not find window"); 1278 return WMError::WM_ERROR_NULLPTR; 1279 } 1280 if (!node->currentVisibility_) { 1281 WLOGFE("could not request focus before it does not be shown"); 1282 return WMError::WM_ERROR_INVALID_OPERATION; 1283 } 1284 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1285 if (container == nullptr) { 1286 WLOGFE("window container could not be found"); 1287 return WMError::WM_ERROR_NULLPTR; 1288 } 1289 if (node->GetWindowProperty()->GetFocusable()) { 1290 return container->SetFocusWindow(windowId); 1291 } 1292 return WMError::WM_ERROR_INVALID_OPERATION; 1293} 1294 1295WMError WindowRoot::RequestActiveWindow(uint32_t windowId) 1296{ 1297 auto node = GetWindowNode(windowId); 1298 if (node == nullptr) { 1299 WLOGFE("could not find window"); 1300 return WMError::WM_ERROR_NULLPTR; 1301 } 1302 if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) { 1303 WLOGFE("window could not be active window"); 1304 return WMError::WM_ERROR_INVALID_TYPE; 1305 } 1306 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1307 if (container == nullptr) { 1308 WLOGFE("window container could not be found"); 1309 return WMError::WM_ERROR_NULLPTR; 1310 } 1311 auto res = container->SetActiveWindow(windowId, false); 1312 WLOGFD("windowId:%{public}u, name:%{public}s, orientation:%{public}u, type:%{public}u, isMainWindow:%{public}d", 1313 windowId, node->GetWindowName().c_str(), static_cast<uint32_t>(node->GetRequestedOrientation()), 1314 node->GetWindowType(), WindowHelper::IsMainWindow(node->GetWindowType())); 1315 return res; 1316} 1317 1318void WindowRoot::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason) 1319{ 1320 for (auto& elem : windowNodeContainerMap_) { 1321 if (elem.second == nullptr) { 1322 continue; 1323 } 1324 elem.second->ProcessWindowStateChange(state, reason); 1325 } 1326} 1327 1328void WindowRoot::NotifySystemBarTints() 1329{ 1330 WLOGFD("notify current system bar tints"); 1331 for (auto& it : windowNodeContainerMap_) { 1332 if (it.second != nullptr) { 1333 it.second->NotifySystemBarTints(displayIdMap_[it.first]); 1334 } 1335 } 1336} 1337 1338WMError WindowRoot::NotifyDesktopUnfrozen() 1339{ 1340 WLOGFD("notify desktop unfrozen"); 1341 for (const auto& it : windowNodeMap_) { 1342 auto& node = it.second; 1343 // just need notify desktop unfrozen when desktop shown 1344 // since unfrozen will change window state to shown 1345 if (node && (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) 1346 && (node->GetWindowToken()) && node->currentVisibility_) { 1347 node->GetWindowToken()->UpdateWindowState(WindowState::STATE_UNFROZEN); 1348 return WMError::WM_OK; 1349 } 1350 } 1351 WLOGFD("notify desktop unfrozen failed, maybe no window node or windowToken!"); 1352 return WMError::WM_ERROR_INVALID_OPERATION; 1353} 1354 1355sptr<WindowNode> WindowRoot::FindWallpaperWindow() 1356{ 1357 auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(), 1358 [](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) { 1359 return pair.second->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER; 1360 }); 1361 if (iter == windowNodeMap_.end()) { 1362 WLOGI("cannot find windowNode"); 1363 return nullptr; 1364 } 1365 return iter->second; 1366} 1367 1368WMError WindowRoot::RaiseZOrderForAppWindow(sptr<WindowNode>& node) 1369{ 1370 if (node == nullptr) { 1371 WLOGFW("add window failed, node is nullptr"); 1372 return WMError::WM_ERROR_NULLPTR; 1373 } 1374 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { 1375 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1376 if (container == nullptr) { 1377 WLOGFW("window container could not be found"); 1378 return WMError::WM_ERROR_NULLPTR; 1379 } 1380 container->RaiseSplitRelatedWindowToTop(node); 1381 return WMError::WM_OK; 1382 } 1383 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) { 1384 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1385 if (container == nullptr) { 1386 WLOGFW("window container could not be found"); 1387 return WMError::WM_ERROR_NULLPTR; 1388 } 1389 sptr<WindowNode> parentNode = FindMainWindowWithToken(node->dialogTargetToken_); 1390 if (parentNode != nullptr) { 1391 container->RaiseZOrderForAppWindow(node, parentNode); 1392 } 1393 return WMError::WM_OK; 1394 } 1395 1396 if (!WindowHelper::IsAppWindow(node->GetWindowType())) { 1397 WLOGFW("window is not app window"); 1398 return WMError::WM_ERROR_INVALID_TYPE; 1399 } 1400 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1401 if (container == nullptr) { 1402 WLOGFW("add window failed, window container could not be found"); 1403 return WMError::WM_ERROR_NULLPTR; 1404 } 1405 1406 auto parentNode = GetWindowNode(node->GetParentId()); 1407 return container->RaiseZOrderForAppWindow(node, parentNode); 1408} 1409 1410void WindowRoot::DispatchKeyEvent(sptr<WindowNode> node, std::shared_ptr<MMI::KeyEvent> event) 1411{ 1412 sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1413 if (container == nullptr) { 1414 WLOGFW("window container could not be found"); 1415 return; 1416 } 1417 std::vector<sptr<WindowNode>> windowNodes; 1418 container->TraverseContainer(windowNodes); 1419 auto iter = std::find(windowNodes.begin(), windowNodes.end(), node); 1420 if (iter == windowNodes.end()) { 1421 WLOGFE("Cannot find node"); 1422 return; 1423 } 1424 for (++iter; iter != windowNodes.end(); ++iter) { 1425 if (*iter == nullptr) { 1426 WLOGFE("Node is null"); 1427 continue; 1428 } 1429 if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) { 1430 WLOGFI("Skip component window: %{public}u", (*iter)->GetWindowId()); 1431 continue; 1432 } 1433 if (WindowHelper::IsAppWindow((*iter)->GetWindowType())) { 1434 WLOGFI("App window: %{public}u", (*iter)->GetWindowId()); 1435 if ((*iter)->GetWindowToken()) { 1436 (*iter)->GetWindowToken()->ConsumeKeyEvent(event); 1437 } 1438 break; 1439 } 1440 WLOGFI("Unexpected window: %{public}u", (*iter)->GetWindowId()); 1441 break; 1442 } 1443} 1444 1445uint32_t WindowRoot::GetWindowIdByObject(const sptr<IRemoteObject>& remoteObject) 1446{ 1447 auto iter = windowIdMap_.find(remoteObject); 1448 return iter == std::end(windowIdMap_) ? INVALID_WINDOW_ID : iter->second; 1449} 1450 1451void WindowRoot::OnRemoteDied(const sptr<IRemoteObject>& remoteObject) 1452{ 1453 callback_(Event::REMOTE_DIED, remoteObject); 1454} 1455 1456WMError WindowRoot::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) 1457{ 1458 if (windowNodeMap_.find(mainWinId) == windowNodeMap_.end()) { 1459 return WMError::WM_ERROR_INVALID_WINDOW; 1460 } 1461 auto node = windowNodeMap_[mainWinId]; 1462 if (!node->currentVisibility_) { 1463 return WMError::WM_ERROR_INVALID_WINDOW; 1464 } 1465 if (!node->children_.empty()) { 1466 auto iter = node->children_.rbegin(); 1467 if (WindowHelper::IsSubWindow((*iter)->GetWindowType()) || 1468 WindowHelper::IsSystemSubWindow((*iter)->GetWindowType())) { 1469 topWinId = (*iter)->GetWindowId(); 1470 return WMError::WM_OK; 1471 } 1472 } 1473 topWinId = mainWinId; 1474 return WMError::WM_OK; 1475} 1476 1477WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) 1478{ 1479 auto container = GetOrCreateWindowNodeContainer(displayId); 1480 if (container == nullptr) { 1481 WLOGFE("window container could not be found"); 1482 return WMError::WM_ERROR_NULLPTR; 1483 } 1484 WMError ret = container->SwitchLayoutPolicy(mode, displayId, true); 1485 if (ret != WMError::WM_OK) { 1486 WLOGFW("set window layout mode failed displayId: %{public}" PRIu64 ", ret: %{public}d", displayId, ret); 1487 } 1488 return ret; 1489} 1490 1491std::vector<DisplayId> WindowRoot::GetAllDisplayIds() const 1492{ 1493 std::vector<DisplayId> displayIds; 1494 for (auto& it : windowNodeContainerMap_) { 1495 if (!it.second) { 1496 return {}; 1497 } 1498 std::vector<DisplayId>& displayIdVec = const_cast<WindowRoot*>(this)->displayIdMap_[it.first]; 1499 for (auto displayId : displayIdVec) { 1500 displayIds.push_back(displayId); 1501 } 1502 } 1503 return displayIds; 1504} 1505 1506std::string WindowRoot::GenAllWindowsLogInfo() const 1507{ 1508 std::ostringstream os; 1509 WindowNodeOperationFunc func = [&os](sptr<WindowNode> node) { 1510 if (node == nullptr) { 1511 WLOGE("WindowNode is nullptr"); 1512 return false; 1513 } 1514 os<<"window_name:"<<node->GetWindowName()<<",id:"<<node->GetWindowId()<< 1515 ",focusable:"<<node->GetWindowProperty()->GetFocusable()<<";"; 1516 return false; 1517 }; 1518 1519 for (auto& elem : windowNodeContainerMap_) { 1520 if (elem.second == nullptr) { 1521 continue; 1522 } 1523 std::vector<DisplayId>& displayIdVec = const_cast<WindowRoot*>(this)->displayIdMap_[elem.first]; 1524 for (const auto& displayId : displayIdVec) { 1525 os << "Display " << displayId << ":"; 1526 } 1527 elem.second->TraverseWindowTree(func, true); 1528 } 1529 return os.str(); 1530} 1531 1532void WindowRoot::FocusFaultDetection() const 1533{ 1534 if (!needCheckFocusWindow) { 1535 return; 1536 } 1537 bool needReport = true; 1538 uint32_t focusWinId = INVALID_WINDOW_ID; 1539 for (auto& elem : windowNodeContainerMap_) { 1540 if (elem.second == nullptr) { 1541 continue; 1542 } 1543 focusWinId = elem.second->GetFocusWindow(); 1544 if (focusWinId != INVALID_WINDOW_ID) { 1545 needReport = false; 1546 sptr<WindowNode> windowNode = GetWindowNode(focusWinId); 1547 if (windowNode == nullptr || !windowNode->currentVisibility_) { 1548 needReport = true; 1549 WLOGFE("The focus windowNode is nullptr or is invisible, focusWinId: %{public}u", focusWinId); 1550 break; 1551 } 1552 } 1553 } 1554 if (needReport) { 1555 std::string windowLog(GenAllWindowsLogInfo()); 1556 WLOGFE("The focus window is faulty, focusWinId:%{public}u, %{public}s", focusWinId, windowLog.c_str()); 1557 int32_t ret = HiSysEventWrite( 1558 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER, 1559 "NO_FOCUS_WINDOW", 1560 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, 1561 "PID", getpid(), 1562 "UID", getuid(), 1563 "PACKAGE_NAME", "foundation", 1564 "PROCESS_NAME", "foundation", 1565 "MSG", windowLog); 1566 if (ret != 0) { 1567 WLOGFE("Write HiSysEvent error, ret:%{public}d", ret); 1568 } 1569 } 1570} 1571 1572void WindowRoot::ProcessExpandDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 1573 std::map<DisplayId, Rect>& displayRectMap) 1574{ 1575 if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) { 1576 WLOGFE("get display failed or get invalid display info"); 1577 return; 1578 } 1579 DisplayGroupInfo::GetInstance().SetDefaultDisplayId(defaultDisplayId); 1580 DisplayId displayId = displayInfo->GetDisplayId(); 1581 ScreenId displayGroupId = displayInfo->GetScreenGroupId(); 1582 auto container = windowNodeContainerMap_[displayGroupId]; 1583 if (container == nullptr) { 1584 WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); 1585 return; 1586 } 1587 1588 container->GetDisplayGroupController()->ProcessDisplayCreate(defaultDisplayId, displayInfo, displayRectMap); 1589 container->GetDisplayGroupController()->SetSplitRatioConfig(splitRatioConfig_); 1590 WLOGI("Container exist, add new display, displayId: %{public}" PRIu64"", displayId); 1591} 1592 1593std::map<DisplayId, Rect> WindowRoot::GetAllDisplayRectsByDMS(sptr<DisplayInfo> displayInfo) 1594{ 1595 std::map<DisplayId, Rect> displayRectMap; 1596 1597 if (displayInfo == nullptr) { 1598 return displayRectMap; 1599 } 1600 1601 for (auto& displayId : displayIdMap_[displayInfo->GetScreenGroupId()]) { 1602 auto info = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); 1603 Rect displayRect = { info->GetOffsetX(), info->GetOffsetY(), info->GetWidth(), info->GetHeight() }; 1604 displayRectMap.insert(std::make_pair(displayId, displayRect)); 1605 1606 WLOGI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]", 1607 displayId, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_); 1608 } 1609 return displayRectMap; 1610} 1611 1612std::map<DisplayId, Rect> WindowRoot::GetAllDisplayRectsByDisplayInfo( 1613 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap) 1614{ 1615 std::map<DisplayId, Rect> displayRectMap; 1616 1617 for (const auto& iter : displayInfoMap) { 1618 auto id = iter.first; 1619 auto info = iter.second; 1620 Rect displayRect = { info->GetOffsetX(), info->GetOffsetY(), info->GetWidth(), info->GetHeight() }; 1621 displayRectMap.insert(std::make_pair(id, displayRect)); 1622 1623 WLOGI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]", 1624 id, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_); 1625 } 1626 return displayRectMap; 1627} 1628 1629void WindowRoot::ProcessDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 1630 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap) 1631{ 1632 DisplayId displayId = (displayInfo == nullptr) ? DISPLAY_ID_INVALID : displayInfo->GetDisplayId(); 1633 ScreenId displayGroupId = (displayInfo == nullptr) ? SCREEN_ID_INVALID : displayInfo->GetScreenGroupId(); 1634 auto iter = windowNodeContainerMap_.find(displayGroupId); 1635 if (iter == windowNodeContainerMap_.end()) { 1636 CreateWindowNodeContainer(defaultDisplayId, displayInfo); 1637 WLOGI("Create new container for display, displayId: %{public}" PRIu64"", displayId); 1638 } else { 1639 auto& displayIdVec = displayIdMap_[displayGroupId]; 1640 if (std::find(displayIdVec.begin(), displayIdVec.end(), displayId) != displayIdVec.end()) { 1641 WLOGI("Current display is already exist, displayId: %{public}" PRIu64"", displayId); 1642 return; 1643 } 1644 // add displayId in displayId vector 1645 displayIdMap_[displayGroupId].push_back(displayId); 1646 auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap); 1647 ProcessExpandDisplayCreate(defaultDisplayId, displayInfo, displayRectMap); 1648 } 1649} 1650 1651void WindowRoot::MoveNotShowingWindowToDefaultDisplay(DisplayId defaultDisplayId, DisplayId displayId) 1652{ 1653 for (auto& elem : windowNodeMap_) { 1654 auto& windowNode = elem.second; 1655 if (windowNode->GetDisplayId() == displayId && !windowNode->currentVisibility_) { 1656 std::vector<DisplayId> newShowingDisplays = { defaultDisplayId }; 1657 windowNode->SetShowingDisplays(newShowingDisplays); 1658 windowNode->isShowingOnMultiDisplays_ = false; 1659 if (windowNode->GetWindowToken()) { 1660 windowNode->GetWindowToken()->UpdateDisplayId(windowNode->GetDisplayId(), defaultDisplayId); 1661 } 1662 windowNode->SetDisplayId(defaultDisplayId); 1663 } 1664 } 1665} 1666 1667void WindowRoot::ProcessDisplayDestroy(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 1668 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap) 1669{ 1670 DisplayId displayId = (displayInfo == nullptr) ? DISPLAY_ID_INVALID : displayInfo->GetDisplayId(); 1671 ScreenId displayGroupId = (displayInfo == nullptr) ? SCREEN_ID_INVALID : displayInfo->GetScreenGroupId(); 1672 auto& displayIdVec = displayIdMap_[displayGroupId]; 1673 1674 auto iter = windowNodeContainerMap_.find(displayGroupId); 1675 if (iter == windowNodeContainerMap_.end() || 1676 std::find(displayIdVec.begin(), displayIdVec.end(), displayId) == displayIdVec.end() || 1677 displayInfoMap.find(displayId) == displayInfoMap.end()) { 1678 WLOGFE("could not find display, destroy failed, displayId: %{public}" PRIu64"", displayId); 1679 return; 1680 } 1681 1682 // erase displayId in displayIdMap 1683 auto displayIter = std::remove(displayIdVec.begin(), displayIdVec.end(), displayId); 1684 displayIdVec.erase(displayIter, displayIdVec.end()); 1685 1686 // container process display destroy 1687 auto container = iter->second; 1688 if (container == nullptr) { 1689 WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); 1690 return; 1691 } 1692 WLOGI("displayId: %{public}" PRIu64"", displayId); 1693 1694 std::vector<uint32_t> needDestroyWindows; 1695 auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap); 1696 // erase displayId in displayRectMap 1697 auto displayRectIter = displayRectMap.find(displayId); 1698 if (displayRectIter == displayRectMap.end()) { 1699 return; 1700 } 1701 displayRectMap.erase(displayRectIter); 1702 container->GetDisplayGroupController()->ProcessDisplayDestroy( 1703 defaultDisplayId, displayInfo, displayRectMap, needDestroyWindows); 1704 for (auto id : needDestroyWindows) { 1705 auto node = GetWindowNode(id); 1706 if (node != nullptr) { 1707 DestroyWindowInner(node); 1708 } 1709 } 1710 // move window which is not showing on destroyed display to default display 1711 MoveNotShowingWindowToDefaultDisplay(defaultDisplayId, displayId); 1712 WLOGI("[Display Destroy] displayId: %{public}" PRIu64" ", displayId); 1713} 1714 1715void WindowRoot::ProcessDisplayChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 1716 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type) 1717{ 1718 if (displayInfo == nullptr) { 1719 WLOGFE("get display failed"); 1720 return; 1721 } 1722 DisplayId displayId = displayInfo->GetDisplayId(); 1723 ScreenId displayGroupId = displayInfo->GetScreenGroupId(); 1724 auto& displayIdVec = displayIdMap_[displayGroupId]; 1725 auto iter = windowNodeContainerMap_.find(displayGroupId); 1726 if (iter == windowNodeContainerMap_.end() || std::find(displayIdVec.begin(), 1727 displayIdVec.end(), displayId) == displayIdVec.end()) { 1728 WLOGFE("[Display Change] could not find display, change failed, displayId: %{public}" PRIu64"", displayId); 1729 return; 1730 } 1731 // container process display change 1732 auto container = iter->second; 1733 if (container == nullptr) { 1734 WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); 1735 return; 1736 } 1737 1738 auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap); 1739 container->GetDisplayGroupController()->ProcessDisplayChange(defaultDisplayId, displayInfo, displayRectMap, type); 1740} 1741 1742Rect WindowRoot::GetDisplayGroupRect(DisplayId displayId) const 1743{ 1744 Rect fullDisplayRect; 1745 auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId); 1746 if (container == nullptr) { 1747 WLOGFE("window container could not be found"); 1748 return fullDisplayRect; 1749 } 1750 return container->GetDisplayGroupRect(); 1751} 1752 1753bool WindowRoot::HasPrivateWindow(DisplayId displayId) 1754{ 1755 auto container = GetWindowNodeContainer(displayId); 1756 return container != nullptr ? container->HasPrivateWindow() : false; 1757} 1758 1759bool WindowRoot::HasMainFullScreenWindowShown(DisplayId displayId) 1760{ 1761 auto container = GetWindowNodeContainer(displayId); 1762 return container != nullptr ? container->HasMainFullScreenWindowShown() : false; 1763} 1764 1765void WindowRoot::SetMaxAppWindowNumber(uint32_t windowNum) 1766{ 1767 maxAppWindowNumber_ = windowNum; 1768} 1769 1770void WindowRoot::SetSplitRatios(const std::vector<float>& splitRatioNumbers) 1771{ 1772 auto& splitRatios = splitRatioConfig_.splitRatios; 1773 splitRatios.clear(); 1774 splitRatios = splitRatioNumbers; 1775 for (auto iter = splitRatios.begin(); iter != splitRatios.end();) { 1776 if (*iter > 0 && *iter < 1) { // valid ratio range (0, 1) 1777 iter++; 1778 } else { 1779 iter = splitRatios.erase(iter); 1780 } 1781 } 1782 std::sort(splitRatios.begin(), splitRatios.end()); 1783 auto iter = std::unique(splitRatios.begin(), splitRatios.end()); 1784 splitRatios.erase(iter, splitRatios.end()); // remove duplicate ratios 1785} 1786 1787void WindowRoot::SetExitSplitRatios(const std::vector<float>& exitSplitRatios) 1788{ 1789 if (exitSplitRatios.size() != 2) { // 2 is size of vector. 1790 return; 1791 } 1792 if (exitSplitRatios[0] > 0 && exitSplitRatios[0] < DEFAULT_SPLIT_RATIO) { 1793 splitRatioConfig_.exitSplitStartRatio = exitSplitRatios[0]; 1794 } 1795 if (exitSplitRatios[1] > DEFAULT_SPLIT_RATIO && exitSplitRatios[1] < 1) { 1796 splitRatioConfig_.exitSplitEndRatio = exitSplitRatios[1]; 1797 } 1798} 1799 1800WMError WindowRoot::GetModeChangeHotZones(DisplayId displayId, 1801 ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config) 1802{ 1803 auto container = GetOrCreateWindowNodeContainer(displayId); 1804 if (container == nullptr) { 1805 WLOGFE("GetModeChangeHotZones failed, window container could not be found"); 1806 return WMError::WM_ERROR_NULLPTR; 1807 } 1808 container->GetModeChangeHotZones(displayId, hotZones, config); 1809 return WMError::WM_OK; 1810} 1811 1812void WindowRoot::RemoveSingleUserWindowNodes(int accountId) 1813{ 1814 std::vector<DisplayId> displayIds = GetAllDisplayIds(); 1815 for (auto id : displayIds) { 1816 sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(id); 1817 if (container == nullptr) { 1818 WLOGW("get container failed %{public}" PRIu64"", id); 1819 continue; 1820 } 1821 container->RemoveSingleUserWindowNodes(accountId); 1822 } 1823} 1824 1825WMError WindowRoot::UpdateRsTree(uint32_t windowId, bool isAdd) 1826{ 1827 sptr<WindowNode> node = GetWindowNode(windowId); 1828 if (node == nullptr) { 1829 WLOGFE("could not find window"); 1830 return WMError::WM_ERROR_NULLPTR; 1831 } 1832 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1833 if (container == nullptr) { 1834 WLOGFE("window container could not be found"); 1835 return WMError::WM_ERROR_NULLPTR; 1836 } 1837 for (auto& displayId : node->GetShowingDisplays()) { 1838 if (isAdd) { 1839 container->AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE); 1840 } else { 1841 container->RemoveNodeFromRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE); 1842 } 1843 } 1844 RSTransaction::FlushImplicitTransaction(); 1845 return WMError::WM_OK; 1846} 1847 1848sptr<WindowNode> WindowRoot::FindMainWindowWithToken(sptr<IRemoteObject> token) 1849{ 1850 auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(), 1851 [token](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) { 1852 if (WindowHelper::IsMainWindow(pair.second->GetWindowType())) { 1853 return pair.second->abilityToken_ == token; 1854 } 1855 return false; 1856 }); 1857 if (iter == windowNodeMap_.end()) { 1858 WLOGI("cannot find windowNode"); 1859 return nullptr; 1860 } 1861 return iter->second; 1862} 1863 1864bool WindowRoot::CheckMultiDialogWindows(WindowType type, sptr<IRemoteObject> token) 1865{ 1866 if (type != WindowType::WINDOW_TYPE_DIALOG) { 1867 return false; 1868 } 1869 1870 sptr<WindowNode> newCaller, oriCaller; 1871 1872 newCaller = FindMainWindowWithToken(token); 1873 if (newCaller == nullptr) { 1874 return false; 1875 } 1876 1877 for (auto& iter : windowNodeMap_) { 1878 if (iter.second->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) { 1879 oriCaller = FindMainWindowWithToken(iter.second->dialogTargetToken_); 1880 if (oriCaller == newCaller) { 1881 return true; 1882 } 1883 } 1884 } 1885 1886 return false; 1887} 1888 1889sptr<WindowNode> WindowRoot::GetWindowNodeByAbilityToken(const sptr<IRemoteObject>& abilityToken) 1890{ 1891 for (const auto& iter : windowNodeMap_) { 1892 if (iter.second != nullptr && iter.second->abilityToken_ == abilityToken) { 1893 return iter.second; 1894 } 1895 } 1896 WLOGFE("could not find required abilityToken!"); 1897 return nullptr; 1898} 1899 1900bool WindowRoot::TakeWindowPairSnapshot(DisplayId displayId) 1901{ 1902 auto container = GetWindowNodeContainer(displayId); 1903 return container == nullptr ? false : container->TakeWindowPairSnapshot(displayId); 1904} 1905 1906void WindowRoot::ClearWindowPairSnapshot(DisplayId displayId) 1907{ 1908 auto container = GetWindowNodeContainer(displayId); 1909 if (container == nullptr) { 1910 WLOGFE("clear window pair snapshot failed, because container in null"); 1911 return; 1912 } 1913 return container->ClearWindowPairSnapshot(displayId); 1914} 1915 1916void WindowRoot::CheckAndNotifyWaterMarkChangedResult() 1917{ 1918 auto searchWaterMarkWindow = [](wptr<WindowNode> node) { 1919 return (node != nullptr && node->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION && 1920 (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK))); 1921 }; 1922 bool currentWaterMarkState = false; 1923 for (auto& containerPair : windowNodeContainerMap_) { 1924 auto container = containerPair.second; 1925 if (container == nullptr) { 1926 continue; 1927 } 1928 std::vector<sptr<WindowNode>> allWindowNode; 1929 container->TraverseContainer(allWindowNode); 1930 auto itor = std::find_if(allWindowNode.begin(), allWindowNode.end(), searchWaterMarkWindow); 1931 if (itor != allWindowNode.end()) { 1932 currentWaterMarkState = true; 1933 break; 1934 } 1935 } 1936 if (lastWaterMarkShowStates_ != currentWaterMarkState) { 1937 WLOGFD("WaterMarkWindows has been changed. lastWaterMarkState : %{public}d, newState:%{public}d", 1938 lastWaterMarkShowStates_, currentWaterMarkState); 1939 WindowManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(currentWaterMarkState); 1940 lastWaterMarkShowStates_ = currentWaterMarkState; 1941 } 1942} 1943} // namespace Rosen 1944} // namespace OHOS 1945