1 /* 2 * Copyright (c) 2022-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 #include "display_group_controller.h" 16 17 #include "window_helper.h" 18 #include "window_inner_manager.h" 19 #include "window_manager_hilog.h" 20 #include "window_node_container.h" 21 22 namespace OHOS { 23 namespace Rosen { 24 namespace { 25 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DisplayGroupController"}; 26 } 27 InitNewDisplay(DisplayId displayId)28 void DisplayGroupController::InitNewDisplay(DisplayId displayId) 29 { 30 // system bar map for display 31 SysBarNodeMap sysBarNodeMap { 32 { WindowType::WINDOW_TYPE_STATUS_BAR, nullptr }, 33 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, nullptr }, 34 }; 35 sysBarNodeMaps_.insert(std::make_pair(displayId, sysBarNodeMap)); 36 37 SysBarTintMap sysBarTintMap { 38 { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarRegionTint() }, 39 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarRegionTint() }, 40 }; 41 sysBarTintMaps_.insert(std::make_pair(displayId, sysBarTintMap)); 42 43 // window node maps for display 44 std::map<WindowRootNodeType, std::unique_ptr<std::vector<sptr<WindowNode>>>> displayWindowTree; 45 displayWindowTree.insert(std::make_pair(WindowRootNodeType::APP_WINDOW_NODE, 46 std::make_unique<std::vector<sptr<WindowNode>>>())); 47 displayWindowTree.insert(std::make_pair(WindowRootNodeType::ABOVE_WINDOW_NODE, 48 std::make_unique<std::vector<sptr<WindowNode>>>())); 49 displayWindowTree.insert(std::make_pair(WindowRootNodeType::BELOW_WINDOW_NODE, 50 std::make_unique<std::vector<sptr<WindowNode>>>())); 51 displayGroupWindowTree_.insert(std::make_pair(displayId, std::move(displayWindowTree))); 52 53 // window pair for display 54 auto windowPair = new WindowPair(displayId); 55 windowPairMap_.insert(std::make_pair(displayId, windowPair)); 56 } 57 GetWindowNodesByDisplayIdAndRootType(DisplayId displayId,WindowRootNodeType type)58 std::vector<sptr<WindowNode>>* DisplayGroupController::GetWindowNodesByDisplayIdAndRootType(DisplayId displayId, 59 WindowRootNodeType type) 60 { 61 if (displayGroupWindowTree_.find(displayId) != displayGroupWindowTree_.end()) { 62 auto& displayWindowTree = displayGroupWindowTree_[displayId]; 63 if (displayWindowTree.find(type) != displayWindowTree.end()) { 64 return displayWindowTree[type].get(); 65 } 66 } 67 return nullptr; 68 } 69 AddWindowNodeOnWindowTree(sptr<WindowNode> & node,WindowRootNodeType rootType)70 void DisplayGroupController::AddWindowNodeOnWindowTree(sptr<WindowNode>& node, WindowRootNodeType rootType) 71 { 72 std::vector<sptr<WindowNode>>* rootNodeVectorPtr = GetWindowNodesByDisplayIdAndRootType(node->GetDisplayId(), 73 rootType); 74 if (rootNodeVectorPtr != nullptr) { 75 rootNodeVectorPtr->push_back(node); 76 WLOGFD("add node in node vector of root, displayId: %{public}" PRIu64" windowId: %{public}d, " 77 "rootType: %{public}d", node->GetDisplayId(), node->GetWindowId(), rootType); 78 } else { 79 WLOGFE("add node failed, rootNode vector is empty, windowId: %{public}d, rootType: %{public}d", 80 node->GetWindowId(), rootType); 81 } 82 } 83 UpdateDisplayGroupWindowTree()84 void DisplayGroupController::UpdateDisplayGroupWindowTree() 85 { 86 // clear ori window tree of displayGroup 87 for (auto& elem : displayGroupWindowTree_) { 88 for (auto& nodeVec : elem.second) { 89 auto emptyVector = std::vector<sptr<WindowNode>>(); 90 nodeVec.second->swap(emptyVector); 91 } 92 } 93 std::vector<WindowRootNodeType> rootNodeType = { 94 WindowRootNodeType::ABOVE_WINDOW_NODE, 95 WindowRootNodeType::APP_WINDOW_NODE, 96 WindowRootNodeType::BELOW_WINDOW_NODE 97 }; 98 for (auto& rootType : rootNodeType) { 99 auto rootNode = windowNodeContainer_->GetRootNode(rootType); 100 if (rootNode == nullptr) { 101 WLOGFE("rootNode is nullptr, %{public}d", rootType); 102 continue; 103 } 104 for (auto& node : rootNode->children_) { 105 AddWindowNodeOnWindowTree(node, rootType); 106 } 107 } 108 } 109 ProcessCrossNodes(DisplayId defaultDisplayId,DisplayStateChangeType type)110 void DisplayGroupController::ProcessCrossNodes(DisplayId defaultDisplayId, DisplayStateChangeType type) 111 { 112 defaultDisplayId_ = defaultDisplayId; 113 for (auto& iter : displayGroupWindowTree_) { 114 auto nodeVec = *(iter.second[WindowRootNodeType::APP_WINDOW_NODE]); 115 for (auto node : nodeVec) { 116 if (node->isShowingOnMultiDisplays_) { 117 WLOGFD("process cross node, windowId: %{public}u, displayId: %{public}" PRIu64"", 118 node->GetWindowId(), node->GetDisplayId()); 119 auto showingDisplays = node->GetShowingDisplays(); 120 121 DisplayId newDisplayId; 122 if (type == DisplayStateChangeType::SIZE_CHANGE || 123 type == DisplayStateChangeType::UPDATE_ROTATION || 124 type == DisplayStateChangeType::DISPLAY_COMPRESS || 125 type == DisplayStateChangeType::UPDATE_ROTATION_FROM_WINDOW) { 126 newDisplayId = node->GetDisplayId(); 127 } else { 128 newDisplayId = defaultDisplayId; 129 } 130 131 for (auto& displayId : showingDisplays) { 132 if (displayId == newDisplayId) { 133 continue; 134 } 135 windowNodeContainer_->RemoveNodeFromRSTree(node, displayId, newDisplayId, 136 WindowUpdateType::WINDOW_UPDATE_ACTIVE); 137 } 138 // update shown displays and displayId 139 MoveCrossNodeToTargetDisplay(node, newDisplayId); 140 } 141 } 142 } 143 } 144 UpdateWindowShowingDisplays(const sptr<WindowNode> & node)145 void DisplayGroupController::UpdateWindowShowingDisplays(const sptr<WindowNode>& node) 146 { 147 auto& displayGroupInfo = DisplayGroupInfo::GetInstance(); 148 auto leftDisplayId = displayGroupInfo.GetLeftDisplayId(); 149 auto rightDisplayId = displayGroupInfo.GetRightDisplayId(); 150 auto displayRectMap = displayGroupInfo.GetAllDisplayRects(); 151 auto showingDisplays = std::vector<DisplayId>(); 152 const auto& winRect = node->GetWindowRect(); 153 for (auto& elem : displayRectMap) { 154 auto& curDisplayRect = elem.second; 155 156 // if window is showing in display region 157 if (((winRect.posX_ + static_cast<int32_t>(winRect.width_)) > curDisplayRect.posX_) && 158 (winRect.posX_ < (curDisplayRect.posX_ + static_cast<int32_t>(curDisplayRect.width_)))) { 159 showingDisplays.push_back(elem.first); 160 } 161 } 162 163 // if window is not showing on any display, maybe in the left of minPosX display, or the right of maxPosX display 164 if (showingDisplays.empty()) { 165 if (((winRect.posX_ + static_cast<int32_t>(winRect.width_)) <= 166 displayRectMap[leftDisplayId].posX_)) { 167 showingDisplays.push_back(leftDisplayId); 168 } 169 if (winRect.posX_ >= 170 (displayRectMap[rightDisplayId].posX_ + static_cast<int32_t>(displayRectMap[rightDisplayId].width_))) { 171 showingDisplays.push_back(rightDisplayId); 172 } 173 } 174 175 // mean that this is cross-display window 176 if (showingDisplays.size() > 1) { 177 node->isShowingOnMultiDisplays_ = true; 178 } else { 179 node->isShowingOnMultiDisplays_ = false; 180 } 181 node->SetShowingDisplays(showingDisplays); 182 } 183 UpdateWindowDisplayIdIfNeeded(const sptr<WindowNode> & node)184 void DisplayGroupController::UpdateWindowDisplayIdIfNeeded(const sptr<WindowNode>& node) 185 { 186 // current multi-display is only support left-right combination, maxNum is two 187 DisplayId newDisplayId = node->GetDisplayId(); 188 const auto& curShowingDisplays = node->GetShowingDisplays(); 189 if (curShowingDisplays.empty()) { 190 WLOGFE("id:%{public}u not show on any display!", node->GetWindowId()); 191 return; 192 } 193 const auto& winRect = node->GetWindowRect(); 194 if (curShowingDisplays.size() == 1) { 195 newDisplayId = *(curShowingDisplays.begin()); 196 } else { 197 // if more than half width of the window is showing on the display, means the window belongs to this display 198 int32_t halfWidth = static_cast<int32_t>(winRect.width_ * 0.5); 199 const auto& displayRectMap = DisplayGroupInfo::GetInstance().GetAllDisplayRects(); 200 for (auto& elem : displayRectMap) { 201 auto& displayRect = elem.second; 202 if ((winRect.posX_ < displayRect.posX_) && 203 (winRect.posX_ + static_cast<int32_t>(winRect.width_) > 204 displayRect.posX_ + static_cast<int32_t>(displayRect.width_))) { // window covers whole display region 205 newDisplayId = elem.first; 206 break; 207 } 208 if (winRect.posX_ >= displayRect.posX_) { // current display is default display 209 if ((displayRect.posX_ + static_cast<int32_t>(displayRect.width_) - winRect.posX_) >= halfWidth) { 210 newDisplayId = elem.first; 211 break; 212 } 213 } else { // current display is expand display 214 if ((winRect.posX_ + static_cast<int32_t>(winRect.width_) - displayRect.posX_) >= halfWidth) { 215 newDisplayId = elem.first; 216 break; 217 } 218 } 219 } 220 } 221 222 // update displayId if needed 223 if (node->GetDisplayId() != newDisplayId) { 224 UpdateWindowDisplayId(node, newDisplayId); 225 UpdateDisplayGroupWindowTree(); 226 } 227 } 228 ChangeToRectInDisplayGroup(const sptr<WindowNode> & node,DisplayId displayId)229 void DisplayGroupController::ChangeToRectInDisplayGroup(const sptr<WindowNode>& node, DisplayId displayId) 230 { 231 auto displays = node->GetShowingDisplays(); 232 if (std::find(displays.begin(), displays.end(), displayId) != displays.end()) { 233 WLOGFD("Alreedy show in display %{public}" PRIu64 "", displayId); 234 return; 235 } 236 237 Rect requestRect = node->GetRequestRect(); 238 const Rect& displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId); 239 requestRect.posX_ += displayRect.posX_; 240 requestRect.posY_ += displayRect.posY_; 241 node->SetRequestRect(requestRect); 242 243 std::vector<DisplayId> curShowingDisplays = { node->GetDisplayId() }; 244 node->SetShowingDisplays(curShowingDisplays); 245 } 246 PreProcessWindowNode(const sptr<WindowNode> & node,WindowUpdateType type)247 void DisplayGroupController::PreProcessWindowNode(const sptr<WindowNode>& node, WindowUpdateType type) 248 { 249 if (!windowNodeContainer_->GetLayoutPolicy()->IsMultiDisplay()) { 250 if (type == WindowUpdateType::WINDOW_UPDATE_ADDED) { 251 std::vector<DisplayId> curShowingDisplays = { node->GetDisplayId() }; 252 node->SetShowingDisplays(curShowingDisplays); 253 for (auto& childNode : node->children_) { 254 PreProcessWindowNode(childNode, type); 255 } 256 } 257 WLOGFD("Current mode is not multi-display"); 258 return; 259 } 260 261 switch (type) { 262 case WindowUpdateType::WINDOW_UPDATE_ADDED: { 263 if (!node->isShowingOnMultiDisplays_) { 264 // change rect to rect in display group 265 ChangeToRectInDisplayGroup(node, node->GetDisplayId()); 266 } 267 WLOGFD("preprocess node when add window"); 268 break; 269 } 270 case WindowUpdateType::WINDOW_UPDATE_ACTIVE: { 271 // MoveTo can be called by user, calculate rect in display group if the reason is move 272 if (IsMoveToOrDragMove(node->GetWindowSizeChangeReason())) { 273 ChangeToRectInDisplayGroup(node, defaultDisplayId_); 274 } 275 WLOGFD("preprocess node when update window"); 276 break; 277 } 278 default: 279 break; 280 } 281 282 for (auto& childNode : node->children_) { 283 PreProcessWindowNode(childNode, type); 284 } 285 } 286 PostProcessWindowNode(const sptr<WindowNode> & node)287 void DisplayGroupController::PostProcessWindowNode(const sptr<WindowNode>& node) 288 { 289 if (!windowNodeContainer_->GetLayoutPolicy()->IsMultiDisplay()) { 290 WLOGFD("Current mode is not multi-display"); 291 return; 292 } 293 294 UpdateWindowShowingDisplays(node); 295 UpdateWindowDisplayIdIfNeeded(node); 296 } 297 UpdateWindowDisplayId(const sptr<WindowNode> & node,DisplayId newDisplayId)298 void DisplayGroupController::UpdateWindowDisplayId(const sptr<WindowNode>& node, DisplayId newDisplayId) 299 { 300 WLOGFD("update node displayId, srcDisplayId: %{public}" PRIu64", newDisplayId: %{public}" PRIu64"", 301 node->GetDisplayId(), newDisplayId); 302 if (node->GetWindowToken()) { 303 node->GetWindowToken()->UpdateDisplayId(node->GetDisplayId(), newDisplayId); 304 } 305 node->SetDisplayId(newDisplayId); 306 } 307 MoveCrossNodeToTargetDisplay(const sptr<WindowNode> & node,DisplayId targetDisplayId)308 void DisplayGroupController::MoveCrossNodeToTargetDisplay(const sptr<WindowNode>& node, DisplayId targetDisplayId) 309 { 310 node->isShowingOnMultiDisplays_ = false; 311 // update showing display 312 std::vector<DisplayId> newShowingDisplays = { targetDisplayId }; 313 node->SetShowingDisplays(newShowingDisplays); 314 // update new displayId 315 if (node->GetDisplayId() != targetDisplayId) { 316 UpdateWindowDisplayId(node, targetDisplayId); 317 } 318 319 for (auto& childNode : node->children_) { 320 MoveCrossNodeToTargetDisplay(childNode, targetDisplayId); 321 } 322 } 323 MoveNotCrossNodeToDefaultDisplay(const sptr<WindowNode> & node,DisplayId displayId)324 void DisplayGroupController::MoveNotCrossNodeToDefaultDisplay(const sptr<WindowNode>& node, DisplayId displayId) 325 { 326 WLOGFD("windowId: %{public}d, displayId: %{public}" PRIu64"", node->GetWindowId(), displayId); 327 // update new rect in display group 328 const Rect& srcDisplayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId); 329 const Rect& dstDisplayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(defaultDisplayId_); 330 Rect newRect = node->GetRequestRect(); 331 if (node->GetWindowType() == WindowType::WINDOW_TYPE_POINTER) { 332 newRect.posX_ = static_cast<int32_t>(dstDisplayRect.width_ / 2); // default pointerX : displayRect.width / 2 333 newRect.posY_ = static_cast<int32_t>(dstDisplayRect.height_ / 2); // default pointerY : displayRect.height / 2 334 } else { 335 newRect.posX_ = newRect.posX_ - srcDisplayRect.posX_ + dstDisplayRect.posX_; 336 newRect.posY_ = newRect.posY_ - srcDisplayRect.posY_ + dstDisplayRect.posY_; 337 } 338 339 node->SetRequestRect(newRect); 340 // update showing display 341 std::vector<DisplayId> newShowingDisplays = { defaultDisplayId_ }; 342 node->SetShowingDisplays(newShowingDisplays); 343 // update new displayId 344 UpdateWindowDisplayId(node, defaultDisplayId_); 345 346 for (auto& childNode : node->children_) { 347 MoveNotCrossNodeToDefaultDisplay(childNode, displayId); 348 } 349 } 350 ProcessNotCrossNodesOnDestroyedDisplay(DisplayId displayId,std::vector<uint32_t> & windowIds)351 void DisplayGroupController::ProcessNotCrossNodesOnDestroyedDisplay(DisplayId displayId, 352 std::vector<uint32_t>& windowIds) 353 { 354 if (displayId == defaultDisplayId_) { 355 WLOGFE("Move window nodes failed, displayId is the same as defaultDisplayId"); 356 return; 357 } 358 if (displayGroupWindowTree_.find(displayId) == displayGroupWindowTree_.end()) { 359 WLOGFE("displayId: %{public}" PRIu64" not in display group window tree", displayId); 360 return; 361 } 362 WLOGI("move window nodes for display destroy, displayId: %{public}" PRIu64"", displayId); 363 364 std::vector<WindowRootNodeType> rootNodeType = { 365 WindowRootNodeType::ABOVE_WINDOW_NODE, 366 WindowRootNodeType::APP_WINDOW_NODE, 367 WindowRootNodeType::BELOW_WINDOW_NODE 368 }; 369 for (const auto& type : rootNodeType) { 370 if (displayGroupWindowTree_[displayId].find(type) == displayGroupWindowTree_[displayId].end()) { 371 continue; 372 } 373 auto nodesVec = *(displayGroupWindowTree_[displayId][type]); 374 for (auto node : nodesVec) { 375 WLOGFD("node on destroied display, windowId: %{public}d, isShowingOnMulti: %{public}d", 376 node->GetWindowId(), node->isShowingOnMultiDisplays_); 377 if (node->GetDisplayId() != displayId || node->isShowingOnMultiDisplays_) { 378 continue; 379 } 380 // destroy status and navigation bar 381 if (node->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || 382 node->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR) { 383 windowNodeContainer_->DestroyWindowNode(node, windowIds); 384 WLOGFW("destroy status or navigation bar on destroyed display, windowId: %{public}d", 385 node->GetWindowId()); 386 continue; 387 } 388 // move not cross-display nodes to default display 389 MoveNotCrossNodeToDefaultDisplay(node, displayId); 390 391 // update RS tree 392 windowNodeContainer_->RemoveNodeFromRSTree(node, displayId, defaultDisplayId_, 393 WindowUpdateType::WINDOW_UPDATE_ACTIVE); 394 windowNodeContainer_->AddNodeOnRSTree(node, defaultDisplayId_, defaultDisplayId_, 395 WindowUpdateType::WINDOW_UPDATE_ACTIVE); 396 } 397 } 398 } 399 ProcessDisplayCreate(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,Rect> & displayRectMap)400 void DisplayGroupController::ProcessDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 401 const std::map<DisplayId, Rect>& displayRectMap) 402 { 403 defaultDisplayId_ = defaultDisplayId; 404 WLOGI("defaultDisplay, displayId: %{public}" PRIu64"", defaultDisplayId); 405 406 DisplayId displayId = displayInfo->GetDisplayId(); 407 408 InitNewDisplay(displayId); 409 410 // add displayInfo in displayGroupInfo 411 DisplayGroupInfo::GetInstance().AddDisplayInfo(displayInfo); 412 413 // modify RSTree and window tree of displayGroup for cross-display nodes 414 ProcessCrossNodes(defaultDisplayId, DisplayStateChangeType::CREATE); 415 UpdateDisplayGroupWindowTree(); 416 const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy(); 417 if (layoutPolicy == nullptr) { 418 return; 419 } 420 layoutPolicy->ProcessDisplayCreate(displayId, displayRectMap); 421 ProcessWindowPairWhenDisplayChange(); 422 } 423 ProcessDisplayDestroy(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,Rect> & displayRectMap,std::vector<uint32_t> & windowIds)424 void DisplayGroupController::ProcessDisplayDestroy(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 425 const std::map<DisplayId, Rect>& displayRectMap, 426 std::vector<uint32_t>& windowIds) 427 { 428 defaultDisplayId_ = defaultDisplayId; 429 DisplayGroupInfo::GetInstance().SetDefaultDisplayId(defaultDisplayId); 430 DisplayId displayId = displayInfo->GetDisplayId(); 431 // delete nodes and map element of deleted display 432 ProcessNotCrossNodesOnDestroyedDisplay(displayId, windowIds); 433 // modify RSTree and window tree of displayGroup for cross-display nodes 434 ProcessCrossNodes(defaultDisplayId, DisplayStateChangeType::DESTROY); 435 UpdateDisplayGroupWindowTree(); 436 ClearMapOfDestroyedDisplay(displayId); 437 windowNodeContainer_->GetLayoutPolicy()->ProcessDisplayDestroy(displayId, displayRectMap); 438 ProcessWindowPairWhenDisplayChange(); 439 } 440 ProcessSystemBarRotation(const sptr<WindowNode> & node,const std::map<DisplayId,Rect> & displayRectMap)441 void DisplayGroupController::ProcessSystemBarRotation(const sptr<WindowNode>& node, 442 const std::map<DisplayId, Rect>& displayRectMap) 443 { 444 auto rect = node->GetWindowRect(); 445 auto displayId = node->GetDisplayId(); 446 auto iter = displayRectMap.find(displayId); 447 if (iter == displayRectMap.end()) { 448 return; 449 } 450 auto displayRect = iter->second; 451 if (node->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR) { 452 rect.width_ = displayRect.width_; 453 } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR) { 454 rect.posY_ = static_cast<int32_t>(displayRect.height_ - rect.height_) + displayRect.posY_; 455 rect.width_ = displayRect.width_; 456 } 457 458 node->SetRequestRect(rect); 459 } 460 UpdateNodeSizeChangeReasonWithRotation(DisplayId displayId,const std::map<DisplayId,Rect> & displayRectMap)461 void DisplayGroupController::UpdateNodeSizeChangeReasonWithRotation(DisplayId displayId, 462 const std::map<DisplayId, Rect>& displayRectMap) 463 { 464 std::vector<WindowRootNodeType> rootNodeType = { 465 WindowRootNodeType::ABOVE_WINDOW_NODE, 466 WindowRootNodeType::APP_WINDOW_NODE, 467 WindowRootNodeType::BELOW_WINDOW_NODE 468 }; 469 for (auto& rootType : rootNodeType) { 470 std::vector<sptr<WindowNode>>* rootNodeVectorPtr = GetWindowNodesByDisplayIdAndRootType(displayId, rootType); 471 if (rootNodeVectorPtr == nullptr) { 472 WLOGFE("rootNodeVectorPtr is nullptr, %{public}d, displayId: %{public}" PRIu64, rootType, displayId); 473 return; 474 } 475 for (auto& node : (*rootNodeVectorPtr)) { 476 // DOCK_SLICE not need do rotation animation 477 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { 478 continue; 479 } 480 if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) { 481 ProcessSystemBarRotation(node, displayRectMap); 482 } 483 node->SetWindowSizeChangeReason(WindowSizeChangeReason::ROTATION); 484 } 485 } 486 } 487 ProcessDisplayChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,Rect> & displayRectMap,DisplayStateChangeType type)488 void DisplayGroupController::ProcessDisplayChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 489 const std::map<DisplayId, Rect>& displayRectMap, 490 DisplayStateChangeType type) 491 { 492 defaultDisplayId_ = defaultDisplayId; 493 auto& displayGroupInfo = DisplayGroupInfo::GetInstance(); 494 displayGroupInfo.SetDefaultDisplayId(defaultDisplayId); 495 DisplayId displayId = displayInfo->GetDisplayId(); 496 WLOGI("display change, displayId: %{public}" PRIu64", type: %{public}d", displayId, type); 497 switch (type) { 498 case DisplayStateChangeType::UPDATE_ROTATION: 499 case DisplayStateChangeType::UPDATE_ROTATION_FROM_WINDOW: { 500 displayGroupInfo.SetDisplayRotation(displayId, displayInfo->GetRotation()); 501 displayGroupInfo.SetDisplayOrientation(displayId, displayInfo->GetDisplayOrientation()); 502 displayGroupInfo.SetDisplayStateChangeType(displayId, type); 503 [[fallthrough]]; 504 } 505 case DisplayStateChangeType::DISPLAY_COMPRESS: 506 case DisplayStateChangeType::SIZE_CHANGE: { 507 ProcessDisplaySizeChangeOrRotation(defaultDisplayId, displayId, displayRectMap, type); 508 break; 509 } 510 case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: { 511 displayGroupInfo.SetDisplayVirtualPixelRatio(displayId, displayInfo->GetVirtualPixelRatio()); 512 windowNodeContainer_->GetLayoutPolicy()->ProcessDisplayVprChange(displayId); 513 break; 514 } 515 default: { 516 break; 517 } 518 } 519 } 520 ProcessDisplaySizeChangeOrRotation(DisplayId defaultDisplayId,DisplayId displayId,const std::map<DisplayId,Rect> & displayRectMap,DisplayStateChangeType type)521 void DisplayGroupController::ProcessDisplaySizeChangeOrRotation(DisplayId defaultDisplayId, DisplayId displayId, 522 const std::map<DisplayId, Rect>& displayRectMap, DisplayStateChangeType type) 523 { 524 // modify RSTree and window tree of displayGroup for cross-display nodes 525 ProcessCrossNodes(defaultDisplayId, type); 526 UpdateDisplayGroupWindowTree(); 527 // update reason after process cross Nodes to get correct display attribution 528 UpdateNodeSizeChangeReasonWithRotation(displayId, displayRectMap); 529 const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy(); 530 if (layoutPolicy == nullptr) { 531 return; 532 } 533 layoutPolicy->ProcessDisplaySizeChangeOrRotation(displayId, displayRectMap); 534 ProcessWindowPairWhenDisplayChange(true); 535 } 536 ClearMapOfDestroyedDisplay(DisplayId displayId)537 void DisplayGroupController::ClearMapOfDestroyedDisplay(DisplayId displayId) 538 { 539 sysBarTintMaps_.erase(displayId); 540 sysBarNodeMaps_.erase(displayId); 541 displayGroupWindowTree_.erase(displayId); 542 DisplayGroupInfo::GetInstance().RemoveDisplayInfo(displayId); 543 windowPairMap_.erase(displayId); 544 } 545 GetWindowPairByDisplayId(DisplayId displayId)546 sptr<WindowPair> DisplayGroupController::GetWindowPairByDisplayId(DisplayId displayId) 547 { 548 if (windowPairMap_.find(displayId) != windowPairMap_.end()) { 549 return windowPairMap_[displayId]; 550 } 551 return nullptr; 552 } 553 ProcessWindowPairWhenDisplayChange(bool rotateDisplay)554 void DisplayGroupController::ProcessWindowPairWhenDisplayChange(bool rotateDisplay) 555 { 556 for (auto& elem : DisplayGroupInfo::GetInstance().GetAllDisplayRects()) { 557 const auto& displayId = elem.first; 558 const auto& windowPair = GetWindowPairByDisplayId(displayId); 559 if (windowPair == nullptr) { 560 WLOGFE("WindowPair is nullptr, displayId: %{public}" PRIu64"", displayId); 561 return; 562 } 563 const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy(); 564 if (layoutPolicy == nullptr) { 565 WLOGFE("LayoutPolicy is nullptr, displayId: %{public}" PRIu64"", displayId); 566 return; 567 } 568 Rect divRect = layoutPolicy->GetDividerRect(displayId); 569 if (rotateDisplay) { 570 windowPair->RotateDividerWindow(divRect); 571 } else { 572 windowPair->SetDividerRect(divRect); 573 } 574 UpdateSplitRatioPoints(displayId); 575 } 576 } 577 SetSplitRatioConfig(const SplitRatioConfig & splitRatioConfig)578 void DisplayGroupController::SetSplitRatioConfig(const SplitRatioConfig& splitRatioConfig) 579 { 580 for (auto& elem : DisplayGroupInfo::GetInstance().GetAllDisplayRects()) { 581 const auto& displayId = elem.first; 582 const auto& windowPair = GetWindowPairByDisplayId(displayId); 583 if (windowPair == nullptr) { 584 WLOGFE("WindowPair is nullptr, displayId: %{public}" PRIu64"", displayId); 585 continue; 586 } 587 windowPair->SetSplitRatioConfig(splitRatioConfig); 588 UpdateSplitRatioPoints(displayId); 589 } 590 } 591 UpdateSplitRatioPoints(DisplayId displayId)592 void DisplayGroupController::UpdateSplitRatioPoints(DisplayId displayId) 593 { 594 const auto& windowPair = GetWindowPairByDisplayId(displayId); 595 if (windowPair == nullptr) { 596 WLOGFE("WindowPair is nullptr, displayId: %{public}" PRIu64"", displayId); 597 return; 598 } 599 auto displayRects = DisplayGroupInfo::GetInstance().GetAllDisplayRects(); 600 if (displayRects.find(displayId) == displayRects.end()) { 601 return; 602 } 603 windowPair->CalculateSplitRatioPoints(displayRects[displayId]); 604 const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy(); 605 if (layoutPolicy == nullptr) { 606 WLOGFE("LayoutPolicy is nullptr, displayId: %{public}" PRIu64"", displayId); 607 return; 608 } 609 layoutPolicy->SetSplitRatioPoints(displayId, windowPair->GetSplitRatioPoints()); 610 } 611 } // namespace Rosen 612 } // namespace OHOS 613