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