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