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