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_controller.h"
17e0dac50fSopenharmony_ci#include <ability_manager_client.h>
18e0dac50fSopenharmony_ci#include <chrono>
19e0dac50fSopenharmony_ci#include <cstdint>
20e0dac50fSopenharmony_ci#include <hisysevent.h>
21e0dac50fSopenharmony_ci#include <hitrace_meter.h>
22e0dac50fSopenharmony_ci#include <parameters.h>
23e0dac50fSopenharmony_ci#include <rs_window_animation_finished_callback.h>
24e0dac50fSopenharmony_ci#include <transaction/rs_transaction.h>
25e0dac50fSopenharmony_ci#include <transaction/rs_sync_transaction_controller.h>
26e0dac50fSopenharmony_ci#include <sstream>
27e0dac50fSopenharmony_ci
28e0dac50fSopenharmony_ci#ifdef POWER_MANAGER_ENABLE
29e0dac50fSopenharmony_ci#include <power_mgr_client.h>
30e0dac50fSopenharmony_ci#endif
31e0dac50fSopenharmony_ci
32e0dac50fSopenharmony_ci#include "display_group_info.h"
33e0dac50fSopenharmony_ci#include "display_manager_service_inner.h"
34e0dac50fSopenharmony_ci#include "minimize_app.h"
35e0dac50fSopenharmony_ci#include "persistent_storage.h"
36e0dac50fSopenharmony_ci#include "surface_capture_future.h"
37e0dac50fSopenharmony_ci#include "remote_animation.h"
38e0dac50fSopenharmony_ci#include "starting_window.h"
39e0dac50fSopenharmony_ci#include "window_inner_manager.h"
40e0dac50fSopenharmony_ci#include "window_manager_hilog.h"
41e0dac50fSopenharmony_ci#include "window_helper.h"
42e0dac50fSopenharmony_ci#include "window_system_effect.h"
43e0dac50fSopenharmony_ci#include "wm_common.h"
44e0dac50fSopenharmony_ci#include "wm_math.h"
45e0dac50fSopenharmony_ci#include "permission.h"
46e0dac50fSopenharmony_ci
47e0dac50fSopenharmony_cinamespace OHOS {
48e0dac50fSopenharmony_cinamespace Rosen {
49e0dac50fSopenharmony_cinamespace {
50e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "Controller"};
51e0dac50fSopenharmony_ciconstexpr uint32_t TOUCH_HOT_AREA_MAX_NUM = 50;
52e0dac50fSopenharmony_ciconstexpr float MASKING_SURFACE_NODE_Z_ORDER = 9999;
53e0dac50fSopenharmony_ci}
54e0dac50fSopenharmony_ci
55e0dac50fSopenharmony_ciuint32_t WindowController::GenWindowId()
56e0dac50fSopenharmony_ci{
57e0dac50fSopenharmony_ci    return ++windowId_;
58e0dac50fSopenharmony_ci}
59e0dac50fSopenharmony_ci
60e0dac50fSopenharmony_civoid WindowController::StartingWindow(sptr<WindowTransitionInfo> info, std::shared_ptr<Media::PixelMap> pixelMap,
61e0dac50fSopenharmony_ci    uint32_t bkgColor, bool isColdStart)
62e0dac50fSopenharmony_ci{
63e0dac50fSopenharmony_ci    if (!info || info->GetAbilityToken() == nullptr) {
64e0dac50fSopenharmony_ci        WLOGFE("info or AbilityToken is nullptr!");
65e0dac50fSopenharmony_ci        return;
66e0dac50fSopenharmony_ci    }
67e0dac50fSopenharmony_ci    StartAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::STARTING_WINDOW),
68e0dac50fSopenharmony_ci        "wms:async:ShowStartingWindow");
69e0dac50fSopenharmony_ci    auto node = windowRoot_->FindWindowNodeWithToken(info->GetAbilityToken());
70e0dac50fSopenharmony_ci    if (node == nullptr) {
71e0dac50fSopenharmony_ci        if (!isColdStart) {
72e0dac50fSopenharmony_ci            WLOGFE("no windowNode exists but is hot start!");
73e0dac50fSopenharmony_ci            return;
74e0dac50fSopenharmony_ci        }
75e0dac50fSopenharmony_ci        node = StartingWindow::CreateWindowNode(info, GenWindowId());
76e0dac50fSopenharmony_ci        if (node == nullptr) {
77e0dac50fSopenharmony_ci            return;
78e0dac50fSopenharmony_ci        }
79e0dac50fSopenharmony_ci        if (windowRoot_->SaveWindow(node) != WMError::WM_OK) {
80e0dac50fSopenharmony_ci            return;
81e0dac50fSopenharmony_ci        }
82e0dac50fSopenharmony_ci        if (!RemoteAnimation::CheckAnimationController()) {
83e0dac50fSopenharmony_ci            UpdateWindowAnimation(node);
84e0dac50fSopenharmony_ci        }
85e0dac50fSopenharmony_ci    } else {
86e0dac50fSopenharmony_ci        if (node->stateMachine_.IsWindowNodeShownOrShowing()) {
87e0dac50fSopenharmony_ci            WLOGFI("WindowId:%{public}u state:%{public}u!",
88e0dac50fSopenharmony_ci                node->GetWindowId(), static_cast<uint32_t>(node->stateMachine_.GetCurrentState()));
89e0dac50fSopenharmony_ci            return;
90e0dac50fSopenharmony_ci        }
91e0dac50fSopenharmony_ci        if (WindowHelper::IsValidWindowMode(info->GetWindowMode()) &&
92e0dac50fSopenharmony_ci            (node->GetWindowMode() != info->GetWindowMode())) {
93e0dac50fSopenharmony_ci            WLOGFW("set starting window mode. starting mode is: %{public}u, window mode is:%{public}u.",
94e0dac50fSopenharmony_ci                node->GetWindowMode(), info->GetWindowMode());
95e0dac50fSopenharmony_ci            node->SetWindowMode(info->GetWindowMode());
96e0dac50fSopenharmony_ci        }
97e0dac50fSopenharmony_ci    }
98e0dac50fSopenharmony_ci
99e0dac50fSopenharmony_ci    if (!WindowHelper::CheckSupportWindowMode(node->GetWindowMode(), node->GetModeSupportInfo(), info)) {
100e0dac50fSopenharmony_ci        WLOGFE("need to cancel starting window");
101e0dac50fSopenharmony_ci        return;
102e0dac50fSopenharmony_ci    }
103e0dac50fSopenharmony_ci
104e0dac50fSopenharmony_ci    if (windowRoot_->AddWindowNode(0, node, true) != WMError::WM_OK) {
105e0dac50fSopenharmony_ci        return;
106e0dac50fSopenharmony_ci    }
107e0dac50fSopenharmony_ci    StartingWindow::DrawStartingWindow(node, pixelMap, bkgColor, isColdStart);
108e0dac50fSopenharmony_ci    FlushWindowInfo(node->GetWindowId());
109e0dac50fSopenharmony_ci    node->startingWindowShown_ = true;
110e0dac50fSopenharmony_ci    WLOGFI("Show success, id:%{public}u!", node->GetWindowId());
111e0dac50fSopenharmony_ci}
112e0dac50fSopenharmony_ci
113e0dac50fSopenharmony_civoid WindowController::CancelStartingWindow(sptr<IRemoteObject> abilityToken)
114e0dac50fSopenharmony_ci{
115e0dac50fSopenharmony_ci    auto node = windowRoot_->FindWindowNodeWithToken(abilityToken);
116e0dac50fSopenharmony_ci    if (node == nullptr) {
117e0dac50fSopenharmony_ci        WLOGFE("Node is nullptr");
118e0dac50fSopenharmony_ci        return;
119e0dac50fSopenharmony_ci    }
120e0dac50fSopenharmony_ci    if (!node->startingWindowShown_) {
121e0dac50fSopenharmony_ci        WLOGFE("CancelStartingWindow failed because client window has shown id:%{public}u", node->GetWindowId());
122e0dac50fSopenharmony_ci        return;
123e0dac50fSopenharmony_ci    }
124e0dac50fSopenharmony_ci    HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "wms:CancelStartingWindow(%u)", node->GetWindowId());
125e0dac50fSopenharmony_ci    FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::STARTING_WINDOW),
126e0dac50fSopenharmony_ci        "wms:async:ShowStartingWindow");
127e0dac50fSopenharmony_ci    WLOGFI("Id:%{public}u!", node->GetWindowId());
128e0dac50fSopenharmony_ci    node->isAppCrash_ = true;
129e0dac50fSopenharmony_ci    WMError res = DestroyWindow(node->GetWindowId(), false);
130e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
131e0dac50fSopenharmony_ci        WLOGFE("DestroyWindow failed!");
132e0dac50fSopenharmony_ci    }
133e0dac50fSopenharmony_ci}
134e0dac50fSopenharmony_ci
135e0dac50fSopenharmony_ciWMError WindowController::NotifyWindowTransition(sptr<WindowTransitionInfo>& srcInfo,
136e0dac50fSopenharmony_ci    sptr<WindowTransitionInfo>& dstInfo)
137e0dac50fSopenharmony_ci{
138e0dac50fSopenharmony_ci    WLOGI("NotifyWindowTransition begin!");
139e0dac50fSopenharmony_ci    sptr<WindowNode> dstNode = nullptr;
140e0dac50fSopenharmony_ci    sptr<WindowNode> srcNode = nullptr;
141e0dac50fSopenharmony_ci    if (srcInfo) {
142e0dac50fSopenharmony_ci        srcNode = windowRoot_->FindWindowNodeWithToken(srcInfo->GetAbilityToken());
143e0dac50fSopenharmony_ci    }
144e0dac50fSopenharmony_ci    if (dstInfo) {
145e0dac50fSopenharmony_ci        dstNode = windowRoot_->FindWindowNodeWithToken(dstInfo->GetAbilityToken());
146e0dac50fSopenharmony_ci    }
147e0dac50fSopenharmony_ci    if (!RemoteAnimation::CheckTransition(srcInfo, srcNode, dstInfo, dstNode)) {
148e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NO_REMOTE_ANIMATION;
149e0dac50fSopenharmony_ci    }
150e0dac50fSopenharmony_ci    StartAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
151e0dac50fSopenharmony_ci        "wms:async:ShowRemoteAnimation");
152e0dac50fSopenharmony_ci    auto transitionEvent = RemoteAnimation::GetTransitionEvent(srcInfo, dstInfo, srcNode, dstNode);
153e0dac50fSopenharmony_ci    switch (transitionEvent) {
154e0dac50fSopenharmony_ci        case TransitionEvent::APP_TRANSITION: {
155e0dac50fSopenharmony_ci            return RemoteAnimation::NotifyAnimationTransition(srcInfo, dstInfo, srcNode, dstNode);
156e0dac50fSopenharmony_ci        }
157e0dac50fSopenharmony_ci        case TransitionEvent::MINIMIZE:
158e0dac50fSopenharmony_ci            return RemoteAnimation::NotifyAnimationMinimize(srcInfo, srcNode);
159e0dac50fSopenharmony_ci        case TransitionEvent::CLOSE:
160e0dac50fSopenharmony_ci        case TransitionEvent::CLOSE_BUTTON:
161e0dac50fSopenharmony_ci            return RemoteAnimation::NotifyAnimationClose(srcInfo, srcNode, transitionEvent);
162e0dac50fSopenharmony_ci        case TransitionEvent::BACK_TRANSITION:
163e0dac50fSopenharmony_ci        case TransitionEvent::BACKGROUND_TRANSITION:
164e0dac50fSopenharmony_ci            return RemoteAnimation::NotifyAnimationBackTransition(srcInfo, dstInfo, srcNode, dstNode, transitionEvent);
165e0dac50fSopenharmony_ci        default:
166e0dac50fSopenharmony_ci            return WMError::WM_ERROR_NO_REMOTE_ANIMATION;
167e0dac50fSopenharmony_ci    }
168e0dac50fSopenharmony_ci    return WMError::WM_OK;
169e0dac50fSopenharmony_ci}
170e0dac50fSopenharmony_ci
171e0dac50fSopenharmony_ciWMError WindowController::GetFocusWindowNode(DisplayId displayId, sptr<WindowNode>& windowNode)
172e0dac50fSopenharmony_ci{
173e0dac50fSopenharmony_ci    auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
174e0dac50fSopenharmony_ci    if (windowNodeContainer == nullptr) {
175e0dac50fSopenharmony_ci        WLOGFE("Container is null, displayId: %{public}" PRIu64"", displayId);
176e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
177e0dac50fSopenharmony_ci    }
178e0dac50fSopenharmony_ci    uint32_t focusWindowId = windowNodeContainer->GetFocusWindow();
179e0dac50fSopenharmony_ci    WLOGFD("Now focusId: %{public}u", focusWindowId);
180e0dac50fSopenharmony_ci    auto thisWindowNode = windowRoot_->GetWindowNode(focusWindowId);
181e0dac50fSopenharmony_ci    if (thisWindowNode == nullptr || !thisWindowNode->currentVisibility_) {
182e0dac50fSopenharmony_ci        WLOGFE("Node is null or invisible, id: %{public}u", focusWindowId);
183e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_WINDOW;
184e0dac50fSopenharmony_ci    }
185e0dac50fSopenharmony_ci    windowNode = thisWindowNode;
186e0dac50fSopenharmony_ci    return WMError::WM_OK;
187e0dac50fSopenharmony_ci}
188e0dac50fSopenharmony_ci
189e0dac50fSopenharmony_ciWMError WindowController::GetFocusWindowInfo(sptr<IRemoteObject>& abilityToken)
190e0dac50fSopenharmony_ci{
191e0dac50fSopenharmony_ci    DisplayId displayId = DisplayGroupInfo::GetInstance().GetDefaultDisplayId();
192e0dac50fSopenharmony_ci    sptr<WindowNode> windowNode;
193e0dac50fSopenharmony_ci    WMError res = GetFocusWindowNode(displayId, windowNode);
194e0dac50fSopenharmony_ci    if (res == WMError::WM_OK) {
195e0dac50fSopenharmony_ci        abilityToken = windowNode->abilityToken_;
196e0dac50fSopenharmony_ci    }
197e0dac50fSopenharmony_ci    return res;
198e0dac50fSopenharmony_ci}
199e0dac50fSopenharmony_ci
200e0dac50fSopenharmony_ciWMError WindowController::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
201e0dac50fSopenharmony_ci{
202e0dac50fSopenharmony_ci    DisplayId displayId = DisplayGroupInfo::GetInstance().GetDefaultDisplayId();
203e0dac50fSopenharmony_ci    sptr<WindowNode> windowNode;
204e0dac50fSopenharmony_ci    WMError res = GetFocusWindowNode(displayId, windowNode);
205e0dac50fSopenharmony_ci    if (res == WMError::WM_OK) {
206e0dac50fSopenharmony_ci        WLOGFD("Get focus window info success");
207e0dac50fSopenharmony_ci        focusInfo.windowId_ = static_cast<int32_t>(windowNode->GetWindowId());
208e0dac50fSopenharmony_ci        focusInfo.displayId_ = windowNode->GetDisplayId();
209e0dac50fSopenharmony_ci        focusInfo.pid_ = windowNode->GetCallingPid();
210e0dac50fSopenharmony_ci        focusInfo.uid_ = windowNode->GetCallingUid();
211e0dac50fSopenharmony_ci        focusInfo.windowType_ = windowNode->GetWindowType();
212e0dac50fSopenharmony_ci        focusInfo.abilityToken_ = windowNode->abilityToken_;
213e0dac50fSopenharmony_ci    }
214e0dac50fSopenharmony_ci    return res;
215e0dac50fSopenharmony_ci}
216e0dac50fSopenharmony_ci
217e0dac50fSopenharmony_cibool WindowController::CheckParentWindowValid(const sptr<WindowProperty>& property)
218e0dac50fSopenharmony_ci{
219e0dac50fSopenharmony_ci    if (WindowHelper::IsSubWindow(property->GetWindowType())) {
220e0dac50fSopenharmony_ci        if (property->GetParentId() == INVALID_WINDOW_ID) {
221e0dac50fSopenharmony_ci            WLOGFE("failed, sub window parent type is invalid");
222e0dac50fSopenharmony_ci            return false;
223e0dac50fSopenharmony_ci        }
224e0dac50fSopenharmony_ci        sptr<WindowNode> parentWindow = windowRoot_->GetWindowNode(property->GetParentId());
225e0dac50fSopenharmony_ci        if (parentWindow == nullptr) {
226e0dac50fSopenharmony_ci            WLOGFE("failed, sub window parent type is error");
227e0dac50fSopenharmony_ci            return false;
228e0dac50fSopenharmony_ci        }
229e0dac50fSopenharmony_ci    } else if (WindowHelper::IsSystemSubWindow(property->GetWindowType())) {
230e0dac50fSopenharmony_ci        if (property->GetParentId() == INVALID_WINDOW_ID) {
231e0dac50fSopenharmony_ci            WLOGFE("failed, sub system window parent type is invalid");
232e0dac50fSopenharmony_ci            return false;
233e0dac50fSopenharmony_ci        }
234e0dac50fSopenharmony_ci        sptr<WindowNode> parentWindow = windowRoot_->GetWindowNode(property->GetParentId());
235e0dac50fSopenharmony_ci        if (parentWindow == nullptr || !WindowHelper::IsSystemWindow(parentWindow->GetWindowType())) {
236e0dac50fSopenharmony_ci            WLOGFE("failed, sub system window parent type is error");
237e0dac50fSopenharmony_ci            return false;
238e0dac50fSopenharmony_ci        }
239e0dac50fSopenharmony_ci    } else {
240e0dac50fSopenharmony_ci        if (property->GetParentId() != INVALID_WINDOW_ID) {
241e0dac50fSopenharmony_ci            WLOGFE("failed, type is error");
242e0dac50fSopenharmony_ci            return false;
243e0dac50fSopenharmony_ci        }
244e0dac50fSopenharmony_ci    }
245e0dac50fSopenharmony_ci    return true;
246e0dac50fSopenharmony_ci}
247e0dac50fSopenharmony_ci
248e0dac50fSopenharmony_ciWMError WindowController::CreateWindow(sptr<IWindow>& window, sptr<WindowProperty>& property,
249e0dac50fSopenharmony_ci    const std::shared_ptr<RSSurfaceNode>& surfaceNode, uint32_t& windowId, sptr<IRemoteObject> token,
250e0dac50fSopenharmony_ci    int32_t pid, int32_t uid)
251e0dac50fSopenharmony_ci{
252e0dac50fSopenharmony_ci    if (!CheckParentWindowValid(property)) {
253e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_PARENT;
254e0dac50fSopenharmony_ci    }
255e0dac50fSopenharmony_ci
256e0dac50fSopenharmony_ci    if (!surfaceNode) {
257e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
258e0dac50fSopenharmony_ci    }
259e0dac50fSopenharmony_ci
260e0dac50fSopenharmony_ci    if (property->GetWindowType() != WindowType::WINDOW_TYPE_BOOT_ANIMATION) {
261e0dac50fSopenharmony_ci        surfaceNode->SetFrameGravity(Gravity::RESIZE);
262e0dac50fSopenharmony_ci    }
263e0dac50fSopenharmony_ci
264e0dac50fSopenharmony_ci    sptr<WindowNode> node = windowRoot_->FindWindowNodeWithToken(token);
265e0dac50fSopenharmony_ci    if (node != nullptr && WindowHelper::IsMainWindow(property->GetWindowType()) && node->startingWindowShown_) {
266e0dac50fSopenharmony_ci        StartingWindow::HandleClientWindowCreate(node, window, windowId, surfaceNode, property, pid, uid);
267e0dac50fSopenharmony_ci        windowRoot_->AddDeathRecipient(node);
268e0dac50fSopenharmony_ci        windowRoot_->AddSurfaceNodeIdWindowNodePair(surfaceNode->GetId(), node);
269e0dac50fSopenharmony_ci        WLOGFD("Flags: %{public}u, API version: %{public}u", property->GetWindowFlags(),
270e0dac50fSopenharmony_ci            node->GetWindowProperty()->GetApiCompatibleVersion());
271e0dac50fSopenharmony_ci        if (property->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) &&
272e0dac50fSopenharmony_ci            node->GetWindowProperty()->GetApiCompatibleVersion() >= 9 && !property->isSystemCalling_) { // 9: API ver.
273e0dac50fSopenharmony_ci            property->SetWindowFlags(property->GetWindowFlags() &
274e0dac50fSopenharmony_ci                ~static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
275e0dac50fSopenharmony_ci        }
276e0dac50fSopenharmony_ci        property->SetApiCompatibleVersion(node->GetWindowProperty()->GetApiCompatibleVersion());
277e0dac50fSopenharmony_ci        return WMError::WM_OK;
278e0dac50fSopenharmony_ci    }
279e0dac50fSopenharmony_ci
280e0dac50fSopenharmony_ci    windowId = GenWindowId();
281e0dac50fSopenharmony_ci    sptr<WindowProperty> windowProperty = new WindowProperty(property);
282e0dac50fSopenharmony_ci    windowProperty->SetWindowId(windowId);
283e0dac50fSopenharmony_ci    node = new WindowNode(windowProperty, window, surfaceNode, pid, uid);
284e0dac50fSopenharmony_ci    node->abilityToken_ = token;
285e0dac50fSopenharmony_ci    node->dialogTargetToken_ = token;
286e0dac50fSopenharmony_ci    UpdateWindowAnimation(node);
287e0dac50fSopenharmony_ci    // for system and subwindow
288e0dac50fSopenharmony_ci    WindowSystemEffect::SetWindowEffect(node);
289e0dac50fSopenharmony_ci    WLOGFD("createWindow id:%{public}u", windowId);
290e0dac50fSopenharmony_ci
291e0dac50fSopenharmony_ci    node->stateMachine_.SetWindowId(windowId);
292e0dac50fSopenharmony_ci    node->stateMachine_.SetWindowType(property->GetWindowType());
293e0dac50fSopenharmony_ci    return windowRoot_->SaveWindow(node);
294e0dac50fSopenharmony_ci}
295e0dac50fSopenharmony_ci
296e0dac50fSopenharmony_civoid WindowController::NotifyAfterAddWindow(sptr<WindowNode>& node)
297e0dac50fSopenharmony_ci{
298e0dac50fSopenharmony_ci    std::vector<sptr<WindowNode>> nodes;
299e0dac50fSopenharmony_ci    nodes.emplace_back(node);
300e0dac50fSopenharmony_ci    for (auto& child : node->children_) {
301e0dac50fSopenharmony_ci        if (child->currentVisibility_) {
302e0dac50fSopenharmony_ci            nodes.emplace_back(child);
303e0dac50fSopenharmony_ci        }
304e0dac50fSopenharmony_ci    }
305e0dac50fSopenharmony_ci    for (auto& iter : nodes) {
306e0dac50fSopenharmony_ci        if ((iter->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
307e0dac50fSopenharmony_ci            (node->abilityToken_ != iter->abilityToken_)) {
308e0dac50fSopenharmony_ci            iter->GetWindowToken()->NotifyForeground();
309e0dac50fSopenharmony_ci        }
310e0dac50fSopenharmony_ci    }
311e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(node->GetDisplayId(), nodes,
312e0dac50fSopenharmony_ci        WindowUpdateType::WINDOW_UPDATE_ADDED);
313e0dac50fSopenharmony_ci}
314e0dac50fSopenharmony_ci
315e0dac50fSopenharmony_ciWMError WindowController::AddWindowNode(sptr<WindowProperty>& property)
316e0dac50fSopenharmony_ci{
317e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(property->GetWindowId());
318e0dac50fSopenharmony_ci    if (node == nullptr) {
319e0dac50fSopenharmony_ci        WLOGFE("could not find window");
320e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
321e0dac50fSopenharmony_ci    }
322e0dac50fSopenharmony_ci
323e0dac50fSopenharmony_ci    if (node->currentVisibility_ && !node->startingWindowShown_) {
324e0dac50fSopenharmony_ci        WLOGFE("Current window is visible, windowId: %{public}u", node->GetWindowId());
325e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_OPERATION;
326e0dac50fSopenharmony_ci    }
327e0dac50fSopenharmony_ci
328e0dac50fSopenharmony_ci    // using starting window rect if client rect is empty
329e0dac50fSopenharmony_ci    if (WindowHelper::IsEmptyRect(property->GetRequestRect()) && node->startingWindowShown_) { // for tile and cascade
330e0dac50fSopenharmony_ci        property->SetRequestRect(node->GetRequestRect());
331e0dac50fSopenharmony_ci        property->SetWindowRect(node->GetWindowRect());
332e0dac50fSopenharmony_ci        property->SetDecoStatus(true);
333e0dac50fSopenharmony_ci    }
334e0dac50fSopenharmony_ci    node->GetWindowProperty()->CopyFrom(property);
335e0dac50fSopenharmony_ci    UpdateWindowAnimation(node);
336e0dac50fSopenharmony_ci
337e0dac50fSopenharmony_ci    RelayoutKeyboard(node);
338e0dac50fSopenharmony_ci    WMError res = windowRoot_->AddWindowNode(property->GetParentId(), node);
339e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
340e0dac50fSopenharmony_ci        MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW);
341e0dac50fSopenharmony_ci        return res;
342e0dac50fSopenharmony_ci    }
343e0dac50fSopenharmony_ci    windowRoot_->FocusFaultDetection();
344e0dac50fSopenharmony_ci
345e0dac50fSopenharmony_ci    FlushWindowInfo(property->GetWindowId());
346e0dac50fSopenharmony_ci    NotifyAfterAddWindow(node);
347e0dac50fSopenharmony_ci    HandleTurnScreenOn(node);
348e0dac50fSopenharmony_ci
349e0dac50fSopenharmony_ci    if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
350e0dac50fSopenharmony_ci        sysBarWinId_[node->GetWindowType()] = node->GetWindowId();
351e0dac50fSopenharmony_ci    }
352e0dac50fSopenharmony_ci    if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
353e0dac50fSopenharmony_ci        ResizeSoftInputCallingWindowIfNeed(node);
354e0dac50fSopenharmony_ci    }
355e0dac50fSopenharmony_ci    StopBootAnimationIfNeed(node);
356e0dac50fSopenharmony_ci    // when hide with remote animation first and show with default animation, need transform state
357e0dac50fSopenharmony_ci    // minimize should execute in finish callback when remote animation enabled
358e0dac50fSopenharmony_ci    if (!node->stateMachine_.IsShowAnimationPlaying()) {
359e0dac50fSopenharmony_ci        if (WindowHelper::IsMainWindow(node->GetWindowType())) {
360e0dac50fSopenharmony_ci            MinimizeApp::ExecuteMinimizeAll();
361e0dac50fSopenharmony_ci            WLOGI("Id:%{public}u execute minimize all", node->GetWindowId());
362e0dac50fSopenharmony_ci        }
363e0dac50fSopenharmony_ci        node->stateMachine_.TransitionTo(WindowNodeState::SHOWN); // for normal show which not use remote animation
364e0dac50fSopenharmony_ci    } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
365e0dac50fSopenharmony_ci        MinimizeApp::ExecuteMinimizeTargetReasons(~MinimizeReason::OTHER_WINDOW);
366e0dac50fSopenharmony_ci    }
367e0dac50fSopenharmony_ci
368e0dac50fSopenharmony_ci    return WMError::WM_OK;
369e0dac50fSopenharmony_ci}
370e0dac50fSopenharmony_ci
371e0dac50fSopenharmony_cibool WindowController::GetNavigationBarHeight(DisplayId displayId, uint32_t& navigationBarHeight)
372e0dac50fSopenharmony_ci{
373e0dac50fSopenharmony_ci    auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
374e0dac50fSopenharmony_ci    if (container == nullptr) {
375e0dac50fSopenharmony_ci        WLOGFE("Node container is null");
376e0dac50fSopenharmony_ci        return false;
377e0dac50fSopenharmony_ci    }
378e0dac50fSopenharmony_ci
379e0dac50fSopenharmony_ci    bool hasFullScreenKeyGuardWindow = false;
380e0dac50fSopenharmony_ci    WindowNodeOperationFunc func = [&navigationBarHeight, &hasFullScreenKeyGuardWindow](sptr<WindowNode> windowNode) {
381e0dac50fSopenharmony_ci        if (!windowNode) {
382e0dac50fSopenharmony_ci            WLOGFE("The window node is nullptr.");
383e0dac50fSopenharmony_ci            return false;
384e0dac50fSopenharmony_ci        }
385e0dac50fSopenharmony_ci        if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
386e0dac50fSopenharmony_ci            windowNode->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) {
387e0dac50fSopenharmony_ci                hasFullScreenKeyGuardWindow = true;
388e0dac50fSopenharmony_ci        }
389e0dac50fSopenharmony_ci        if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR &&
390e0dac50fSopenharmony_ci            windowNode->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
391e0dac50fSopenharmony_ci            navigationBarHeight = windowNode->GetWindowRect().height_;
392e0dac50fSopenharmony_ci            if (hasFullScreenKeyGuardWindow) {
393e0dac50fSopenharmony_ci                WLOGFW("The navigation bar is overlaid by the keyguard window and is invisible");
394e0dac50fSopenharmony_ci                navigationBarHeight = 0;
395e0dac50fSopenharmony_ci            }
396e0dac50fSopenharmony_ci            return true;
397e0dac50fSopenharmony_ci        }
398e0dac50fSopenharmony_ci        return false;
399e0dac50fSopenharmony_ci    };
400e0dac50fSopenharmony_ci    container->TraverseWindowTree(func, true); // FromTopToBottom
401e0dac50fSopenharmony_ci
402e0dac50fSopenharmony_ci    return true;
403e0dac50fSopenharmony_ci}
404e0dac50fSopenharmony_ci
405e0dac50fSopenharmony_civoid WindowController::RelayoutKeyboard(const sptr<WindowNode>& node)
406e0dac50fSopenharmony_ci{
407e0dac50fSopenharmony_ci    if (node == nullptr) {
408e0dac50fSopenharmony_ci        WLOGFE("Node is nullptr");
409e0dac50fSopenharmony_ci        return;
410e0dac50fSopenharmony_ci    }
411e0dac50fSopenharmony_ci    WindowGravity gravity;
412e0dac50fSopenharmony_ci    uint32_t percent = 0;
413e0dac50fSopenharmony_ci    node->GetWindowGravity(gravity, percent);
414e0dac50fSopenharmony_ci    if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
415e0dac50fSopenharmony_ci        gravity == WindowGravity::WINDOW_GRAVITY_FLOAT) {
416e0dac50fSopenharmony_ci        return;
417e0dac50fSopenharmony_ci    }
418e0dac50fSopenharmony_ci
419e0dac50fSopenharmony_ci    auto container = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
420e0dac50fSopenharmony_ci    if (container == nullptr) {
421e0dac50fSopenharmony_ci        WLOGFE("Node container is null");
422e0dac50fSopenharmony_ci        return;
423e0dac50fSopenharmony_ci    }
424e0dac50fSopenharmony_ci
425e0dac50fSopenharmony_ci    uint32_t navigationBarHeight = 0;
426e0dac50fSopenharmony_ci    bool res = GetNavigationBarHeight(node->GetDisplayId(), navigationBarHeight);
427e0dac50fSopenharmony_ci    if (res == false) {
428e0dac50fSopenharmony_ci        return;
429e0dac50fSopenharmony_ci    }
430e0dac50fSopenharmony_ci
431e0dac50fSopenharmony_ci    sptr<DisplayInfo> defaultDisplayInfo = DisplayGroupInfo::GetInstance().GetDefaultDisplayInfo();
432e0dac50fSopenharmony_ci    if (defaultDisplayInfo == nullptr) {
433e0dac50fSopenharmony_ci        WLOGFE("defaultDisplayInfo is null");
434e0dac50fSopenharmony_ci        return;
435e0dac50fSopenharmony_ci    }
436e0dac50fSopenharmony_ci
437e0dac50fSopenharmony_ci    auto requestRect = node->GetRequestRect();
438e0dac50fSopenharmony_ci    if (gravity == WindowGravity::WINDOW_GRAVITY_BOTTOM) {
439e0dac50fSopenharmony_ci        if (percent != 0) {
440e0dac50fSopenharmony_ci            requestRect.width_ = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
441e0dac50fSopenharmony_ci            requestRect.height_ =
442e0dac50fSopenharmony_ci                static_cast<uint32_t>(defaultDisplayInfo->GetHeight()) * percent / 100u; // 100: for calc percent.
443e0dac50fSopenharmony_ci            requestRect.posX_ = 0;
444e0dac50fSopenharmony_ci        }
445e0dac50fSopenharmony_ci    }
446e0dac50fSopenharmony_ci    requestRect.posY_ = defaultDisplayInfo->GetHeight() -
447e0dac50fSopenharmony_ci        static_cast<int32_t>(requestRect.height_ + navigationBarHeight);
448e0dac50fSopenharmony_ci    node->SetRequestRect(requestRect);
449e0dac50fSopenharmony_ci}
450e0dac50fSopenharmony_ci
451e0dac50fSopenharmony_civoid WindowController::NotifyInputCallingWindowRectAndOccupiedAreaChange(const sptr<WindowNode>& callingWindow,
452e0dac50fSopenharmony_ci    const Rect& rect, const Rect& occupiedArea)
453e0dac50fSopenharmony_ci{
454e0dac50fSopenharmony_ci    if (callingWindow->GetWindowType() != WindowType::WINDOW_TYPE_APP_COMPONENT) {
455e0dac50fSopenharmony_ci        // update calling window rect
456e0dac50fSopenharmony_ci        callingWindow->SetWindowRect(rect);
457e0dac50fSopenharmony_ci        WindowLayoutPolicy::CalcAndSetNodeHotZone(rect, callingWindow);
458e0dac50fSopenharmony_ci
459e0dac50fSopenharmony_ci        // set bounds and do animation for calling window
460e0dac50fSopenharmony_ci        wptr<WindowNode> weakNode = callingWindow;
461e0dac50fSopenharmony_ci        auto setBoundsFun = [weakNode, rect]() {
462e0dac50fSopenharmony_ci            auto winNode = weakNode.promote();
463e0dac50fSopenharmony_ci            if (winNode == nullptr) {
464e0dac50fSopenharmony_ci                WLOGFW("Window node is nullptr");
465e0dac50fSopenharmony_ci                return;
466e0dac50fSopenharmony_ci            }
467e0dac50fSopenharmony_ci            if (winNode->leashWinSurfaceNode_) {
468e0dac50fSopenharmony_ci                winNode->leashWinSurfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
469e0dac50fSopenharmony_ci                if (winNode->startingWinSurfaceNode_) {
470e0dac50fSopenharmony_ci                    winNode->startingWinSurfaceNode_->SetBounds(0, 0, rect.width_, rect.height_);
471e0dac50fSopenharmony_ci                }
472e0dac50fSopenharmony_ci                if (winNode->surfaceNode_) {
473e0dac50fSopenharmony_ci                    winNode->surfaceNode_->SetBounds(0, 0, rect.width_, rect.height_);
474e0dac50fSopenharmony_ci                }
475e0dac50fSopenharmony_ci            } else {
476e0dac50fSopenharmony_ci                if (winNode->surfaceNode_) {
477e0dac50fSopenharmony_ci                    winNode->surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
478e0dac50fSopenharmony_ci                }
479e0dac50fSopenharmony_ci            }
480e0dac50fSopenharmony_ci        };
481e0dac50fSopenharmony_ci
482e0dac50fSopenharmony_ci        const AnimationConfig::KeyboardAnimation& animation = WindowHelper::IsEmptyRect(occupiedArea) ?
483e0dac50fSopenharmony_ci            WindowNodeContainer::GetAnimationConfigRef().keyboardAnimationOut_ :
484e0dac50fSopenharmony_ci            WindowNodeContainer::GetAnimationConfigRef().keyboardAnimationIn_;
485e0dac50fSopenharmony_ci        RSNode::Animate(animation.duration_, animation.curve_, setBoundsFun);
486e0dac50fSopenharmony_ci    }
487e0dac50fSopenharmony_ci
488e0dac50fSopenharmony_ci    // if keyboard will occupy calling, notify calling window the occupied area and safe height
489e0dac50fSopenharmony_ci    const Rect& safeRect = WindowHelper::GetOverlap(occupiedArea, rect, 0, 0);
490e0dac50fSopenharmony_ci    sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT,
491e0dac50fSopenharmony_ci        safeRect, safeRect.height_);
492e0dac50fSopenharmony_ci
493e0dac50fSopenharmony_ci    if (WindowNodeContainer::GetAnimateTransactionEnabled()) {
494e0dac50fSopenharmony_ci        auto syncTransactionController = RSSyncTransactionController::GetInstance();
495e0dac50fSopenharmony_ci        if (syncTransactionController) {
496e0dac50fSopenharmony_ci            callingWindow->GetWindowToken()->UpdateOccupiedAreaAndRect(info, rect,
497e0dac50fSopenharmony_ci                syncTransactionController->GetRSTransaction());
498e0dac50fSopenharmony_ci        }
499e0dac50fSopenharmony_ci    } else {
500e0dac50fSopenharmony_ci        callingWindow->GetWindowToken()->UpdateOccupiedAreaAndRect(info, rect);
501e0dac50fSopenharmony_ci    }
502e0dac50fSopenharmony_ci
503e0dac50fSopenharmony_ci    FlushWindowInfo(callingWindow->GetWindowId());
504e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(callingWindow, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
505e0dac50fSopenharmony_ci    WLOGFD("Calling windowId: %{public}u, calling winRect: [%{public}d, %{public}d, %{public}u, %{public}u], "
506e0dac50fSopenharmony_ci        "occupiedArea: [%{public}d, %{public}d, %{public}u, %{public}u], safeHeight: %{public}u",
507e0dac50fSopenharmony_ci        callingWindow->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_,
508e0dac50fSopenharmony_ci        occupiedArea.posX_, occupiedArea.posY_, occupiedArea.width_, occupiedArea.height_, safeRect.height_);
509e0dac50fSopenharmony_ci}
510e0dac50fSopenharmony_ci
511e0dac50fSopenharmony_civoid WindowController::ResizeSoftInputCallingWindowIfNeed(const sptr<WindowNode>& node)
512e0dac50fSopenharmony_ci{
513e0dac50fSopenharmony_ci    auto callingWindowId = node->GetCallingWindow();
514e0dac50fSopenharmony_ci    auto callingWindow = windowRoot_->GetWindowNode(callingWindowId);
515e0dac50fSopenharmony_ci    if (callingWindow == nullptr) {
516e0dac50fSopenharmony_ci        auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
517e0dac50fSopenharmony_ci        if (windowNodeContainer == nullptr) {
518e0dac50fSopenharmony_ci            WLOGFE("NodeContainer is null, displayId:%{public}" PRIu64"", node->GetDisplayId());
519e0dac50fSopenharmony_ci            return;
520e0dac50fSopenharmony_ci        }
521e0dac50fSopenharmony_ci        callingWindowId = windowNodeContainer->GetFocusWindow();
522e0dac50fSopenharmony_ci        callingWindow = windowRoot_->GetWindowNode(callingWindowId);
523e0dac50fSopenharmony_ci    }
524e0dac50fSopenharmony_ci    if (callingWindow == nullptr || !callingWindow->currentVisibility_ ||
525e0dac50fSopenharmony_ci        callingWindow->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
526e0dac50fSopenharmony_ci        WLOGFE("callingWindow is null or invisible or not float window, callingWindowId:%{public}u", callingWindowId);
527e0dac50fSopenharmony_ci        return;
528e0dac50fSopenharmony_ci    }
529e0dac50fSopenharmony_ci    WindowGravity gravity;
530e0dac50fSopenharmony_ci    uint32_t percent = 0;
531e0dac50fSopenharmony_ci    node->GetWindowGravity(gravity, percent);
532e0dac50fSopenharmony_ci    if (gravity != WindowGravity::WINDOW_GRAVITY_BOTTOM) {
533e0dac50fSopenharmony_ci        WLOGFI("input method window gravity is not bottom, no need to raise calling window");
534e0dac50fSopenharmony_ci        return;
535e0dac50fSopenharmony_ci    }
536e0dac50fSopenharmony_ci
537e0dac50fSopenharmony_ci    const Rect& softInputWindowRect = node->GetWindowRect();
538e0dac50fSopenharmony_ci    const Rect& callingWindowRect = callingWindow->GetWindowRect();
539e0dac50fSopenharmony_ci    if (WindowHelper::IsEmptyRect(WindowHelper::GetOverlap(softInputWindowRect, callingWindowRect, 0, 0))) {
540e0dac50fSopenharmony_ci        WLOGFD("There is no overlap area");
541e0dac50fSopenharmony_ci        return;
542e0dac50fSopenharmony_ci    }
543e0dac50fSopenharmony_ci
544e0dac50fSopenharmony_ci    // calculate new rect of calling window
545e0dac50fSopenharmony_ci    Rect newRect = callingWindowRect;
546e0dac50fSopenharmony_ci    if (callingWindow->GetWindowType() != WindowType::WINDOW_TYPE_APP_COMPONENT) {
547e0dac50fSopenharmony_ci        newRect.posY_ = softInputWindowRect.posY_ - static_cast<int32_t>(newRect.height_);
548e0dac50fSopenharmony_ci        Rect statusBarWindowRect = { 0, 0, 0, 0 };
549e0dac50fSopenharmony_ci        auto statusbarWindow = windowRoot_->GetWindowNode(sysBarWinId_[WindowType::WINDOW_TYPE_STATUS_BAR]);
550e0dac50fSopenharmony_ci        if (statusbarWindow != nullptr && statusbarWindow->parent_ != nullptr) {
551e0dac50fSopenharmony_ci            statusBarWindowRect = statusbarWindow->GetWindowRect();
552e0dac50fSopenharmony_ci        }
553e0dac50fSopenharmony_ci        newRect.posY_ = std::max(newRect.posY_,
554e0dac50fSopenharmony_ci            statusBarWindowRect.posY_ + static_cast<int32_t>(statusBarWindowRect.height_));
555e0dac50fSopenharmony_ci
556e0dac50fSopenharmony_ci        callingWindowRestoringRect_ = callingWindowRect;
557e0dac50fSopenharmony_ci        callingWindowId_ = callingWindow->GetWindowId();
558e0dac50fSopenharmony_ci    }
559e0dac50fSopenharmony_ci
560e0dac50fSopenharmony_ci    NotifyInputCallingWindowRectAndOccupiedAreaChange(callingWindow, newRect, softInputWindowRect);
561e0dac50fSopenharmony_ci}
562e0dac50fSopenharmony_ci
563e0dac50fSopenharmony_civoid WindowController::RestoreCallingWindowSizeIfNeed()
564e0dac50fSopenharmony_ci{
565e0dac50fSopenharmony_ci    auto callingWindow = windowRoot_->GetWindowNode(callingWindowId_);
566e0dac50fSopenharmony_ci    if (!WindowHelper::IsEmptyRect(callingWindowRestoringRect_) && callingWindow != nullptr &&
567e0dac50fSopenharmony_ci        callingWindow->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
568e0dac50fSopenharmony_ci        Rect overlapRect = { 0, 0, 0, 0 };
569e0dac50fSopenharmony_ci        NotifyInputCallingWindowRectAndOccupiedAreaChange(callingWindow, callingWindowRestoringRect_, overlapRect);
570e0dac50fSopenharmony_ci    }
571e0dac50fSopenharmony_ci    callingWindowRestoringRect_ = { 0, 0, 0, 0 };
572e0dac50fSopenharmony_ci    callingWindowId_ = 0u;
573e0dac50fSopenharmony_ci}
574e0dac50fSopenharmony_ci
575e0dac50fSopenharmony_civoid WindowController::HandleTurnScreenOn(const sptr<WindowNode>& node)
576e0dac50fSopenharmony_ci{
577e0dac50fSopenharmony_ci    if (node == nullptr) {
578e0dac50fSopenharmony_ci        WLOGFE("Node is nullptr");
579e0dac50fSopenharmony_ci        return;
580e0dac50fSopenharmony_ci    }
581e0dac50fSopenharmony_ci    WLOGFD("Win: %{public}s, is turn on%{public}d", node->GetWindowName().c_str(), node->IsTurnScreenOn());
582e0dac50fSopenharmony_ci#ifdef POWER_MANAGER_ENABLE
583e0dac50fSopenharmony_ci    // reset ipc identity
584e0dac50fSopenharmony_ci    std::string identity = IPCSkeleton::ResetCallingIdentity();
585e0dac50fSopenharmony_ci    if (node->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
586e0dac50fSopenharmony_ci        WLOGI("turn screen on");
587e0dac50fSopenharmony_ci        PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
588e0dac50fSopenharmony_ci    }
589e0dac50fSopenharmony_ci    // set ipc identity to raw
590e0dac50fSopenharmony_ci    IPCSkeleton::SetCallingIdentity(identity);
591e0dac50fSopenharmony_ci#endif
592e0dac50fSopenharmony_ci}
593e0dac50fSopenharmony_ci
594e0dac50fSopenharmony_ciWMError WindowController::RemoveWindowNode(uint32_t windowId, bool fromAnimation)
595e0dac50fSopenharmony_ci{
596e0dac50fSopenharmony_ci    auto windowNode = windowRoot_->GetWindowNode(windowId);
597e0dac50fSopenharmony_ci    if (windowNode == nullptr) {
598e0dac50fSopenharmony_ci        WLOGFE("Could not find window");
599e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
600e0dac50fSopenharmony_ci    }
601e0dac50fSopenharmony_ci    auto removeFunc = [this, windowId, windowNode, fromAnimation]() {
602e0dac50fSopenharmony_ci        WMError res = windowRoot_->RemoveWindowNode(windowId, fromAnimation);
603e0dac50fSopenharmony_ci        if (res != WMError::WM_OK) {
604e0dac50fSopenharmony_ci            WLOGFE("RemoveWindowNode failed");
605e0dac50fSopenharmony_ci            return res;
606e0dac50fSopenharmony_ci        }
607e0dac50fSopenharmony_ci        windowRoot_->FocusFaultDetection();
608e0dac50fSopenharmony_ci        FlushWindowInfo(windowId);
609e0dac50fSopenharmony_ci        std::vector<sptr<WindowNode>> nodes;
610e0dac50fSopenharmony_ci        nodes.emplace_back(windowNode);
611e0dac50fSopenharmony_ci        for (auto& child : windowNode->children_) {
612e0dac50fSopenharmony_ci            nodes.emplace_back(child);
613e0dac50fSopenharmony_ci        }
614e0dac50fSopenharmony_ci        for (auto& iter : nodes) {
615e0dac50fSopenharmony_ci            if ((iter->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
616e0dac50fSopenharmony_ci                (windowNode->abilityToken_ != iter->abilityToken_)) {
617e0dac50fSopenharmony_ci                iter->GetWindowToken()->NotifyBackground();
618e0dac50fSopenharmony_ci            }
619e0dac50fSopenharmony_ci        }
620e0dac50fSopenharmony_ci        displayZoomController_->ClearZoomTransform(nodes);
621e0dac50fSopenharmony_ci        accessibilityConnection_->NotifyAccessibilityWindowInfo(windowNode->GetDisplayId(), nodes,
622e0dac50fSopenharmony_ci            WindowUpdateType::WINDOW_UPDATE_REMOVED);
623e0dac50fSopenharmony_ci        return res;
624e0dac50fSopenharmony_ci    };
625e0dac50fSopenharmony_ci    WMError res = WMError::WM_ERROR_NO_REMOTE_ANIMATION;
626e0dac50fSopenharmony_ci    if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
627e0dac50fSopenharmony_ci        // if has main full screen window, no need to do remote unlock animation
628e0dac50fSopenharmony_ci        if (windowRoot_->NotifyDesktopUnfrozen() == WMError::WM_OK &&
629e0dac50fSopenharmony_ci            !windowRoot_->HasMainFullScreenWindowShown(windowNode->GetDisplayId())) {
630e0dac50fSopenharmony_ci            res = RemoteAnimation::NotifyAnimationScreenUnlock(removeFunc, windowNode);
631e0dac50fSopenharmony_ci            WLOGI("NotifyAnimationScreenUnlock with remote animation");
632e0dac50fSopenharmony_ci        }
633e0dac50fSopenharmony_ci    }
634e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
635e0dac50fSopenharmony_ci        res = removeFunc();
636e0dac50fSopenharmony_ci    }
637e0dac50fSopenharmony_ci    if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
638e0dac50fSopenharmony_ci        RestoreCallingWindowSizeIfNeed();
639e0dac50fSopenharmony_ci    }
640e0dac50fSopenharmony_ci    if (!windowNode->stateMachine_.IsHideAnimationPlaying()) {
641e0dac50fSopenharmony_ci        windowNode->stateMachine_.TransitionTo(WindowNodeState::HIDDEN);
642e0dac50fSopenharmony_ci    }
643e0dac50fSopenharmony_ci    return res;
644e0dac50fSopenharmony_ci}
645e0dac50fSopenharmony_ci
646e0dac50fSopenharmony_ciWMError WindowController::DestroyWindow(uint32_t windowId, bool onlySelf)
647e0dac50fSopenharmony_ci{
648e0dac50fSopenharmony_ci    DisplayId displayId = DISPLAY_ID_INVALID;
649e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
650e0dac50fSopenharmony_ci    if (node == nullptr) {
651e0dac50fSopenharmony_ci        WLOGFE("Destroy window %{public}u failed.", windowId);
652e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
653e0dac50fSopenharmony_ci    }
654e0dac50fSopenharmony_ci    sptr<WindowNode> parent = node->parent_;
655e0dac50fSopenharmony_ci    displayId = node->GetDisplayId();
656e0dac50fSopenharmony_ci    WMError res = windowRoot_->DestroyWindow(windowId, onlySelf);
657e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
658e0dac50fSopenharmony_ci        return res;
659e0dac50fSopenharmony_ci    }
660e0dac50fSopenharmony_ci    if (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
661e0dac50fSopenharmony_ci        if ((parent != nullptr) && WindowHelper::IsSplitWindowMode(parent->GetWindowMode())) {
662e0dac50fSopenharmony_ci            auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
663e0dac50fSopenharmony_ci            windowNodeContainer->RaiseSplitRelatedWindowToTop(parent);
664e0dac50fSopenharmony_ci        }
665e0dac50fSopenharmony_ci    }
666e0dac50fSopenharmony_ci    windowRoot_->FocusFaultDetection();
667e0dac50fSopenharmony_ci    FlushWindowInfoWithDisplayId(displayId);
668e0dac50fSopenharmony_ci    std::vector<sptr<WindowNode>> nodes;
669e0dac50fSopenharmony_ci    nodes.emplace_back(node);
670e0dac50fSopenharmony_ci    for (auto& child : node->children_) {
671e0dac50fSopenharmony_ci        nodes.emplace_back(child);
672e0dac50fSopenharmony_ci    }
673e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(node->GetDisplayId(), nodes,
674e0dac50fSopenharmony_ci        WindowUpdateType::WINDOW_UPDATE_REMOVED);
675e0dac50fSopenharmony_ci    node->stateMachine_.TransitionTo(WindowNodeState::DESTROYED);
676e0dac50fSopenharmony_ci    return res;
677e0dac50fSopenharmony_ci}
678e0dac50fSopenharmony_ci
679e0dac50fSopenharmony_ciWMError WindowController::ResizeRect(uint32_t windowId, const Rect& rect, WindowSizeChangeReason reason)
680e0dac50fSopenharmony_ci{
681e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
682e0dac50fSopenharmony_ci    if (node == nullptr) {
683e0dac50fSopenharmony_ci        WLOGFE("could not find window");
684e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
685e0dac50fSopenharmony_ci    }
686e0dac50fSopenharmony_ci    if (node->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
687e0dac50fSopenharmony_ci        WLOGFE("fullscreen window could not resize");
688e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_OPERATION;
689e0dac50fSopenharmony_ci    }
690e0dac50fSopenharmony_ci    /*
691e0dac50fSopenharmony_ci     *  if requestRect of systemBar equals to winRect, not need to resize. This may happen when rotate display
692e0dac50fSopenharmony_ci     */
693e0dac50fSopenharmony_ci    if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
694e0dac50fSopenharmony_ci        if ((reason== WindowSizeChangeReason::MOVE || reason == WindowSizeChangeReason::RESIZE) &&
695e0dac50fSopenharmony_ci            rect == node->GetWindowRect()) {
696e0dac50fSopenharmony_ci            return WMError::WM_OK;
697e0dac50fSopenharmony_ci        }
698e0dac50fSopenharmony_ci    }
699e0dac50fSopenharmony_ci    auto property = node->GetWindowProperty();
700e0dac50fSopenharmony_ci    node->SetWindowSizeChangeReason(reason);
701e0dac50fSopenharmony_ci    Rect lastRect = property->GetWindowRect();
702e0dac50fSopenharmony_ci    Rect newRect;
703e0dac50fSopenharmony_ci    if (reason == WindowSizeChangeReason::MOVE) {
704e0dac50fSopenharmony_ci        newRect = { rect.posX_, rect.posY_, lastRect.width_, lastRect.height_ };
705e0dac50fSopenharmony_ci        if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
706e0dac50fSopenharmony_ci            if (windowRoot_->IsForbidDockSliceMove(node->GetDisplayId())) {
707e0dac50fSopenharmony_ci                WLOGI("dock slice is forbidden to move");
708e0dac50fSopenharmony_ci                newRect = lastRect;
709e0dac50fSopenharmony_ci            } else if (windowRoot_->IsVerticalDisplay(node)) {
710e0dac50fSopenharmony_ci                newRect.posX_ = lastRect.posX_;
711e0dac50fSopenharmony_ci            } else {
712e0dac50fSopenharmony_ci                newRect.posY_ = lastRect.posY_;
713e0dac50fSopenharmony_ci            }
714e0dac50fSopenharmony_ci        }
715e0dac50fSopenharmony_ci    } else if (reason == WindowSizeChangeReason::RESIZE) {
716e0dac50fSopenharmony_ci        newRect = { lastRect.posX_, lastRect.posY_, rect.width_, rect.height_ };
717e0dac50fSopenharmony_ci    } else if (reason == WindowSizeChangeReason::DRAG || reason == WindowSizeChangeReason::MAXIMIZE) {
718e0dac50fSopenharmony_ci        newRect = rect;
719e0dac50fSopenharmony_ci    }
720e0dac50fSopenharmony_ci    property->SetRequestRect(newRect);
721e0dac50fSopenharmony_ci    if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
722e0dac50fSopenharmony_ci        (reason == WindowSizeChangeReason::RESIZE || reason == WindowSizeChangeReason::MOVE)) {
723e0dac50fSopenharmony_ci        RelayoutKeyboard(node);
724e0dac50fSopenharmony_ci        ResizeSoftInputCallingWindowIfNeed(node);
725e0dac50fSopenharmony_ci    }
726e0dac50fSopenharmony_ci    WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_RECT);
727e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
728e0dac50fSopenharmony_ci        return res;
729e0dac50fSopenharmony_ci    }
730e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
731e0dac50fSopenharmony_ci    return WMError::WM_OK;
732e0dac50fSopenharmony_ci}
733e0dac50fSopenharmony_ci
734e0dac50fSopenharmony_ciWMError WindowController::ResizeRectAndFlush(uint32_t windowId, const Rect& rect, WindowSizeChangeReason reason)
735e0dac50fSopenharmony_ci{
736e0dac50fSopenharmony_ci    WMError res = ResizeRect(windowId, rect, reason);
737e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
738e0dac50fSopenharmony_ci        return res;
739e0dac50fSopenharmony_ci    } else {
740e0dac50fSopenharmony_ci        FlushWindowInfo(windowId);
741e0dac50fSopenharmony_ci        return WMError::WM_OK;
742e0dac50fSopenharmony_ci    }
743e0dac50fSopenharmony_ci}
744e0dac50fSopenharmony_ci
745e0dac50fSopenharmony_ciWMError WindowController::RequestFocus(uint32_t windowId)
746e0dac50fSopenharmony_ci{
747e0dac50fSopenharmony_ci    if (windowRoot_ == nullptr) {
748e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
749e0dac50fSopenharmony_ci    }
750e0dac50fSopenharmony_ci    WMError res = windowRoot_->RequestFocus(windowId);
751e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
752e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(windowRoot_->GetWindowNode(windowId),
753e0dac50fSopenharmony_ci        WindowUpdateType::WINDOW_UPDATE_FOCUSED);
754e0dac50fSopenharmony_ci    return res;
755e0dac50fSopenharmony_ci}
756e0dac50fSopenharmony_ci
757e0dac50fSopenharmony_ciWMError WindowController::SetWindowMode(uint32_t windowId, WindowMode dstMode)
758e0dac50fSopenharmony_ci{
759e0dac50fSopenharmony_ci    HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
760e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
761e0dac50fSopenharmony_ci    if (node == nullptr) {
762e0dac50fSopenharmony_ci        WLOGFE("could not find window");
763e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
764e0dac50fSopenharmony_ci    }
765e0dac50fSopenharmony_ci    WMError ret = windowRoot_->SetWindowMode(node, dstMode);
766e0dac50fSopenharmony_ci    if (ret != WMError::WM_OK) {
767e0dac50fSopenharmony_ci        return ret;
768e0dac50fSopenharmony_ci    }
769e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
770e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
771e0dac50fSopenharmony_ci    if (!node->stateMachine_.IsShowAnimationPlaying()) {
772e0dac50fSopenharmony_ci        if (WindowHelper::IsMainWindow(node->GetWindowType())) {
773e0dac50fSopenharmony_ci            MinimizeApp::ExecuteMinimizeAll();
774e0dac50fSopenharmony_ci            WLOGI("id:%{public}u execute minimize all", node->GetWindowId());
775e0dac50fSopenharmony_ci        }
776e0dac50fSopenharmony_ci    }
777e0dac50fSopenharmony_ci    return WMError::WM_OK;
778e0dac50fSopenharmony_ci}
779e0dac50fSopenharmony_ci
780e0dac50fSopenharmony_civoid WindowController::NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
781e0dac50fSopenharmony_ci    const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
782e0dac50fSopenharmony_ci{
783e0dac50fSopenharmony_ci    WLOGFD("NotifyDisplayStateChange start: %{public}u", type);
784e0dac50fSopenharmony_ci    switch (type) {
785e0dac50fSopenharmony_ci        case DisplayStateChangeType::BEFORE_SUSPEND: {
786e0dac50fSopenharmony_ci            isScreenLocked_ = true;
787e0dac50fSopenharmony_ci            windowRoot_->ProcessWindowStateChange(WindowState::STATE_FROZEN, WindowStateChangeReason::KEYGUARD);
788e0dac50fSopenharmony_ci            break;
789e0dac50fSopenharmony_ci        }
790e0dac50fSopenharmony_ci        case DisplayStateChangeType::BEFORE_UNLOCK: {
791e0dac50fSopenharmony_ci            windowRoot_->ProcessWindowStateChange(WindowState::STATE_UNFROZEN, WindowStateChangeReason::KEYGUARD);
792e0dac50fSopenharmony_ci            isScreenLocked_ = false;
793e0dac50fSopenharmony_ci            break;
794e0dac50fSopenharmony_ci        }
795e0dac50fSopenharmony_ci        case DisplayStateChangeType::CREATE: {
796e0dac50fSopenharmony_ci            SetDefaultDisplayInfo(defaultDisplayId, displayInfo);
797e0dac50fSopenharmony_ci            windowRoot_->ProcessDisplayCreate(defaultDisplayId, displayInfo, displayInfoMap);
798e0dac50fSopenharmony_ci            FlushWindowInfoWithDisplayId(displayInfo->GetDisplayId());
799e0dac50fSopenharmony_ci            break;
800e0dac50fSopenharmony_ci        }
801e0dac50fSopenharmony_ci        case DisplayStateChangeType::DESTROY: {
802e0dac50fSopenharmony_ci            windowRoot_->ProcessDisplayDestroy(defaultDisplayId, displayInfo, displayInfoMap);
803e0dac50fSopenharmony_ci            FlushWindowInfoWithDisplayId(defaultDisplayId);
804e0dac50fSopenharmony_ci            break;
805e0dac50fSopenharmony_ci        }
806e0dac50fSopenharmony_ci        case DisplayStateChangeType::DISPLAY_COMPRESS:
807e0dac50fSopenharmony_ci        case DisplayStateChangeType::SIZE_CHANGE:
808e0dac50fSopenharmony_ci        case DisplayStateChangeType::UPDATE_ROTATION:
809e0dac50fSopenharmony_ci        case DisplayStateChangeType::UPDATE_ROTATION_FROM_WINDOW:
810e0dac50fSopenharmony_ci        case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
811e0dac50fSopenharmony_ci            ProcessDisplayChange(defaultDisplayId, displayInfo, displayInfoMap, type);
812e0dac50fSopenharmony_ci            /*
813e0dac50fSopenharmony_ci             * Window tile num may change when display rotate or change size, need to execute minimize
814e0dac50fSopenharmony_ci             */
815e0dac50fSopenharmony_ci            MinimizeApp::ExecuteMinimizeTargetReasons(MinimizeReason::LAYOUT_TILE);
816e0dac50fSopenharmony_ci            break;
817e0dac50fSopenharmony_ci        }
818e0dac50fSopenharmony_ci        default: {
819e0dac50fSopenharmony_ci            WLOGFE("unknown DisplayStateChangeType:%{public}u", type);
820e0dac50fSopenharmony_ci            return;
821e0dac50fSopenharmony_ci        }
822e0dac50fSopenharmony_ci    }
823e0dac50fSopenharmony_ci    WLOGFD("NotifyDisplayStateChange end, type: %{public}u", type);
824e0dac50fSopenharmony_ci}
825e0dac50fSopenharmony_ci
826e0dac50fSopenharmony_civoid WindowController::SetDefaultDisplayInfo(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo)
827e0dac50fSopenharmony_ci{
828e0dac50fSopenharmony_ci    if (displayInfo == nullptr) {
829e0dac50fSopenharmony_ci        WLOGFE("display is null");
830e0dac50fSopenharmony_ci        return;
831e0dac50fSopenharmony_ci    }
832e0dac50fSopenharmony_ci    if (displayInfo->GetDisplayId() != defaultDisplayId) {
833e0dac50fSopenharmony_ci        return;
834e0dac50fSopenharmony_ci    }
835e0dac50fSopenharmony_ci    WLOGI("Set defaultDisplayInfo");
836e0dac50fSopenharmony_ci    auto displayWidth = static_cast<uint32_t>(displayInfo->GetWidth());
837e0dac50fSopenharmony_ci    auto displayHeight = static_cast<uint32_t>(displayInfo->GetHeight());
838e0dac50fSopenharmony_ci    defaultDisplayRect_ = { 0, 0, displayWidth, displayHeight };
839e0dac50fSopenharmony_ci}
840e0dac50fSopenharmony_ci
841e0dac50fSopenharmony_civoid WindowController::ProcessDisplayChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
842e0dac50fSopenharmony_ci    const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
843e0dac50fSopenharmony_ci{
844e0dac50fSopenharmony_ci    if (displayInfo == nullptr) {
845e0dac50fSopenharmony_ci        WLOGFE("get display failed");
846e0dac50fSopenharmony_ci        return;
847e0dac50fSopenharmony_ci    }
848e0dac50fSopenharmony_ci    auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayInfo->GetDisplayId());
849e0dac50fSopenharmony_ci    if (windowNodeContainer != nullptr) {
850e0dac50fSopenharmony_ci        windowNodeContainer->BeforeProcessWindowAvoidAreaChangeWhenDisplayChange();
851e0dac50fSopenharmony_ci        DisplayGroupInfo::GetInstance().UpdateDisplayInfo(displayInfo);
852e0dac50fSopenharmony_ci    }
853e0dac50fSopenharmony_ci    switch (type) {
854e0dac50fSopenharmony_ci        case DisplayStateChangeType::DISPLAY_COMPRESS:
855e0dac50fSopenharmony_ci            ProcessDisplayCompression(defaultDisplayId, displayInfo);
856e0dac50fSopenharmony_ci            [[fallthrough]];
857e0dac50fSopenharmony_ci        case DisplayStateChangeType::SIZE_CHANGE:
858e0dac50fSopenharmony_ci        case DisplayStateChangeType::UPDATE_ROTATION:
859e0dac50fSopenharmony_ci        case DisplayStateChangeType::UPDATE_ROTATION_FROM_WINDOW:
860e0dac50fSopenharmony_ci        case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
861e0dac50fSopenharmony_ci            windowRoot_->ProcessDisplayChange(defaultDisplayId, displayInfo, displayInfoMap, type);
862e0dac50fSopenharmony_ci            break;
863e0dac50fSopenharmony_ci        }
864e0dac50fSopenharmony_ci        default: {
865e0dac50fSopenharmony_ci            WLOGFE("unknown DisplayStateChangeType:%{public}u", type);
866e0dac50fSopenharmony_ci            return;
867e0dac50fSopenharmony_ci        }
868e0dac50fSopenharmony_ci    }
869e0dac50fSopenharmony_ci    auto displayId = displayInfo->GetDisplayId();
870e0dac50fSopenharmony_ci    displayZoomController_->UpdateAllWindowsZoomInfo(displayId);
871e0dac50fSopenharmony_ci    FlushWindowInfoWithDisplayId(displayId);
872e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(displayId, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
873e0dac50fSopenharmony_ci    if (windowNodeContainer != nullptr) {
874e0dac50fSopenharmony_ci        windowNodeContainer->ProcessWindowAvoidAreaChangeWhenDisplayChange();
875e0dac50fSopenharmony_ci    }
876e0dac50fSopenharmony_ci}
877e0dac50fSopenharmony_ci
878e0dac50fSopenharmony_civoid WindowController::ProcessDisplayCompression(DisplayId defaultDisplayId, const sptr<DisplayInfo>& displayInfo)
879e0dac50fSopenharmony_ci{
880e0dac50fSopenharmony_ci    WLOGI("Enter processDisplayCompress");
881e0dac50fSopenharmony_ci    DisplayId displayId = displayInfo->GetDisplayId();
882e0dac50fSopenharmony_ci    if (displayId != defaultDisplayId) {
883e0dac50fSopenharmony_ci        WLOGI("Not default display");
884e0dac50fSopenharmony_ci        return;
885e0dac50fSopenharmony_ci    }
886e0dac50fSopenharmony_ci    auto& dms = DisplayManagerServiceInner::GetInstance();
887e0dac50fSopenharmony_ci    if (!displayInfo->GetWaterfallDisplayCompressionStatus()) {
888e0dac50fSopenharmony_ci        if (maskingSurfaceNode_ == nullptr) {
889e0dac50fSopenharmony_ci            WLOGFD("MaskingSurfaceNode is not created");
890e0dac50fSopenharmony_ci            return;
891e0dac50fSopenharmony_ci        } else {
892e0dac50fSopenharmony_ci            WLOGFD("Remove maskingSurfaceNode");
893e0dac50fSopenharmony_ci            dms.UpdateRSTree(displayId, displayId, maskingSurfaceNode_, false, false);
894e0dac50fSopenharmony_ci            maskingSurfaceNode_ = nullptr;
895e0dac50fSopenharmony_ci            return;
896e0dac50fSopenharmony_ci        }
897e0dac50fSopenharmony_ci    }
898e0dac50fSopenharmony_ci    WLOGFD("Add maskingSurfaceNode");
899e0dac50fSopenharmony_ci    struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
900e0dac50fSopenharmony_ci    rsSurfaceNodeConfig.SurfaceNodeName = "maskingSurface";
901e0dac50fSopenharmony_ci    maskingSurfaceNode_ = RSSurfaceNode::Create(rsSurfaceNodeConfig);
902e0dac50fSopenharmony_ci    if (maskingSurfaceNode_ == nullptr) {
903e0dac50fSopenharmony_ci        WLOGFE("Create maskingSurfaceNode failed");
904e0dac50fSopenharmony_ci        return;
905e0dac50fSopenharmony_ci    }
906e0dac50fSopenharmony_ci    auto displayWidth = displayInfo->GetWidth();
907e0dac50fSopenharmony_ci    auto displayHeight = displayInfo->GetHeight();
908e0dac50fSopenharmony_ci    auto maskingSizeX = displayInfo->GetOffsetX();
909e0dac50fSopenharmony_ci    auto maskingSizeY = displayInfo->GetOffsetY();
910e0dac50fSopenharmony_ci    auto fullDisplayWidth = displayWidth + maskingSizeX * 2; // *2: Get full width.
911e0dac50fSopenharmony_ci    auto fullDisplayHeight = displayHeight + maskingSizeY * 2; // *2: Get full height.
912e0dac50fSopenharmony_ci
913e0dac50fSopenharmony_ci    Rect screenRect = Rect {0, 0, fullDisplayWidth, fullDisplayHeight};
914e0dac50fSopenharmony_ci    Rect transparentRect = Rect {maskingSizeX, maskingSizeY, displayWidth, displayHeight};
915e0dac50fSopenharmony_ci    WLOGFD("ScreenRect: fullDisplayWidth: %{public}d, fullDisplayHeight: %{public}d",
916e0dac50fSopenharmony_ci        fullDisplayWidth, fullDisplayHeight);
917e0dac50fSopenharmony_ci    WLOGFD("TransparentRect: X: %{public}u, Y: %{public}u, Width: %{public}d, Height: %{public}d",
918e0dac50fSopenharmony_ci        maskingSizeX, maskingSizeY, displayWidth, displayHeight);
919e0dac50fSopenharmony_ci
920e0dac50fSopenharmony_ci    maskingSurfaceNode_->SetPositionZ(MASKING_SURFACE_NODE_Z_ORDER);
921e0dac50fSopenharmony_ci
922e0dac50fSopenharmony_ci    if (!SurfaceDraw::DrawMasking(maskingSurfaceNode_, screenRect, transparentRect)) {
923e0dac50fSopenharmony_ci        WLOGFE("Draw masking surface failed");
924e0dac50fSopenharmony_ci        return;
925e0dac50fSopenharmony_ci    }
926e0dac50fSopenharmony_ci    maskingSurfaceNode_->SetBounds(0, 0, fullDisplayWidth, fullDisplayHeight);
927e0dac50fSopenharmony_ci    dms.UpdateRSTree(displayId, displayId, maskingSurfaceNode_, true, false);
928e0dac50fSopenharmony_ci}
929e0dac50fSopenharmony_ci
930e0dac50fSopenharmony_civoid WindowController::StopBootAnimationIfNeed(const sptr<WindowNode>& node)
931e0dac50fSopenharmony_ci{
932e0dac50fSopenharmony_ci    if (isBootAnimationStopped_) {
933e0dac50fSopenharmony_ci        return;
934e0dac50fSopenharmony_ci    }
935e0dac50fSopenharmony_ci    if (node == nullptr) {
936e0dac50fSopenharmony_ci        WLOGFE("Node is nullptr");
937e0dac50fSopenharmony_ci        return;
938e0dac50fSopenharmony_ci    }
939e0dac50fSopenharmony_ci    if (node->GetDisplayId() != DisplayGroupInfo::GetInstance().GetDefaultDisplayId()) {
940e0dac50fSopenharmony_ci        return;
941e0dac50fSopenharmony_ci    }
942e0dac50fSopenharmony_ci    auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
943e0dac50fSopenharmony_ci    if (windowNodeContainer == nullptr) {
944e0dac50fSopenharmony_ci        WLOGFE("Node container is nullptr");
945e0dac50fSopenharmony_ci        return;
946e0dac50fSopenharmony_ci    }
947e0dac50fSopenharmony_ci    std::vector<sptr<WindowNode>> windowNodes;
948e0dac50fSopenharmony_ci    windowNodeContainer->TraverseContainer(windowNodes);
949e0dac50fSopenharmony_ci    WmOcclusion::Rect defaultDisplayRect = { defaultDisplayRect_.posX_, defaultDisplayRect_.posY_,
950e0dac50fSopenharmony_ci        defaultDisplayRect_.posX_ + static_cast<int32_t>(defaultDisplayRect_.width_),
951e0dac50fSopenharmony_ci        defaultDisplayRect_.posY_ + static_cast<int32_t>(defaultDisplayRect_.height_)};
952e0dac50fSopenharmony_ci    WmOcclusion::Region defaultDisplayRegion(defaultDisplayRect);
953e0dac50fSopenharmony_ci    WmOcclusion::Region allRegion; // Counts the area of all shown windows
954e0dac50fSopenharmony_ci    for (auto& node : windowNodes) {
955e0dac50fSopenharmony_ci        if (node->GetWindowType() == WindowType::WINDOW_TYPE_BOOT_ANIMATION) {
956e0dac50fSopenharmony_ci            continue;
957e0dac50fSopenharmony_ci        }
958e0dac50fSopenharmony_ci        auto windowRect = node->GetWindowRect();
959e0dac50fSopenharmony_ci        WmOcclusion::Rect curRect = { windowRect.posX_, windowRect.posY_,
960e0dac50fSopenharmony_ci            windowRect.posX_ + static_cast<int32_t>(windowRect.width_),
961e0dac50fSopenharmony_ci            windowRect.posY_ + static_cast<int32_t>(windowRect.height_)};
962e0dac50fSopenharmony_ci        WmOcclusion::Region curRegion(curRect);
963e0dac50fSopenharmony_ci        allRegion = curRegion.Or(allRegion);
964e0dac50fSopenharmony_ci        WmOcclusion::Region subResult = defaultDisplayRegion.Sub(allRegion);
965e0dac50fSopenharmony_ci        if (subResult.GetSize() == 0) {
966e0dac50fSopenharmony_ci            WLOGI("stop boot animation");
967e0dac50fSopenharmony_ci            system::SetParameter("bootevent.wms.fullscreen.ready", "true");
968e0dac50fSopenharmony_ci            isBootAnimationStopped_ = true;
969e0dac50fSopenharmony_ci            RecordBootAnimationEvent();
970e0dac50fSopenharmony_ci            DisplayManagerServiceInner::GetInstance().SetGravitySensorSubscriptionEnabled();
971e0dac50fSopenharmony_ci        }
972e0dac50fSopenharmony_ci    }
973e0dac50fSopenharmony_ci}
974e0dac50fSopenharmony_ci
975e0dac50fSopenharmony_civoid WindowController::RecordBootAnimationEvent() const
976e0dac50fSopenharmony_ci{
977e0dac50fSopenharmony_ci    uint64_t time = static_cast<uint64_t>(std::chrono::time_point_cast<std::chrono::seconds>
978e0dac50fSopenharmony_ci        (std::chrono::steady_clock::now()).time_since_epoch().count());
979e0dac50fSopenharmony_ci    WLOGI("boot animation done duration(s): %{public}" PRIu64"", time);
980e0dac50fSopenharmony_ci    std::ostringstream os;
981e0dac50fSopenharmony_ci    os << "boot animation done duration(s): " << time <<";";
982e0dac50fSopenharmony_ci    int32_t ret = HiSysEventWrite(
983e0dac50fSopenharmony_ci        OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
984e0dac50fSopenharmony_ci        "WINDOW_BOOT_ANIMATION_DONE",
985e0dac50fSopenharmony_ci        OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
986e0dac50fSopenharmony_ci        "MSG", os.str());
987e0dac50fSopenharmony_ci    if (ret != 0) {
988e0dac50fSopenharmony_ci        WLOGFE("Write HiSysEvent error, ret:%{public}d", ret);
989e0dac50fSopenharmony_ci    }
990e0dac50fSopenharmony_ci}
991e0dac50fSopenharmony_ci
992e0dac50fSopenharmony_cistd::shared_ptr<Media::PixelMap> WindowController::GetSnapshot(int32_t windowId)
993e0dac50fSopenharmony_ci{
994e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
995e0dac50fSopenharmony_ci    if (node == nullptr) {
996e0dac50fSopenharmony_ci        WLOGFE("could not find window");
997e0dac50fSopenharmony_ci        return nullptr;
998e0dac50fSopenharmony_ci    }
999e0dac50fSopenharmony_ci    auto callback = std::make_shared<SurfaceCaptureFuture>();
1000e0dac50fSopenharmony_ci    bool ret = RSInterfaces::GetInstance().TakeSurfaceCapture(node->surfaceNode_, callback);
1001e0dac50fSopenharmony_ci    if (!ret) {
1002e0dac50fSopenharmony_ci        WLOGFE("takeSurfaceCapture failed");
1003e0dac50fSopenharmony_ci        return nullptr;
1004e0dac50fSopenharmony_ci    }
1005e0dac50fSopenharmony_ci    return callback->GetResult(SNAPSHOT_TIMEOUT_MS);
1006e0dac50fSopenharmony_ci}
1007e0dac50fSopenharmony_ci
1008e0dac50fSopenharmony_ciWMError WindowController::SetWindowType(uint32_t windowId, WindowType type)
1009e0dac50fSopenharmony_ci{
1010e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1011e0dac50fSopenharmony_ci    if (node == nullptr) {
1012e0dac50fSopenharmony_ci        WLOGFE("could not find window");
1013e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1014e0dac50fSopenharmony_ci    }
1015e0dac50fSopenharmony_ci    auto property = node->GetWindowProperty();
1016e0dac50fSopenharmony_ci    property->SetWindowType(type);
1017e0dac50fSopenharmony_ci    UpdateWindowAnimation(node);
1018e0dac50fSopenharmony_ci    WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_TYPE);
1019e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
1020e0dac50fSopenharmony_ci        return res;
1021e0dac50fSopenharmony_ci    }
1022e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
1023e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1024e0dac50fSopenharmony_ci    WLOGI("SetWindowType end");
1025e0dac50fSopenharmony_ci    return res;
1026e0dac50fSopenharmony_ci}
1027e0dac50fSopenharmony_ci
1028e0dac50fSopenharmony_ciWMError WindowController::SetWindowFlags(uint32_t windowId, uint32_t flags, bool isSystemCalling)
1029e0dac50fSopenharmony_ci{
1030e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1031e0dac50fSopenharmony_ci    if (node == nullptr) {
1032e0dac50fSopenharmony_ci        WLOGFE("could not find window");
1033e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1034e0dac50fSopenharmony_ci    }
1035e0dac50fSopenharmony_ci    auto property = node->GetWindowProperty();
1036e0dac50fSopenharmony_ci    uint32_t oldFlags = property->GetWindowFlags();
1037e0dac50fSopenharmony_ci    if (property->GetApiCompatibleVersion() >= 9 && !isSystemCalling && // 9: api version.
1038e0dac50fSopenharmony_ci        (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
1039e0dac50fSopenharmony_ci        WLOGFW("Only API 9- or system calling support showing when locked.");
1040e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_PERMISSION;
1041e0dac50fSopenharmony_ci    }
1042e0dac50fSopenharmony_ci    property->SetWindowFlags(flags);
1043e0dac50fSopenharmony_ci    // only forbid_split_move flag change, just set property
1044e0dac50fSopenharmony_ci    if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE)) {
1045e0dac50fSopenharmony_ci        return WMError::WM_OK;
1046e0dac50fSopenharmony_ci    }
1047e0dac50fSopenharmony_ci    WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_FLAGS);
1048e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
1049e0dac50fSopenharmony_ci        return res;
1050e0dac50fSopenharmony_ci    }
1051e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
1052e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1053e0dac50fSopenharmony_ci    WLOGI("SetWindowFlags end");
1054e0dac50fSopenharmony_ci    return res;
1055e0dac50fSopenharmony_ci}
1056e0dac50fSopenharmony_ci
1057e0dac50fSopenharmony_ciWMError WindowController::SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& property)
1058e0dac50fSopenharmony_ci{
1059e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1060e0dac50fSopenharmony_ci    if (node == nullptr) {
1061e0dac50fSopenharmony_ci        WLOGFE("could not find window");
1062e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1063e0dac50fSopenharmony_ci    }
1064e0dac50fSopenharmony_ci    node->SetSystemBarProperty(type, property);
1065e0dac50fSopenharmony_ci    WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_OTHER_PROPS);
1066e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
1067e0dac50fSopenharmony_ci        return res;
1068e0dac50fSopenharmony_ci    }
1069e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
1070e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1071e0dac50fSopenharmony_ci    WLOGI("SetSystemBarProperty end");
1072e0dac50fSopenharmony_ci    return res;
1073e0dac50fSopenharmony_ci}
1074e0dac50fSopenharmony_ci
1075e0dac50fSopenharmony_civoid WindowController::NotifySystemBarTints()
1076e0dac50fSopenharmony_ci{
1077e0dac50fSopenharmony_ci    windowRoot_->NotifySystemBarTints();
1078e0dac50fSopenharmony_ci}
1079e0dac50fSopenharmony_ci
1080e0dac50fSopenharmony_ciWMError WindowController::SetWindowAnimationController(const sptr<RSIWindowAnimationController>& controller)
1081e0dac50fSopenharmony_ci{
1082e0dac50fSopenharmony_ci    return RemoteAnimation::SetWindowAnimationController(controller);
1083e0dac50fSopenharmony_ci}
1084e0dac50fSopenharmony_ci
1085e0dac50fSopenharmony_ciAvoidArea WindowController::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType avoidAreaType) const
1086e0dac50fSopenharmony_ci{
1087e0dac50fSopenharmony_ci    return windowRoot_->GetAvoidAreaByType(windowId, avoidAreaType);
1088e0dac50fSopenharmony_ci}
1089e0dac50fSopenharmony_ci
1090e0dac50fSopenharmony_ciWMError WindowController::ChangeMouseStyle(uint32_t windowId, sptr<MoveDragProperty>& moveDragProperty)
1091e0dac50fSopenharmony_ci{
1092e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1093e0dac50fSopenharmony_ci    int32_t mouseStyle = 0;
1094e0dac50fSopenharmony_ci    MMI::PointerStyle pointerStyle;
1095e0dac50fSopenharmony_ci    if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1096e0dac50fSopenharmony_ci        if (node->GetWindowRect().width_ > node->GetWindowRect().height_) {
1097e0dac50fSopenharmony_ci            mouseStyle = MMI::MOUSE_ICON::NORTH_SOUTH;
1098e0dac50fSopenharmony_ci        } else {
1099e0dac50fSopenharmony_ci            mouseStyle = MMI::MOUSE_ICON::WEST_EAST;
1100e0dac50fSopenharmony_ci        }
1101e0dac50fSopenharmony_ci        pointerStyle.id = mouseStyle;
1102e0dac50fSopenharmony_ci        int32_t res = MMI::InputManager::GetInstance()->SetPointerStyle(windowId, pointerStyle);
1103e0dac50fSopenharmony_ci        if (res != 0) {
1104e0dac50fSopenharmony_ci            WLOGFE("set pointer style failed");
1105e0dac50fSopenharmony_ci            return WMError::WM_ERROR_INVALID_OPERATION;
1106e0dac50fSopenharmony_ci        }
1107e0dac50fSopenharmony_ci        return WMError::WM_OK;
1108e0dac50fSopenharmony_ci    }
1109e0dac50fSopenharmony_ci    pointerStyle.id = STYLEID_MAP.at(moveDragProperty->dragType_);
1110e0dac50fSopenharmony_ci    int32_t res = MMI::InputManager::GetInstance()->SetPointerStyle(windowId, pointerStyle);
1111e0dac50fSopenharmony_ci    if (res != 0) {
1112e0dac50fSopenharmony_ci        WLOGFE("set pointer style failed");
1113e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_OPERATION;
1114e0dac50fSopenharmony_ci    }
1115e0dac50fSopenharmony_ci    return WMError::WM_OK;
1116e0dac50fSopenharmony_ci}
1117e0dac50fSopenharmony_ci
1118e0dac50fSopenharmony_ciWMError WindowController::NotifyServerReadyToMoveOrDrag(uint32_t windowId, sptr<MoveDragProperty>& moveDragProperty)
1119e0dac50fSopenharmony_ci{
1120e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1121e0dac50fSopenharmony_ci    if (node == nullptr) {
1122e0dac50fSopenharmony_ci        WLOGFW("could not find window");
1123e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1124e0dac50fSopenharmony_ci    }
1125e0dac50fSopenharmony_ci    if (!node->currentVisibility_) {
1126e0dac50fSopenharmony_ci        WLOGFE("Window is invisible, windowId: %{public}u", windowId);
1127e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_OPERATION;
1128e0dac50fSopenharmony_ci    }
1129e0dac50fSopenharmony_ci
1130e0dac50fSopenharmony_ci    if (node->GetWindowProperty()->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
1131e0dac50fSopenharmony_ci        return WMError::WM_OK;
1132e0dac50fSopenharmony_ci    }
1133e0dac50fSopenharmony_ci
1134e0dac50fSopenharmony_ci    // if start dragging or start moving dock_slice, need to update size change reason
1135e0dac50fSopenharmony_ci    if ((moveDragProperty->startMoveFlag_ && node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) ||
1136e0dac50fSopenharmony_ci        moveDragProperty->startDragFlag_) {
1137e0dac50fSopenharmony_ci        WMError res = windowRoot_->UpdateSizeChangeReason(windowId, WindowSizeChangeReason::DRAG_START);
1138e0dac50fSopenharmony_ci        ChangeMouseStyle(windowId, moveDragProperty);
1139e0dac50fSopenharmony_ci        if (node->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && dragFrameGravity_ != INVALID_GRAVITY) {
1140e0dac50fSopenharmony_ci            if (node->surfaceNode_) {
1141e0dac50fSopenharmony_ci                node->surfaceNode_->SetFrameGravity(static_cast<Gravity>(dragFrameGravity_));
1142e0dac50fSopenharmony_ci            }
1143e0dac50fSopenharmony_ci        }
1144e0dac50fSopenharmony_ci        return res;
1145e0dac50fSopenharmony_ci    }
1146e0dac50fSopenharmony_ci    return WMError::WM_OK;
1147e0dac50fSopenharmony_ci}
1148e0dac50fSopenharmony_ci
1149e0dac50fSopenharmony_ciWMError WindowController::ProcessPointDown(uint32_t windowId, bool isPointDown)
1150e0dac50fSopenharmony_ci{
1151e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1152e0dac50fSopenharmony_ci    if (node == nullptr) {
1153e0dac50fSopenharmony_ci        WLOGFW("could not find window");
1154e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1155e0dac50fSopenharmony_ci    }
1156e0dac50fSopenharmony_ci    if (!node->currentVisibility_) {
1157e0dac50fSopenharmony_ci        WLOGFE("Window is invisible, windowId: %{public}u", windowId);
1158e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_OPERATION;
1159e0dac50fSopenharmony_ci    }
1160e0dac50fSopenharmony_ci
1161e0dac50fSopenharmony_ci    /*
1162e0dac50fSopenharmony_ci     * If not point down, no need to notify touch outside
1163e0dac50fSopenharmony_ci     */
1164e0dac50fSopenharmony_ci    if (isPointDown) {
1165e0dac50fSopenharmony_ci        NotifyTouchOutside(node);
1166e0dac50fSopenharmony_ci        if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1167e0dac50fSopenharmony_ci            windowRoot_->TakeWindowPairSnapshot(node->GetDisplayId());
1168e0dac50fSopenharmony_ci        }
1169e0dac50fSopenharmony_ci    }
1170e0dac50fSopenharmony_ci
1171e0dac50fSopenharmony_ci    WLOGFD("WindowId: %{public}u", windowId);
1172e0dac50fSopenharmony_ci    WMError zOrderRes = windowRoot_->RaiseZOrderForAppWindow(node);
1173e0dac50fSopenharmony_ci    WMError focusRes = windowRoot_->RequestFocus(windowId);
1174e0dac50fSopenharmony_ci    windowRoot_->RequestActiveWindow(windowId);
1175e0dac50fSopenharmony_ci    windowRoot_->FocusFaultDetection();
1176e0dac50fSopenharmony_ci    if (zOrderRes == WMError::WM_OK || focusRes == WMError::WM_OK) {
1177e0dac50fSopenharmony_ci        FlushWindowInfo(windowId);
1178e0dac50fSopenharmony_ci        accessibilityConnection_->NotifyAccessibilityWindowInfo(windowRoot_->GetWindowNode(windowId),
1179e0dac50fSopenharmony_ci            WindowUpdateType::WINDOW_UPDATE_FOCUSED);
1180e0dac50fSopenharmony_ci        WLOGI("ProcessPointDown end");
1181e0dac50fSopenharmony_ci        return WMError::WM_OK;
1182e0dac50fSopenharmony_ci    }
1183e0dac50fSopenharmony_ci    return WMError::WM_ERROR_INVALID_OPERATION;
1184e0dac50fSopenharmony_ci}
1185e0dac50fSopenharmony_ci
1186e0dac50fSopenharmony_ciWMError WindowController::ProcessPointUp(uint32_t windowId)
1187e0dac50fSopenharmony_ci{
1188e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1189e0dac50fSopenharmony_ci    if (node == nullptr) {
1190e0dac50fSopenharmony_ci        WLOGFW("could not find window");
1191e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1192e0dac50fSopenharmony_ci    }
1193e0dac50fSopenharmony_ci    if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1194e0dac50fSopenharmony_ci        DisplayId displayId = node->GetDisplayId();
1195e0dac50fSopenharmony_ci        if (windowRoot_->IsDockSliceInExitSplitModeArea(displayId)) {
1196e0dac50fSopenharmony_ci            windowRoot_->ExitSplitMode(displayId);
1197e0dac50fSopenharmony_ci        } else {
1198e0dac50fSopenharmony_ci            windowRoot_->ClearWindowPairSnapshot(node->GetDisplayId());
1199e0dac50fSopenharmony_ci            auto property = node->GetWindowProperty();
1200e0dac50fSopenharmony_ci            node->SetWindowSizeChangeReason(WindowSizeChangeReason::DRAG_END);
1201e0dac50fSopenharmony_ci            property->SetRequestRect(property->GetWindowRect());
1202e0dac50fSopenharmony_ci            WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_RECT);
1203e0dac50fSopenharmony_ci            if (res == WMError::WM_OK) {
1204e0dac50fSopenharmony_ci                FlushWindowInfo(windowId);
1205e0dac50fSopenharmony_ci                accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1206e0dac50fSopenharmony_ci            }
1207e0dac50fSopenharmony_ci        }
1208e0dac50fSopenharmony_ci    }
1209e0dac50fSopenharmony_ci    if (node->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && dragFrameGravity_ != INVALID_GRAVITY) {
1210e0dac50fSopenharmony_ci        if (node->surfaceNode_) {
1211e0dac50fSopenharmony_ci            node->surfaceNode_->SetFrameGravity(Gravity::RESIZE);
1212e0dac50fSopenharmony_ci        }
1213e0dac50fSopenharmony_ci    }
1214e0dac50fSopenharmony_ci    WMError res = windowRoot_->UpdateSizeChangeReason(windowId, WindowSizeChangeReason::DRAG_END);
1215e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
1216e0dac50fSopenharmony_ci        return res;
1217e0dac50fSopenharmony_ci    }
1218e0dac50fSopenharmony_ci    return WMError::WM_OK;
1219e0dac50fSopenharmony_ci}
1220e0dac50fSopenharmony_ci
1221e0dac50fSopenharmony_ciWMError WindowController::InterceptInputEventToServer(uint32_t windowId)
1222e0dac50fSopenharmony_ci{
1223e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1224e0dac50fSopenharmony_ci    if (node == nullptr) {
1225e0dac50fSopenharmony_ci        WLOGFW("could not find window");
1226e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1227e0dac50fSopenharmony_ci    }
1228e0dac50fSopenharmony_ci    auto inputPidInServer = WindowInnerManager::GetInstance().GetPid();
1229e0dac50fSopenharmony_ci    WLOGI("InterceptInputEventToServer, windowId: %{public}u, inputPid: %{public}u", windowId, inputPidInServer);
1230e0dac50fSopenharmony_ci    node->SetInputEventCallingPid(static_cast<int32_t>(inputPidInServer));
1231e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
1232e0dac50fSopenharmony_ci    return WMError::WM_OK;
1233e0dac50fSopenharmony_ci}
1234e0dac50fSopenharmony_ci
1235e0dac50fSopenharmony_ciWMError WindowController::RecoverInputEventToClient(uint32_t windowId)
1236e0dac50fSopenharmony_ci{
1237e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1238e0dac50fSopenharmony_ci    if (node == nullptr) {
1239e0dac50fSopenharmony_ci        WLOGFW("could not find window");
1240e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1241e0dac50fSopenharmony_ci    }
1242e0dac50fSopenharmony_ci    if (node->GetInputEventCallingPid() == node->GetCallingPid()) {
1243e0dac50fSopenharmony_ci        WLOGFD("There is no need to recover input event to client");
1244e0dac50fSopenharmony_ci        return WMError::WM_OK;
1245e0dac50fSopenharmony_ci    }
1246e0dac50fSopenharmony_ci
1247e0dac50fSopenharmony_ci    node->SetInputEventCallingPid(node->GetCallingPid());
1248e0dac50fSopenharmony_ci    RecoverDefaultMouseStyle(windowId);
1249e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
1250e0dac50fSopenharmony_ci    return WMError::WM_OK;
1251e0dac50fSopenharmony_ci}
1252e0dac50fSopenharmony_ci
1253e0dac50fSopenharmony_civoid WindowController::RecoverDefaultMouseStyle(uint32_t windowId)
1254e0dac50fSopenharmony_ci{
1255e0dac50fSopenharmony_ci    // asynchronously calls SetMouseStyle of MultiModalInput
1256e0dac50fSopenharmony_ci    MMI::PointerStyle pointerStyle;
1257e0dac50fSopenharmony_ci    pointerStyle.id = MMI::MOUSE_ICON::DEFAULT;
1258e0dac50fSopenharmony_ci    auto task = [this, windowId, pointerStyle]() {
1259e0dac50fSopenharmony_ci        int32_t res = MMI::InputManager::GetInstance()->SetPointerStyle(windowId, pointerStyle);
1260e0dac50fSopenharmony_ci        if (res != 0) {
1261e0dac50fSopenharmony_ci            WLOGFE("set pointer style failed");
1262e0dac50fSopenharmony_ci        }
1263e0dac50fSopenharmony_ci    };
1264e0dac50fSopenharmony_ci    WindowInnerManager::GetInstance().PostTask(task, "RecoverDefaultMouseStyle");
1265e0dac50fSopenharmony_ci}
1266e0dac50fSopenharmony_ci
1267e0dac50fSopenharmony_ci/** @note @window.hierarchy */
1268e0dac50fSopenharmony_ciWMError WindowController::RaiseToAppTop(uint32_t windowId)
1269e0dac50fSopenharmony_ci{
1270e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1271e0dac50fSopenharmony_ci    if (node == nullptr) {
1272e0dac50fSopenharmony_ci        WLOGFW("could not find window");
1273e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1274e0dac50fSopenharmony_ci    }
1275e0dac50fSopenharmony_ci
1276e0dac50fSopenharmony_ci    auto parentNode = node->parent_;
1277e0dac50fSopenharmony_ci    if (parentNode == nullptr) {
1278e0dac50fSopenharmony_ci        WLOGFW("could not find parent");
1279e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_PARENT;
1280e0dac50fSopenharmony_ci    }
1281e0dac50fSopenharmony_ci
1282e0dac50fSopenharmony_ci    WMError zOrderRes = windowRoot_->RaiseZOrderForAppWindow(node);
1283e0dac50fSopenharmony_ci    if (zOrderRes != WMError::WM_OK) {
1284e0dac50fSopenharmony_ci        WLOGFE("Raise subwindow zorder fail, ret: %{public}d", zOrderRes);
1285e0dac50fSopenharmony_ci        return  WMError::WM_DO_NOTHING;
1286e0dac50fSopenharmony_ci    }
1287e0dac50fSopenharmony_ci
1288e0dac50fSopenharmony_ci    UpdateFocusIfNeededWhenRaiseWindow(node);
1289e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
1290e0dac50fSopenharmony_ci    return WMError::WM_OK;
1291e0dac50fSopenharmony_ci}
1292e0dac50fSopenharmony_ci
1293e0dac50fSopenharmony_civoid WindowController::DispatchKeyEvent(uint32_t windowId, std::shared_ptr<MMI::KeyEvent> event)
1294e0dac50fSopenharmony_ci{
1295e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1296e0dac50fSopenharmony_ci    if (node == nullptr) {
1297e0dac50fSopenharmony_ci        WLOGFW("Could not find window");
1298e0dac50fSopenharmony_ci        return;
1299e0dac50fSopenharmony_ci    }
1300e0dac50fSopenharmony_ci    if (node->GetWindowType() != WindowType::WINDOW_TYPE_APP_COMPONENT) {
1301e0dac50fSopenharmony_ci        WLOGFI("Window type is not WINDOW_TYPE_APP_COMPONENT");
1302e0dac50fSopenharmony_ci        return;
1303e0dac50fSopenharmony_ci    }
1304e0dac50fSopenharmony_ci    windowRoot_->DispatchKeyEvent(node, event);
1305e0dac50fSopenharmony_ci}
1306e0dac50fSopenharmony_ci
1307e0dac50fSopenharmony_civoid WindowController::UpdateFocusIfNeededWhenRaiseWindow(const sptr<WindowNode>& node)
1308e0dac50fSopenharmony_ci{
1309e0dac50fSopenharmony_ci    auto property = node->GetWindowProperty();
1310e0dac50fSopenharmony_ci    if (!property->GetFocusable()) {
1311e0dac50fSopenharmony_ci        return;
1312e0dac50fSopenharmony_ci    }
1313e0dac50fSopenharmony_ci    uint32_t windowId = node->GetWindowId();
1314e0dac50fSopenharmony_ci    sptr<WindowNode> focusWindow = nullptr;
1315e0dac50fSopenharmony_ci    WMError res = GetFocusWindowNode(node->GetDisplayId(), focusWindow);
1316e0dac50fSopenharmony_ci    if (res != WMError::WM_OK || focusWindow == nullptr) {
1317e0dac50fSopenharmony_ci        return;
1318e0dac50fSopenharmony_ci    }
1319e0dac50fSopenharmony_ci    if (node->parent_->GetWindowId() == focusWindow->GetWindowId() ||
1320e0dac50fSopenharmony_ci        node->parent_->GetWindowId() == focusWindow->GetParentId()) {
1321e0dac50fSopenharmony_ci        windowRoot_->RequestFocus(windowId);
1322e0dac50fSopenharmony_ci        windowRoot_->RequestActiveWindow(windowId);
1323e0dac50fSopenharmony_ci        windowRoot_->FocusFaultDetection();
1324e0dac50fSopenharmony_ci
1325e0dac50fSopenharmony_ci        accessibilityConnection_->NotifyAccessibilityWindowInfo(windowRoot_->GetWindowNode(windowId),
1326e0dac50fSopenharmony_ci            WindowUpdateType::WINDOW_UPDATE_FOCUSED);
1327e0dac50fSopenharmony_ci    }
1328e0dac50fSopenharmony_ci}
1329e0dac50fSopenharmony_ci
1330e0dac50fSopenharmony_ciWMError WindowController::NotifyWindowClientPointUp(uint32_t windowId,
1331e0dac50fSopenharmony_ci    const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1332e0dac50fSopenharmony_ci{
1333e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1334e0dac50fSopenharmony_ci    if (node == nullptr) {
1335e0dac50fSopenharmony_ci        WLOGFW("could not find window");
1336e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1337e0dac50fSopenharmony_ci    }
1338e0dac50fSopenharmony_ci    if (node->GetWindowToken() != nullptr) {
1339e0dac50fSopenharmony_ci        WLOGI("notify client when receive point_up event, windowId: %{public}u", windowId);
1340e0dac50fSopenharmony_ci        node->GetWindowToken()->NotifyWindowClientPointUp(pointerEvent);
1341e0dac50fSopenharmony_ci    }
1342e0dac50fSopenharmony_ci    return WMError::WM_OK;
1343e0dac50fSopenharmony_ci}
1344e0dac50fSopenharmony_ci
1345e0dac50fSopenharmony_civoid WindowController::MinimizeAllAppWindows(DisplayId displayId)
1346e0dac50fSopenharmony_ci{
1347e0dac50fSopenharmony_ci    windowRoot_->MinimizeAllAppWindows(displayId);
1348e0dac50fSopenharmony_ci    if (RemoteAnimation::NotifyAnimationByHome() != WMError::WM_OK) {
1349e0dac50fSopenharmony_ci        MinimizeApp::ExecuteMinimizeAll();
1350e0dac50fSopenharmony_ci    }
1351e0dac50fSopenharmony_ci}
1352e0dac50fSopenharmony_ci
1353e0dac50fSopenharmony_ciWMError WindowController::ToggleShownStateForAllAppWindows()
1354e0dac50fSopenharmony_ci{
1355e0dac50fSopenharmony_ci    if (isScreenLocked_) {
1356e0dac50fSopenharmony_ci        return WMError::WM_DO_NOTHING;
1357e0dac50fSopenharmony_ci    }
1358e0dac50fSopenharmony_ci    return windowRoot_->ToggleShownStateForAllAppWindows();
1359e0dac50fSopenharmony_ci}
1360e0dac50fSopenharmony_ci
1361e0dac50fSopenharmony_ciWMError WindowController::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
1362e0dac50fSopenharmony_ci{
1363e0dac50fSopenharmony_ci    return windowRoot_->GetTopWindowId(mainWinId, topWinId);
1364e0dac50fSopenharmony_ci}
1365e0dac50fSopenharmony_ci
1366e0dac50fSopenharmony_civoid WindowController::FlushWindowInfo(uint32_t windowId)
1367e0dac50fSopenharmony_ci{
1368e0dac50fSopenharmony_ci    WLOGD("FlushWindowInfo");
1369e0dac50fSopenharmony_ci    displayZoomController_->UpdateWindowZoomInfo(windowId);
1370e0dac50fSopenharmony_ci    RSTransaction::FlushImplicitTransaction();
1371e0dac50fSopenharmony_ci    inputWindowMonitor_->UpdateInputWindow(windowId);
1372e0dac50fSopenharmony_ci}
1373e0dac50fSopenharmony_ci
1374e0dac50fSopenharmony_civoid WindowController::FlushWindowInfoWithDisplayId(DisplayId displayId)
1375e0dac50fSopenharmony_ci{
1376e0dac50fSopenharmony_ci    WLOGFD("DisplayId: %{public}" PRIu64"", displayId);
1377e0dac50fSopenharmony_ci    RSTransaction::FlushImplicitTransaction();
1378e0dac50fSopenharmony_ci    inputWindowMonitor_->UpdateInputWindowByDisplayId(displayId);
1379e0dac50fSopenharmony_ci}
1380e0dac50fSopenharmony_ci
1381e0dac50fSopenharmony_civoid WindowController::UpdateWindowAnimation(const sptr<WindowNode>& node)
1382e0dac50fSopenharmony_ci{
1383e0dac50fSopenharmony_ci    if (node == nullptr || (node->leashWinSurfaceNode_ == nullptr && node->surfaceNode_ == nullptr)) {
1384e0dac50fSopenharmony_ci        WLOGFE("windowNode or surfaceNode is nullptr");
1385e0dac50fSopenharmony_ci        return;
1386e0dac50fSopenharmony_ci    }
1387e0dac50fSopenharmony_ci    const auto& windowAnimationConfig = WindowNodeContainer::GetAnimationConfigRef().windowAnimationConfig_;
1388e0dac50fSopenharmony_ci
1389e0dac50fSopenharmony_ci    uint32_t animationFlag = node->GetWindowProperty()->GetAnimationFlag();
1390e0dac50fSopenharmony_ci    uint32_t windowId = node->GetWindowProperty()->GetWindowId();
1391e0dac50fSopenharmony_ci    WLOGFD("Id: %{public}u, anim_Flag: %{public}u", windowId, animationFlag);
1392e0dac50fSopenharmony_ci    std::shared_ptr<const RSTransitionEffect> effect = nullptr;
1393e0dac50fSopenharmony_ci    if (animationFlag == static_cast<uint32_t>(WindowAnimation::DEFAULT)) {
1394e0dac50fSopenharmony_ci        effect = RSTransitionEffect::Create()
1395e0dac50fSopenharmony_ci            ->Scale(windowAnimationConfig.scale_)
1396e0dac50fSopenharmony_ci            ->Rotate(windowAnimationConfig.rotation_)
1397e0dac50fSopenharmony_ci            ->Translate(windowAnimationConfig.translate_)
1398e0dac50fSopenharmony_ci            ->Opacity(windowAnimationConfig.opacity_);
1399e0dac50fSopenharmony_ci    } else if (animationFlag == static_cast<uint32_t>(WindowAnimation::INPUTE)) {
1400e0dac50fSopenharmony_ci        float translateY = static_cast<float>(node->GetWindowRect().height_);
1401e0dac50fSopenharmony_ci        if (!node->GetWindowRect().height_) {
1402e0dac50fSopenharmony_ci            translateY = static_cast<float>(node->GetRequestRect().height_);
1403e0dac50fSopenharmony_ci        }
1404e0dac50fSopenharmony_ci        effect = RSTransitionEffect::Create()->Translate(Vector3f(0, translateY, 0))->Opacity(1.0f);
1405e0dac50fSopenharmony_ci    };
1406e0dac50fSopenharmony_ci    if (node->leashWinSurfaceNode_) {
1407e0dac50fSopenharmony_ci        node->leashWinSurfaceNode_->SetTransitionEffect(effect);
1408e0dac50fSopenharmony_ci    }
1409e0dac50fSopenharmony_ci    if (node->surfaceNode_) {
1410e0dac50fSopenharmony_ci        node->surfaceNode_->SetTransitionEffect(effect);
1411e0dac50fSopenharmony_ci    }
1412e0dac50fSopenharmony_ci}
1413e0dac50fSopenharmony_ci
1414e0dac50fSopenharmony_ciWMError WindowController::SetWindowLayoutMode(WindowLayoutMode mode)
1415e0dac50fSopenharmony_ci{
1416e0dac50fSopenharmony_ci    WMError res = WMError::WM_OK;
1417e0dac50fSopenharmony_ci    auto displayIds = windowRoot_->GetAllDisplayIds();
1418e0dac50fSopenharmony_ci    for (auto displayId : displayIds) {
1419e0dac50fSopenharmony_ci        res = windowRoot_->SetWindowLayoutMode(displayId, mode);
1420e0dac50fSopenharmony_ci        if (res != WMError::WM_OK) {
1421e0dac50fSopenharmony_ci            return res;
1422e0dac50fSopenharmony_ci        }
1423e0dac50fSopenharmony_ci        displayZoomController_->UpdateAllWindowsZoomInfo(displayId);
1424e0dac50fSopenharmony_ci        FlushWindowInfoWithDisplayId(displayId);
1425e0dac50fSopenharmony_ci        accessibilityConnection_->NotifyAccessibilityWindowInfo(displayId, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1426e0dac50fSopenharmony_ci    }
1427e0dac50fSopenharmony_ci    MinimizeApp::ExecuteMinimizeAll();
1428e0dac50fSopenharmony_ci    return res;
1429e0dac50fSopenharmony_ci}
1430e0dac50fSopenharmony_ci
1431e0dac50fSopenharmony_ciWMError WindowController::UpdateProperty(sptr<WindowProperty>& property, PropertyChangeAction action)
1432e0dac50fSopenharmony_ci{
1433e0dac50fSopenharmony_ci    if (property == nullptr) {
1434e0dac50fSopenharmony_ci        WLOGFE("property is invalid");
1435e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1436e0dac50fSopenharmony_ci    }
1437e0dac50fSopenharmony_ci
1438e0dac50fSopenharmony_ci    uint32_t windowId = property->GetWindowId();
1439e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1440e0dac50fSopenharmony_ci    if (node == nullptr) {
1441e0dac50fSopenharmony_ci        WLOGFE("window is invalid");
1442e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1443e0dac50fSopenharmony_ci    }
1444e0dac50fSopenharmony_ci    WLOGI("Id: %{public}u, action: %{public}u", node->GetWindowId(), static_cast<uint32_t>(action));
1445e0dac50fSopenharmony_ci    WMError ret = WMError::WM_OK;
1446e0dac50fSopenharmony_ci    switch (action) {
1447e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_RECT: {
1448e0dac50fSopenharmony_ci            node->SetDecoStatus(property->GetDecoStatus());
1449e0dac50fSopenharmony_ci            node->SetOriginRect(property->GetOriginRect());
1450e0dac50fSopenharmony_ci            node->SetDragType(property->GetDragType());
1451e0dac50fSopenharmony_ci            ret = ResizeRectAndFlush(windowId, property->GetRequestRect(), property->GetWindowSizeChangeReason());
1452e0dac50fSopenharmony_ci            if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING && ret == WMError::WM_OK &&
1453e0dac50fSopenharmony_ci                callingWindowId_ == windowId && !WindowHelper::IsEmptyRect(callingWindowRestoringRect_)) {
1454e0dac50fSopenharmony_ci                if (property->GetWindowSizeChangeReason() != WindowSizeChangeReason::MOVE) {
1455e0dac50fSopenharmony_ci                    callingWindowId_ = 0u;
1456e0dac50fSopenharmony_ci                    callingWindowRestoringRect_ = { 0, 0, 0, 0 };
1457e0dac50fSopenharmony_ci                } else {
1458e0dac50fSopenharmony_ci                    auto windowRect = node->GetWindowRect();
1459e0dac50fSopenharmony_ci                    callingWindowRestoringRect_.posX_ = windowRect.posX_;
1460e0dac50fSopenharmony_ci                    callingWindowRestoringRect_.posY_ = windowRect.posY_;
1461e0dac50fSopenharmony_ci                }
1462e0dac50fSopenharmony_ci            }
1463e0dac50fSopenharmony_ci            break;
1464e0dac50fSopenharmony_ci        }
1465e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_MODE: {
1466e0dac50fSopenharmony_ci            node->SetDecorEnable(property->GetDecorEnable());
1467e0dac50fSopenharmony_ci            ret = SetWindowMode(windowId, property->GetWindowMode());
1468e0dac50fSopenharmony_ci            break;
1469e0dac50fSopenharmony_ci        }
1470e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_FLAGS: {
1471e0dac50fSopenharmony_ci            ret = SetWindowFlags(windowId, property->GetWindowFlags(), property->isSystemCalling_);
1472e0dac50fSopenharmony_ci            break;
1473e0dac50fSopenharmony_ci        }
1474e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_OTHER_PROPS: {
1475e0dac50fSopenharmony_ci            auto& props = property->GetSystemBarProperty();
1476e0dac50fSopenharmony_ci            for (auto& iter : props) {
1477e0dac50fSopenharmony_ci                SetSystemBarProperty(windowId, iter.first, iter.second);
1478e0dac50fSopenharmony_ci            }
1479e0dac50fSopenharmony_ci            break;
1480e0dac50fSopenharmony_ci        }
1481e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_FOCUSABLE: {
1482e0dac50fSopenharmony_ci            node->SetFocusable(property->GetFocusable());
1483e0dac50fSopenharmony_ci            windowRoot_->UpdateFocusableProperty(windowId);
1484e0dac50fSopenharmony_ci            FlushWindowInfo(windowId);
1485e0dac50fSopenharmony_ci            accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1486e0dac50fSopenharmony_ci            break;
1487e0dac50fSopenharmony_ci        }
1488e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_TOUCHABLE: {
1489e0dac50fSopenharmony_ci            node->SetTouchable(property->GetTouchable());
1490e0dac50fSopenharmony_ci            FlushWindowInfo(windowId);
1491e0dac50fSopenharmony_ci            accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1492e0dac50fSopenharmony_ci            break;
1493e0dac50fSopenharmony_ci        }
1494e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_CALLING_WINDOW: {
1495e0dac50fSopenharmony_ci            node->SetCallingWindow(property->GetCallingWindow());
1496e0dac50fSopenharmony_ci            break;
1497e0dac50fSopenharmony_ci        }
1498e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_ORIENTATION: {
1499e0dac50fSopenharmony_ci            node->SetRequestedOrientation(property->GetRequestedOrientation());
1500e0dac50fSopenharmony_ci            if (WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
1501e0dac50fSopenharmony_ci                DisplayManagerServiceInner::GetInstance().
1502e0dac50fSopenharmony_ci                    SetOrientationFromWindow(node->GetDisplayId(), property->GetRequestedOrientation());
1503e0dac50fSopenharmony_ci            }
1504e0dac50fSopenharmony_ci            break;
1505e0dac50fSopenharmony_ci        }
1506e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON: {
1507e0dac50fSopenharmony_ci            node->SetTurnScreenOn(property->IsTurnScreenOn());
1508e0dac50fSopenharmony_ci            HandleTurnScreenOn(node);
1509e0dac50fSopenharmony_ci            break;
1510e0dac50fSopenharmony_ci        }
1511e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON: {
1512e0dac50fSopenharmony_ci            node->SetKeepScreenOn(property->IsKeepScreenOn());
1513e0dac50fSopenharmony_ci            windowRoot_->HandleKeepScreenOn(node->GetWindowId(), node->IsKeepScreenOn());
1514e0dac50fSopenharmony_ci            break;
1515e0dac50fSopenharmony_ci        }
1516e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS: {
1517e0dac50fSopenharmony_ci            node->SetBrightness(property->GetBrightness());
1518e0dac50fSopenharmony_ci            windowRoot_->SetBrightness(node->GetWindowId(), node->GetBrightness());
1519e0dac50fSopenharmony_ci            break;
1520e0dac50fSopenharmony_ci        }
1521e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO: {
1522e0dac50fSopenharmony_ci            node->SetModeSupportInfo(property->GetModeSupportInfo());
1523e0dac50fSopenharmony_ci            break;
1524e0dac50fSopenharmony_ci        }
1525e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA: {
1526e0dac50fSopenharmony_ci            std::vector<Rect> rects;
1527e0dac50fSopenharmony_ci            property->GetTouchHotAreas(rects);
1528e0dac50fSopenharmony_ci            ret = UpdateTouchHotAreas(node, rects);
1529e0dac50fSopenharmony_ci            break;
1530e0dac50fSopenharmony_ci        }
1531e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG: {
1532e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetAnimationFlag(property->GetAnimationFlag());
1533e0dac50fSopenharmony_ci            UpdateWindowAnimation(node);
1534e0dac50fSopenharmony_ci            break;
1535e0dac50fSopenharmony_ci        }
1536e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_TRANSFORM_PROPERTY: {
1537e0dac50fSopenharmony_ci            node->SetTransform(property->GetTransform());
1538e0dac50fSopenharmony_ci            node->SetWindowSizeChangeReason(WindowSizeChangeReason::TRANSFORM);
1539e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetAnimateWindowFlag(true);
1540e0dac50fSopenharmony_ci            ret = UpdateTransform(windowId);
1541e0dac50fSopenharmony_ci            break;
1542e0dac50fSopenharmony_ci        }
1543e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE: {
1544e0dac50fSopenharmony_ci            bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
1545e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetPrivacyMode(isPrivacyMode);
1546e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetSystemPrivacyMode(isPrivacyMode);
1547e0dac50fSopenharmony_ci            node->surfaceNode_->SetSecurityLayer(isPrivacyMode);
1548e0dac50fSopenharmony_ci            if (node->leashWinSurfaceNode_ != nullptr) {
1549e0dac50fSopenharmony_ci                node->leashWinSurfaceNode_->SetSecurityLayer(isPrivacyMode);
1550e0dac50fSopenharmony_ci            }
1551e0dac50fSopenharmony_ci            RSTransaction::FlushImplicitTransaction();
1552e0dac50fSopenharmony_ci            UpdatePrivateStateAndNotify(node);
1553e0dac50fSopenharmony_ci            break;
1554e0dac50fSopenharmony_ci        }
1555e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE: {
1556e0dac50fSopenharmony_ci            bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
1557e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetPrivacyMode(isPrivacyMode);
1558e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetSystemPrivacyMode(isPrivacyMode);
1559e0dac50fSopenharmony_ci            node->surfaceNode_->SetSecurityLayer(isPrivacyMode);
1560e0dac50fSopenharmony_ci            if (node->leashWinSurfaceNode_ != nullptr) {
1561e0dac50fSopenharmony_ci                node->leashWinSurfaceNode_->SetSecurityLayer(isPrivacyMode);
1562e0dac50fSopenharmony_ci            }
1563e0dac50fSopenharmony_ci            RSTransaction::FlushImplicitTransaction();
1564e0dac50fSopenharmony_ci            UpdatePrivateStateAndNotify(node);
1565e0dac50fSopenharmony_ci            break;
1566e0dac50fSopenharmony_ci        }
1567e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP: {
1568e0dac50fSopenharmony_ci            bool isSnapshotSkip = property->GetSnapshotSkip() || property->GetSystemPrivacyMode();
1569e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetSnapshotSkip(isSnapshotSkip);
1570e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetSystemPrivacyMode(isSnapshotSkip);
1571e0dac50fSopenharmony_ci            node->surfaceNode_->SetSkipLayer(isSnapshotSkip);
1572e0dac50fSopenharmony_ci            if (node->leashWinSurfaceNode_ != nullptr) {
1573e0dac50fSopenharmony_ci                node->leashWinSurfaceNode_->SetSkipLayer(isSnapshotSkip);
1574e0dac50fSopenharmony_ci            }
1575e0dac50fSopenharmony_ci            RSTransaction::FlushImplicitTransaction();
1576e0dac50fSopenharmony_ci            break;
1577e0dac50fSopenharmony_ci        }
1578e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_ASPECT_RATIO: {
1579e0dac50fSopenharmony_ci            ret = SetAspectRatio(windowId, property->GetAspectRatio());
1580e0dac50fSopenharmony_ci            break;
1581e0dac50fSopenharmony_ci        }
1582e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE: {
1583e0dac50fSopenharmony_ci            MaximizeMode mode = property->GetMaximizeMode();
1584e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetMaximizeMode(mode);
1585e0dac50fSopenharmony_ci            Rect newRect = {0, 0, 0, 0};
1586e0dac50fSopenharmony_ci            if (mode == MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
1587e0dac50fSopenharmony_ci                node->SetOriginRect(node->GetWindowRect());
1588e0dac50fSopenharmony_ci                auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
1589e0dac50fSopenharmony_ci                if (windowNodeContainer == nullptr) {
1590e0dac50fSopenharmony_ci                    WLOGFE("window node container is null");
1591e0dac50fSopenharmony_ci                    return WMError::WM_ERROR_NULLPTR;
1592e0dac50fSopenharmony_ci                }
1593e0dac50fSopenharmony_ci                windowNodeContainer->GetLayoutPolicy()->GetMaximizeRect(node, newRect);
1594e0dac50fSopenharmony_ci            } else {
1595e0dac50fSopenharmony_ci                newRect = node->GetOriginRect();
1596e0dac50fSopenharmony_ci            }
1597e0dac50fSopenharmony_ci            WLOGI("window %{public}d maximizeMode %{public}d rect %{public}d %{public}d %{public}d %{public}d",
1598e0dac50fSopenharmony_ci                windowId, static_cast<uint32_t>(mode), newRect.posX_, newRect.posY_, newRect.width_, newRect.height_);
1599e0dac50fSopenharmony_ci            ret = ResizeRectAndFlush(windowId, newRect, WindowSizeChangeReason::MAXIMIZE);
1600e0dac50fSopenharmony_ci            break;
1601e0dac50fSopenharmony_ci        }
1602e0dac50fSopenharmony_ci        case PropertyChangeAction::ACTION_UPDATE_TEXTFIELD_AVOID_INFO: {
1603e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetTextFieldPositionY(property->GetTextFieldPositionY());
1604e0dac50fSopenharmony_ci            node->GetWindowProperty()->SetTextFieldHeight(property->GetTextFieldHeight());
1605e0dac50fSopenharmony_ci            break;
1606e0dac50fSopenharmony_ci        }
1607e0dac50fSopenharmony_ci        default:
1608e0dac50fSopenharmony_ci            break;
1609e0dac50fSopenharmony_ci    }
1610e0dac50fSopenharmony_ci    return ret;
1611e0dac50fSopenharmony_ci}
1612e0dac50fSopenharmony_ci
1613e0dac50fSopenharmony_ciWMError WindowController::SetWindowGravity(uint32_t windowId, WindowGravity gravity, uint32_t percent)
1614e0dac50fSopenharmony_ci{
1615e0dac50fSopenharmony_ci    sptr<WindowNode> node = windowRoot_->GetWindowNode(windowId);
1616e0dac50fSopenharmony_ci    if (node == nullptr) {
1617e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1618e0dac50fSopenharmony_ci    }
1619e0dac50fSopenharmony_ci    if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1620e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_TYPE;
1621e0dac50fSopenharmony_ci    }
1622e0dac50fSopenharmony_ci    node->SetWindowGravity(gravity, percent);
1623e0dac50fSopenharmony_ci    RelayoutKeyboard(node);
1624e0dac50fSopenharmony_ci    if (gravity == WindowGravity::WINDOW_GRAVITY_FLOAT) {
1625e0dac50fSopenharmony_ci        RestoreCallingWindowSizeIfNeed();
1626e0dac50fSopenharmony_ci    } else {
1627e0dac50fSopenharmony_ci        ResizeSoftInputCallingWindowIfNeed(node);
1628e0dac50fSopenharmony_ci    }
1629e0dac50fSopenharmony_ci    WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_RECT);
1630e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
1631e0dac50fSopenharmony_ci        return res;
1632e0dac50fSopenharmony_ci    }
1633e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
1634e0dac50fSopenharmony_ci    return WMError::WM_OK;
1635e0dac50fSopenharmony_ci}
1636e0dac50fSopenharmony_ci
1637e0dac50fSopenharmony_civoid WindowController::UpdatePrivateStateAndNotify(const sptr<WindowNode>& node)
1638e0dac50fSopenharmony_ci{
1639e0dac50fSopenharmony_ci    auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
1640e0dac50fSopenharmony_ci    if (windowNodeContainer == nullptr) {
1641e0dac50fSopenharmony_ci        WLOGFE("window node container is null");
1642e0dac50fSopenharmony_ci        return;
1643e0dac50fSopenharmony_ci    }
1644e0dac50fSopenharmony_ci    windowNodeContainer->UpdatePrivateStateAndNotify();
1645e0dac50fSopenharmony_ci}
1646e0dac50fSopenharmony_ci
1647e0dac50fSopenharmony_ciWMError WindowController::SetAspectRatio(uint32_t windowId, float ratio)
1648e0dac50fSopenharmony_ci{
1649e0dac50fSopenharmony_ci    WLOGI("SetAspectRatio, windowId: %{public}u, %{public}f", windowId, ratio);
1650e0dac50fSopenharmony_ci    HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1651e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1652e0dac50fSopenharmony_ci    if (node == nullptr) {
1653e0dac50fSopenharmony_ci        WLOGFE("could not find window");
1654e0dac50fSopenharmony_ci        return WMError::WM_OK;
1655e0dac50fSopenharmony_ci    }
1656e0dac50fSopenharmony_ci    if (!WindowHelper::IsAspectRatioSatisfiedWithSizeLimits(node->GetWindowUpdatedSizeLimits(), ratio,
1657e0dac50fSopenharmony_ci        DisplayGroupInfo::GetInstance().GetDisplayVirtualPixelRatio(node->GetDisplayId()))) {
1658e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_PARAM;
1659e0dac50fSopenharmony_ci    }
1660e0dac50fSopenharmony_ci
1661e0dac50fSopenharmony_ci    node->SetAspectRatio(ratio);
1662e0dac50fSopenharmony_ci
1663e0dac50fSopenharmony_ci    // perserve aspect ratio
1664e0dac50fSopenharmony_ci    std::vector<std::string> nameVector;
1665e0dac50fSopenharmony_ci    if (node->abilityInfo_.abilityName_.size() > 0) {
1666e0dac50fSopenharmony_ci        nameVector = WindowHelper::Split(node->abilityInfo_.abilityName_, ".");
1667e0dac50fSopenharmony_ci    }
1668e0dac50fSopenharmony_ci    std::string keyName = nameVector.empty() ? node->abilityInfo_.bundleName_ :
1669e0dac50fSopenharmony_ci                                               node->abilityInfo_.bundleName_ + "." + nameVector.back();
1670e0dac50fSopenharmony_ci    if (MathHelper::NearZero(ratio)) { // If ratio is 0.0, need to reset aspect and delete storage
1671e0dac50fSopenharmony_ci        if (PersistentStorage::HasKey(keyName, PersistentStorageType::ASPECT_RATIO)) {
1672e0dac50fSopenharmony_ci            PersistentStorage::Delete(keyName, PersistentStorageType::ASPECT_RATIO);
1673e0dac50fSopenharmony_ci        }
1674e0dac50fSopenharmony_ci        return WMError::WM_OK;
1675e0dac50fSopenharmony_ci    }
1676e0dac50fSopenharmony_ci    PersistentStorage::Insert(keyName, ratio, PersistentStorageType::ASPECT_RATIO);
1677e0dac50fSopenharmony_ci
1678e0dac50fSopenharmony_ci    WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_ASPECT_RATIO);
1679e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
1680e0dac50fSopenharmony_ci        return res;
1681e0dac50fSopenharmony_ci    }
1682e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
1683e0dac50fSopenharmony_ci    return WMError::WM_OK;
1684e0dac50fSopenharmony_ci}
1685e0dac50fSopenharmony_ci
1686e0dac50fSopenharmony_ciWMError WindowController::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos) const
1687e0dac50fSopenharmony_ci{
1688e0dac50fSopenharmony_ci    accessibilityConnection_->GetAccessibilityWindowInfo(infos);
1689e0dac50fSopenharmony_ci    return WMError::WM_OK;
1690e0dac50fSopenharmony_ci}
1691e0dac50fSopenharmony_ci
1692e0dac50fSopenharmony_ciWMError WindowController::GetUnreliableWindowInfo(int32_t windowId,
1693e0dac50fSopenharmony_ci    std::vector<sptr<UnreliableWindowInfo>>& infos) const
1694e0dac50fSopenharmony_ci{
1695e0dac50fSopenharmony_ci    windowRoot_->GetUnreliableWindowInfo(windowId, infos);
1696e0dac50fSopenharmony_ci    return WMError::WM_OK;
1697e0dac50fSopenharmony_ci}
1698e0dac50fSopenharmony_ci
1699e0dac50fSopenharmony_ciWMError WindowController::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos) const
1700e0dac50fSopenharmony_ci{
1701e0dac50fSopenharmony_ci    windowRoot_->GetVisibilityWindowInfo(infos);
1702e0dac50fSopenharmony_ci    return WMError::WM_OK;
1703e0dac50fSopenharmony_ci}
1704e0dac50fSopenharmony_ci
1705e0dac50fSopenharmony_ciWMError WindowController::GetModeChangeHotZones(DisplayId displayId,
1706e0dac50fSopenharmony_ci    ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config)
1707e0dac50fSopenharmony_ci{
1708e0dac50fSopenharmony_ci    return windowRoot_->GetModeChangeHotZones(displayId, hotZones, config);
1709e0dac50fSopenharmony_ci}
1710e0dac50fSopenharmony_ci
1711e0dac50fSopenharmony_ciWMError WindowController::UpdateTouchHotAreas(const sptr<WindowNode>& node, const std::vector<Rect>& rects)
1712e0dac50fSopenharmony_ci{
1713e0dac50fSopenharmony_ci    std::ostringstream oss;
1714e0dac50fSopenharmony_ci    int index = 0;
1715e0dac50fSopenharmony_ci    for (const auto& rect : rects) {
1716e0dac50fSopenharmony_ci        oss << "[ " << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_ << " ]";
1717e0dac50fSopenharmony_ci        index++;
1718e0dac50fSopenharmony_ci        if (index < static_cast<int32_t>(rects.size())) {
1719e0dac50fSopenharmony_ci            oss <<", ";
1720e0dac50fSopenharmony_ci        }
1721e0dac50fSopenharmony_ci    }
1722e0dac50fSopenharmony_ci    WLOGI("windowId: %{public}u, size: %{public}d, rects: %{public}s",
1723e0dac50fSopenharmony_ci        node->GetWindowId(), static_cast<int32_t>(rects.size()), oss.str().c_str());
1724e0dac50fSopenharmony_ci    if (rects.size() > TOUCH_HOT_AREA_MAX_NUM) {
1725e0dac50fSopenharmony_ci        WLOGFE("the number of touch hot areas exceeds the maximum");
1726e0dac50fSopenharmony_ci        return WMError::WM_ERROR_INVALID_PARAM;
1727e0dac50fSopenharmony_ci    }
1728e0dac50fSopenharmony_ci
1729e0dac50fSopenharmony_ci    std::vector<Rect> touchHotAreas;
1730e0dac50fSopenharmony_ci    std::vector<Rect> pointerHotAreas;
1731e0dac50fSopenharmony_ci    if (rects.empty()) {
1732e0dac50fSopenharmony_ci        touchHotAreas.emplace_back(node->GetEntireWindowTouchHotArea());
1733e0dac50fSopenharmony_ci        pointerHotAreas.emplace_back(node->GetEntireWindowPointerHotArea());
1734e0dac50fSopenharmony_ci    } else {
1735e0dac50fSopenharmony_ci        Rect windowRect = node->GetWindowRect();
1736e0dac50fSopenharmony_ci        if (!WindowHelper::CalculateTouchHotAreas(windowRect, rects, touchHotAreas)) {
1737e0dac50fSopenharmony_ci            WLOGFE("the requested touch hot areas are incorrect");
1738e0dac50fSopenharmony_ci            return WMError::WM_ERROR_INVALID_PARAM;
1739e0dac50fSopenharmony_ci        }
1740e0dac50fSopenharmony_ci        pointerHotAreas = touchHotAreas;
1741e0dac50fSopenharmony_ci    }
1742e0dac50fSopenharmony_ci    node->GetWindowProperty()->SetTouchHotAreas(rects);
1743e0dac50fSopenharmony_ci    node->SetTouchHotAreas(touchHotAreas);
1744e0dac50fSopenharmony_ci    node->SetPointerHotAreas(pointerHotAreas);
1745e0dac50fSopenharmony_ci    FlushWindowInfo(node->GetWindowId());
1746e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1747e0dac50fSopenharmony_ci    return WMError::WM_OK;
1748e0dac50fSopenharmony_ci}
1749e0dac50fSopenharmony_ci
1750e0dac50fSopenharmony_ciWMError WindowController::UpdateTransform(uint32_t windowId)
1751e0dac50fSopenharmony_ci{
1752e0dac50fSopenharmony_ci    WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_TRANSFORM);
1753e0dac50fSopenharmony_ci    if (res != WMError::WM_OK) {
1754e0dac50fSopenharmony_ci        return res;
1755e0dac50fSopenharmony_ci    }
1756e0dac50fSopenharmony_ci    FlushWindowInfo(windowId);
1757e0dac50fSopenharmony_ci    accessibilityConnection_->NotifyAccessibilityWindowInfo(windowRoot_->GetWindowNode(windowId),
1758e0dac50fSopenharmony_ci        WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1759e0dac50fSopenharmony_ci    return WMError::WM_OK;
1760e0dac50fSopenharmony_ci}
1761e0dac50fSopenharmony_ci
1762e0dac50fSopenharmony_civoid WindowController::NotifyTouchOutside(const sptr<WindowNode>& node)
1763e0dac50fSopenharmony_ci{
1764e0dac50fSopenharmony_ci    auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
1765e0dac50fSopenharmony_ci    if (windowNodeContainer == nullptr) {
1766e0dac50fSopenharmony_ci        WLOGFE("window node container is null");
1767e0dac50fSopenharmony_ci        return;
1768e0dac50fSopenharmony_ci    }
1769e0dac50fSopenharmony_ci
1770e0dac50fSopenharmony_ci    std::vector<sptr<WindowNode>> windowNodes;
1771e0dac50fSopenharmony_ci    windowNodeContainer->TraverseContainer(windowNodes);
1772e0dac50fSopenharmony_ci    uint32_t skipNodeId = GetEmbedNodeId(windowNodes, node);
1773e0dac50fSopenharmony_ci    for (const auto& windowNode : windowNodes) {
1774e0dac50fSopenharmony_ci        if (windowNode == nullptr || windowNode->GetWindowToken() == nullptr ||
1775e0dac50fSopenharmony_ci            windowNode->GetWindowId() == skipNodeId ||
1776e0dac50fSopenharmony_ci            windowNode->GetWindowId() == node->GetWindowId()) {
1777e0dac50fSopenharmony_ci            WLOGFD("continue %{public}s", windowNode == nullptr ? "nullptr" : windowNode->GetWindowName().c_str());
1778e0dac50fSopenharmony_ci            continue;
1779e0dac50fSopenharmony_ci        }
1780e0dac50fSopenharmony_ci        WLOGFD("notify %{public}s id %{public}d", windowNode->GetWindowName().c_str(), windowNode->GetWindowId());
1781e0dac50fSopenharmony_ci        windowNode->GetWindowToken()->NotifyTouchOutside();
1782e0dac50fSopenharmony_ci    }
1783e0dac50fSopenharmony_ci}
1784e0dac50fSopenharmony_ci
1785e0dac50fSopenharmony_ciuint32_t WindowController::GetEmbedNodeId(const std::vector<sptr<WindowNode>>& windowNodes,
1786e0dac50fSopenharmony_ci    const sptr<WindowNode>& node)
1787e0dac50fSopenharmony_ci{
1788e0dac50fSopenharmony_ci    if (node->GetWindowType() != WindowType::WINDOW_TYPE_APP_COMPONENT) {
1789e0dac50fSopenharmony_ci        return 0;
1790e0dac50fSopenharmony_ci    }
1791e0dac50fSopenharmony_ci
1792e0dac50fSopenharmony_ci    Rect nodeRect = node->GetWindowRect();
1793e0dac50fSopenharmony_ci    bool isSkip = true;
1794e0dac50fSopenharmony_ci    for (auto& windowNode : windowNodes) {
1795e0dac50fSopenharmony_ci        if (windowNode == nullptr) {
1796e0dac50fSopenharmony_ci            continue;
1797e0dac50fSopenharmony_ci        }
1798e0dac50fSopenharmony_ci        if (windowNode->GetWindowId() == node->GetWindowId()) {
1799e0dac50fSopenharmony_ci            isSkip = false;
1800e0dac50fSopenharmony_ci            continue;
1801e0dac50fSopenharmony_ci        }
1802e0dac50fSopenharmony_ci        if (isSkip) {
1803e0dac50fSopenharmony_ci            continue;
1804e0dac50fSopenharmony_ci        }
1805e0dac50fSopenharmony_ci        if (nodeRect.IsInsideOf(windowNode->GetWindowRect())) {
1806e0dac50fSopenharmony_ci            WLOGI("TouchOutside window type is component %{public}s windowNode %{public}d",
1807e0dac50fSopenharmony_ci                windowNode->GetWindowName().c_str(), windowNode->GetWindowId());
1808e0dac50fSopenharmony_ci            return windowNode->GetWindowId();
1809e0dac50fSopenharmony_ci        }
1810e0dac50fSopenharmony_ci    }
1811e0dac50fSopenharmony_ci    return 0;
1812e0dac50fSopenharmony_ci}
1813e0dac50fSopenharmony_ci
1814e0dac50fSopenharmony_civoid WindowController::MinimizeWindowsByLauncher(std::vector<uint32_t>& windowIds, bool isAnimated,
1815e0dac50fSopenharmony_ci    sptr<RSIWindowAnimationFinishedCallback>& finishCallback)
1816e0dac50fSopenharmony_ci{
1817e0dac50fSopenharmony_ci    windowRoot_->MinimizeTargetWindows(windowIds);
1818e0dac50fSopenharmony_ci    auto func = []() {
1819e0dac50fSopenharmony_ci        MinimizeApp::ExecuteMinimizeTargetReasons(MinimizeReason::GESTURE_ANIMATION);
1820e0dac50fSopenharmony_ci    };
1821e0dac50fSopenharmony_ci    if (!isAnimated) {
1822e0dac50fSopenharmony_ci        WLOGFD("no animation minimize size: %{public}u", static_cast<uint32_t>(windowIds.size()));
1823e0dac50fSopenharmony_ci        func();
1824e0dac50fSopenharmony_ci    } else {
1825e0dac50fSopenharmony_ci        WLOGFD("animation minimize size: %{public}u", static_cast<uint32_t>(windowIds.size()));
1826e0dac50fSopenharmony_ci        auto needMinimizeAppNodes = MinimizeApp::GetNeedMinimizeAppNodesWithReason(MinimizeReason::GESTURE_ANIMATION);
1827e0dac50fSopenharmony_ci        for (auto& weakNode : needMinimizeAppNodes) {
1828e0dac50fSopenharmony_ci            auto node = weakNode.promote();
1829e0dac50fSopenharmony_ci            if (node) {
1830e0dac50fSopenharmony_ci                // gesture animation no need to play default animation when minimize
1831e0dac50fSopenharmony_ci                node->isPlayAnimationHide_ = true;
1832e0dac50fSopenharmony_ci            }
1833e0dac50fSopenharmony_ci        }
1834e0dac50fSopenharmony_ci        finishCallback = RemoteAnimation::CreateAnimationFinishedCallback(func, nullptr);
1835e0dac50fSopenharmony_ci        if (finishCallback == nullptr) {
1836e0dac50fSopenharmony_ci            return;
1837e0dac50fSopenharmony_ci        }
1838e0dac50fSopenharmony_ci    }
1839e0dac50fSopenharmony_ci}
1840e0dac50fSopenharmony_ci
1841e0dac50fSopenharmony_civoid WindowController::OnScreenshot(DisplayId displayId)
1842e0dac50fSopenharmony_ci{
1843e0dac50fSopenharmony_ci    std::vector<sptr<WindowNode>> windowNodes;
1844e0dac50fSopenharmony_ci    windowRoot_->GetForegroundNodes(windowNodes);
1845e0dac50fSopenharmony_ci    for (auto& windowNode : windowNodes) {
1846e0dac50fSopenharmony_ci        auto windowToken = windowNode->GetWindowToken();
1847e0dac50fSopenharmony_ci        if (windowToken != nullptr) {
1848e0dac50fSopenharmony_ci            windowToken->NotifyScreenshot();
1849e0dac50fSopenharmony_ci        }
1850e0dac50fSopenharmony_ci    }
1851e0dac50fSopenharmony_ci}
1852e0dac50fSopenharmony_ci
1853e0dac50fSopenharmony_civoid WindowController::SetAnchorOffset(int32_t deltaX, int32_t deltaY)
1854e0dac50fSopenharmony_ci{
1855e0dac50fSopenharmony_ci    displayZoomController_->SetAnchorOffset(deltaX, deltaY);
1856e0dac50fSopenharmony_ci    DisplayId displayId = DisplayGroupInfo::GetInstance().GetDefaultDisplayId();
1857e0dac50fSopenharmony_ci    FlushWindowInfoWithDisplayId(displayId);
1858e0dac50fSopenharmony_ci}
1859e0dac50fSopenharmony_ci
1860e0dac50fSopenharmony_civoid WindowController::OffWindowZoom()
1861e0dac50fSopenharmony_ci{
1862e0dac50fSopenharmony_ci    displayZoomController_->OffWindowZoom();
1863e0dac50fSopenharmony_ci    DisplayId displayId = DisplayGroupInfo::GetInstance().GetDefaultDisplayId();
1864e0dac50fSopenharmony_ci    FlushWindowInfoWithDisplayId(displayId);
1865e0dac50fSopenharmony_ci}
1866e0dac50fSopenharmony_ci
1867e0dac50fSopenharmony_civoid WindowController::SetAnchorAndScale(int32_t x, int32_t y, float scale)
1868e0dac50fSopenharmony_ci{
1869e0dac50fSopenharmony_ci    displayZoomController_->SetAnchorAndScale(x, y, scale);
1870e0dac50fSopenharmony_ci    DisplayId displayId = DisplayGroupInfo::GetInstance().GetDefaultDisplayId();
1871e0dac50fSopenharmony_ci    FlushWindowInfoWithDisplayId(displayId);
1872e0dac50fSopenharmony_ci}
1873e0dac50fSopenharmony_ci
1874e0dac50fSopenharmony_ciWMError WindowController::BindDialogTarget(uint32_t& windowId, sptr<IRemoteObject> targetToken)
1875e0dac50fSopenharmony_ci{
1876e0dac50fSopenharmony_ci    auto node = windowRoot_->GetWindowNode(windowId);
1877e0dac50fSopenharmony_ci    if (node == nullptr) {
1878e0dac50fSopenharmony_ci        WLOGFE("could not find window");
1879e0dac50fSopenharmony_ci        return WMError::WM_ERROR_NULLPTR;
1880e0dac50fSopenharmony_ci    }
1881e0dac50fSopenharmony_ci
1882e0dac50fSopenharmony_ci    node->dialogTargetToken_ = targetToken;
1883e0dac50fSopenharmony_ci
1884e0dac50fSopenharmony_ci    return WMError::WM_OK;
1885e0dac50fSopenharmony_ci}
1886e0dac50fSopenharmony_ci
1887e0dac50fSopenharmony_civoid WindowController::SetDragFrameGravity(int32_t dragGravity)
1888e0dac50fSopenharmony_ci{
1889e0dac50fSopenharmony_ci    dragFrameGravity_ = dragGravity;
1890e0dac50fSopenharmony_ci}
1891e0dac50fSopenharmony_ci} // namespace OHOS
1892e0dac50fSopenharmony_ci} // namespace Rosen
1893