• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "window_controller.h"
17 #include <ability_manager_client.h>
18 #include <chrono>
19 #include <cstdint>
20 #include <hisysevent.h>
21 #include <hitrace_meter.h>
22 #include <parameters.h>
23 #include <power_mgr_client.h>
24 #include <rs_window_animation_finished_callback.h>
25 #include <transaction/rs_transaction.h>
26 #include <sstream>
27 
28 #include "display_manager_service_inner.h"
29 #include "minimize_app.h"
30 #include "remote_animation.h"
31 #include "starting_window.h"
32 #include "window_inner_manager.h"
33 #include "window_manager_hilog.h"
34 #include "window_helper.h"
35 #include "wm_common.h"
36 
37 namespace OHOS {
38 namespace Rosen {
39 namespace {
40     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowController"};
41     constexpr uint32_t TOUCH_HOT_AREA_MAX_NUM = 10;
42     constexpr float MASKING_SURFACE_NODE_Z_ORDER = 9999;
43 }
44 
GenWindowId()45 uint32_t WindowController::GenWindowId()
46 {
47     return ++windowId_;
48 }
49 
StartingWindow(sptr<WindowTransitionInfo> info,std::shared_ptr<Media::PixelMap> pixelMap,uint32_t bkgColor,bool isColdStart)50 void WindowController::StartingWindow(sptr<WindowTransitionInfo> info, std::shared_ptr<Media::PixelMap> pixelMap,
51     uint32_t bkgColor, bool isColdStart)
52 {
53     if (!info || info->GetAbilityToken() == nullptr) {
54         WLOGFE("info or AbilityToken is nullptr!");
55         return;
56     }
57     StartAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::STARTING_WINDOW),
58         "wms:async:ShowStartingWindow");
59     auto node = windowRoot_->FindWindowNodeWithToken(info->GetAbilityToken());
60     if (node == nullptr) {
61         if (!isColdStart) {
62             WLOGFE("no windowNode exists but is hot start!");
63             return;
64         }
65         node = StartingWindow::CreateWindowNode(info, GenWindowId());
66         if (node == nullptr) {
67             return;
68         }
69         if (windowRoot_->SaveWindow(node) != WMError::WM_OK) {
70             return;
71         }
72         if (!RemoteAnimation::CheckAnimationController()) {
73             UpdateWindowAnimation(node);
74         }
75     } else {
76         if (node->stateMachine_.IsWindowNodeShownOrShowing()) {
77             WLOGFI("current window is visible, windowId:%{public}u state:%{public}u!",
78                 node->GetWindowId(), static_cast<uint32_t>(node->stateMachine_.GetCurrentState()));
79             return;
80         }
81         if (WindowHelper::IsValidWindowMode(info->GetWindowMode()) &&
82             (node->GetWindowMode() != info->GetWindowMode())) {
83             WLOGFW("set starting window mode. starting mode is: %{public}u, window mode is:%{public}u.",
84                 node->GetWindowMode(), info->GetWindowMode());
85             node->SetWindowMode(info->GetWindowMode());
86         }
87     }
88 
89     if (!WindowHelper::CheckSupportWindowMode(node->GetWindowMode(), node->GetModeSupportInfo(), info)) {
90         WLOGFE("need to cancel starting window");
91         return;
92     }
93 
94     if (windowRoot_->AddWindowNode(0, node, true) != WMError::WM_OK) {
95         return;
96     }
97     StartingWindow::DrawStartingWindow(node, pixelMap, bkgColor, isColdStart);
98     FlushWindowInfo(node->GetWindowId());
99     node->startingWindowShown_ = true;
100     WLOGFI("StartingWindow show success with id:%{public}u!", node->GetWindowId());
101 }
102 
CancelStartingWindow(sptr<IRemoteObject> abilityToken)103 void WindowController::CancelStartingWindow(sptr<IRemoteObject> abilityToken)
104 {
105     auto node = windowRoot_->FindWindowNodeWithToken(abilityToken);
106     if (node == nullptr) {
107         WLOGFI("cannot find windowNode!");
108         return;
109     }
110     if (!node->startingWindowShown_) {
111         WLOGFE("CancelStartingWindow failed because client window has shown id:%{public}u", node->GetWindowId());
112         return;
113     }
114     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "wms:CancelStartingWindow(%u)", node->GetWindowId());
115     FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::STARTING_WINDOW),
116         "wms:async:ShowStartingWindow");
117     WLOGFI("CancelStartingWindow with id:%{public}u!", node->GetWindowId());
118     node->isAppCrash_ = true;
119     WMError res = DestroyWindow(node->GetWindowId(), false);
120     if (res != WMError::WM_OK) {
121         WLOGFE("DestroyWindow failed!");
122     }
123 }
124 
NotifyWindowTransition(sptr<WindowTransitionInfo> & srcInfo,sptr<WindowTransitionInfo> & dstInfo)125 WMError WindowController::NotifyWindowTransition(sptr<WindowTransitionInfo>& srcInfo,
126     sptr<WindowTransitionInfo>& dstInfo)
127 {
128     WLOGFI("NotifyWindowTransition begin!");
129     sptr<WindowNode> dstNode = nullptr;
130     sptr<WindowNode> srcNode = nullptr;
131     if (srcInfo) {
132         srcNode = windowRoot_->FindWindowNodeWithToken(srcInfo->GetAbilityToken());
133     }
134     if (dstInfo) {
135         dstNode = windowRoot_->FindWindowNodeWithToken(dstInfo->GetAbilityToken());
136     }
137     if (!RemoteAnimation::CheckTransition(srcInfo, srcNode, dstInfo, dstNode)) {
138         return WMError::WM_ERROR_NO_REMOTE_ANIMATION;
139     }
140     StartAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
141         "wms:async:ShowRemoteAnimation");
142     auto transitionEvent = RemoteAnimation::GetTransitionEvent(srcInfo, dstInfo, srcNode, dstNode);
143     switch (transitionEvent) {
144         case TransitionEvent::APP_TRANSITION: {
145             return RemoteAnimation::NotifyAnimationTransition(srcInfo, dstInfo, srcNode, dstNode);
146         }
147         case TransitionEvent::MINIMIZE:
148             return RemoteAnimation::NotifyAnimationMinimize(srcInfo, srcNode);
149         case TransitionEvent::CLOSE:
150             return RemoteAnimation::NotifyAnimationClose(srcInfo, srcNode, TransitionEvent::CLOSE);
151         case TransitionEvent::BACK_TRANSITION:
152             return RemoteAnimation::NotifyAnimationBackTransition(srcInfo, dstInfo, srcNode, dstNode);
153         default:
154             return WMError::WM_ERROR_NO_REMOTE_ANIMATION;
155     }
156     return WMError::WM_OK;
157 }
158 
GetFocusWindowNode(DisplayId displayId,sptr<WindowNode> & windowNode)159 WMError WindowController::GetFocusWindowNode(DisplayId displayId, sptr<WindowNode>& windowNode)
160 {
161     auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
162     if (windowNodeContainer == nullptr) {
163         WLOGFE("windowNodeContainer is null, displayId: %{public}" PRIu64"", displayId);
164         return WMError::WM_ERROR_NULLPTR;
165     }
166     uint32_t focusWindowId = windowNodeContainer->GetFocusWindow();
167     WLOGFI("focusWindowId: %{public}u", focusWindowId);
168     auto thisWindowNode = windowRoot_->GetWindowNode(focusWindowId);
169     if (thisWindowNode == nullptr || !thisWindowNode->currentVisibility_) {
170         WLOGFE("focusWindowNode is null or invisible, focusWindowId: %{public}u", focusWindowId);
171         return WMError::WM_ERROR_INVALID_WINDOW;
172     }
173     windowNode = thisWindowNode;
174     return WMError::WM_OK;
175 }
176 
GetFocusWindowInfo(sptr<IRemoteObject> & abilityToken)177 WMError WindowController::GetFocusWindowInfo(sptr<IRemoteObject>& abilityToken)
178 {
179     DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
180     sptr<WindowNode> windowNode;
181     WMError res = GetFocusWindowNode(displayId, windowNode);
182     if (res == WMError::WM_OK) {
183         abilityToken = windowNode->abilityToken_;
184     }
185     return res;
186 }
187 
CreateWindow(sptr<IWindow> & window,sptr<WindowProperty> & property,const std::shared_ptr<RSSurfaceNode> & surfaceNode,uint32_t & windowId,sptr<IRemoteObject> token,int32_t pid,int32_t uid)188 WMError WindowController::CreateWindow(sptr<IWindow>& window, sptr<WindowProperty>& property,
189     const std::shared_ptr<RSSurfaceNode>& surfaceNode, uint32_t& windowId, sptr<IRemoteObject> token,
190     int32_t pid, int32_t uid)
191 {
192     uint32_t parentId = property->GetParentId();
193     if ((parentId != INVALID_WINDOW_ID) &&
194         !WindowHelper::IsSubWindow(property->GetWindowType()) &&
195         !WindowHelper::IsSystemSubWindow(property->GetWindowType())) {
196         WLOGFE("create window failed, type is error");
197         return WMError::WM_ERROR_INVALID_TYPE;
198     }
199 
200     if (windowRoot_->CheckMultiDialogWindows(property->GetWindowType(), token)) {
201         return WMError::WM_ERROR_INVALID_WINDOW;
202     }
203 
204     sptr<WindowNode> node = windowRoot_->FindWindowNodeWithToken(token);
205     if (node != nullptr && WindowHelper::IsMainWindow(property->GetWindowType()) && node->startingWindowShown_) {
206         StartingWindow::HandleClientWindowCreate(node, window, windowId, surfaceNode, property, pid, uid);
207         windowRoot_->AddDeathRecipient(node);
208         windowRoot_->AddSurfaceNodeIdWindowNodePair(surfaceNode->GetId(), node);
209         return WMError::WM_OK;
210     }
211 
212     windowId = GenWindowId();
213     sptr<WindowProperty> windowProperty = new WindowProperty(property);
214     windowProperty->SetWindowId(windowId);
215     node = new WindowNode(windowProperty, window, surfaceNode, pid, uid);
216     node->abilityToken_ = token;
217     node->dialogTargetToken_ = token;
218     UpdateWindowAnimation(node);
219     WLOGFI("createWindow name:%{public}u, windowName:%{public}s",
220         windowId, node->GetWindowName().c_str());
221     // test
222     node->stateMachine_.SetWindowId(windowId);
223     node->stateMachine_.SetWindowType(property->GetWindowType());
224     return windowRoot_->SaveWindow(node);
225 }
226 
NotifyAfterAddWindow(sptr<WindowNode> & node)227 void WindowController::NotifyAfterAddWindow(sptr<WindowNode>& node)
228 {
229     std::vector<sptr<WindowNode>> nodes;
230     nodes.emplace_back(node);
231     for (auto& child : node->children_) {
232         if (child->currentVisibility_) {
233             nodes.emplace_back(child);
234         }
235     }
236     for (auto& iter : nodes) {
237         if ((iter->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
238             (node->abilityToken_ != iter->abilityToken_)) {
239             iter->GetWindowToken()->NotifyForeground();
240         }
241     }
242     accessibilityConnection_->NotifyAccessibilityWindowInfo(node->GetDisplayId(), nodes,
243         WindowUpdateType::WINDOW_UPDATE_ADDED);
244 }
245 
AddWindowNode(sptr<WindowProperty> & property)246 WMError WindowController::AddWindowNode(sptr<WindowProperty>& property)
247 {
248     auto node = windowRoot_->GetWindowNode(property->GetWindowId());
249     if (node == nullptr) {
250         WLOGFE("could not find window");
251         return WMError::WM_ERROR_NULLPTR;
252     }
253 
254     if (node->currentVisibility_ && !node->startingWindowShown_) {
255         WLOGFE("current window is visible, windowId: %{public}u", node->GetWindowId());
256         return WMError::WM_ERROR_INVALID_OPERATION;
257     }
258 
259     // using starting window rect if client rect is empty
260     if (WindowHelper::IsEmptyRect(property->GetRequestRect()) && node->startingWindowShown_) { // for tile and cascade
261         property->SetRequestRect(node->GetRequestRect());
262         property->SetWindowRect(node->GetWindowRect());
263         property->SetDecoStatus(true);
264     }
265     node->GetWindowProperty()->CopyFrom(property);
266     // Need 'check permission'
267     // Need 'adjust property'
268     UpdateWindowAnimation(node);
269     WMError res = windowRoot_->AddWindowNode(property->GetParentId(), node);
270     if (res != WMError::WM_OK) {
271         MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW);
272         return res;
273     }
274     windowRoot_->FocusFaultDetection();
275     RelayoutKeyboard(node);
276     FlushWindowInfo(property->GetWindowId());
277     NotifyAfterAddWindow(node);
278     HandleTurnScreenOn(node);
279 
280     if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
281         sysBarWinId_[node->GetWindowType()] = node->GetWindowId();
282     }
283     if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
284         ResizeSoftInputCallingWindowIfNeed(node);
285     }
286     StopBootAnimationIfNeed(node);
287     // when hide with remote animation first and show with default animation, need transform state
288     // minimize should execute in finish callback when remote animation enabled
289     if (!node->stateMachine_.IsShowAnimationPlaying()) {
290         if (WindowHelper::IsMainWindow(node->GetWindowType())) {
291             MinimizeApp::ExecuteMinimizeAll();
292             WLOGFI("id:%{public}u execute minimize all", node->GetWindowId());
293         }
294         node->stateMachine_.TransitionTo(WindowNodeState::SHOWN); // for normal show which not use remote animation
295     } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
296         MinimizeApp::ExecuteMinimizeTargetReasons(~MinimizeReason::OTHER_WINDOW);
297     }
298     return WMError::WM_OK;
299 }
300 
RelayoutKeyboard(const sptr<WindowNode> & node)301 void WindowController::RelayoutKeyboard(const sptr<WindowNode>& node)
302 {
303     if (node == nullptr) {
304         WLOGFE("could not find window");
305         return;
306     }
307     if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
308         return;
309     }
310 
311     auto container = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
312     if (container == nullptr) {
313         WLOGFE("window node container is null");
314         return;
315     }
316 
317     uint32_t navigationBarHeight = 0;
318     bool hasFullScreenKeyGuardWindow = false;
319     WindowNodeOperationFunc func = [&navigationBarHeight, &hasFullScreenKeyGuardWindow](sptr<WindowNode> windowNode) {
320         if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
321             windowNode->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) {
322                 hasFullScreenKeyGuardWindow = true;
323         }
324         if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR && windowNode->isVisible_) {
325             navigationBarHeight = windowNode->GetWindowRect().height_;
326             if (hasFullScreenKeyGuardWindow) {
327                 WLOGFW("RelayoutKeyboard: The navigation bar is overlaid by the keyguard window and is invisible");
328                 navigationBarHeight = 0;
329             }
330             return true;
331         }
332         return false;
333     };
334     container->TraverseWindowTree(func, true); // FromTopToBottom
335 
336     sptr<DisplayInfo> defaultDisplayInfo = DisplayManagerServiceInner::GetInstance().GetDefaultDisplay();
337     if (defaultDisplayInfo == nullptr) {
338         WLOGFE("defaultDisplayInfo is null");
339         return;
340     }
341 
342     auto previousRect = node->GetWindowRect();
343     WLOGFI("relayout keyboard window with navigationBarHeight: %{public}u", navigationBarHeight);
344     Rect requestedRect = { previousRect.posX_,
345         static_cast<int32_t>(defaultDisplayInfo->GetHeight() - previousRect.height_ - navigationBarHeight),
346         previousRect.width_, previousRect.height_ };
347     ResizeRect(node->GetWindowId(), requestedRect, WindowSizeChangeReason::MOVE);
348 }
349 
ResizeSoftInputCallingWindowIfNeed(const sptr<WindowNode> & node)350 void WindowController::ResizeSoftInputCallingWindowIfNeed(const sptr<WindowNode>& node)
351 {
352     auto callingWindowId = node->GetCallingWindow();
353     auto callingWindow = windowRoot_->GetWindowNode(callingWindowId);
354     if (callingWindow == nullptr) {
355         auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
356         if (windowNodeContainer == nullptr) {
357             WLOGFE("windowNodeContainer is null, displayId:%{public}" PRIu64"", node->GetDisplayId());
358             return;
359         }
360         callingWindowId = windowNodeContainer->GetFocusWindow();
361         callingWindow = windowRoot_->GetWindowNode(callingWindowId);
362     }
363     if (callingWindow == nullptr || !callingWindow->currentVisibility_ ||
364         callingWindow->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
365         WLOGFE("callingWindow is null or invisible or not float window, callingWindowId:%{public}u", callingWindowId);
366         return;
367     }
368     Rect softInputWindowRect = node->GetWindowRect();
369     Rect callingWindowRect = callingWindow->GetWindowRect();
370     Rect rect = WindowHelper::GetOverlap(softInputWindowRect, callingWindowRect, 0, 0);
371     if (WindowHelper::IsEmptyRect(rect)) {
372         WLOGFE("there is no overlap");
373         return;
374     }
375     Rect requestedRect = callingWindowRect;
376     requestedRect.posY_ = softInputWindowRect.posY_ - static_cast<int32_t>(requestedRect.height_);
377     Rect statusBarWindowRect = { 0, 0, 0, 0 };
378     auto statusbarWindow = windowRoot_->GetWindowNode(sysBarWinId_[WindowType::WINDOW_TYPE_STATUS_BAR]);
379     if (statusbarWindow != nullptr && statusbarWindow->parent_ != nullptr) {
380         statusBarWindowRect = statusbarWindow->GetWindowRect();
381     }
382     int32_t posY = std::max(requestedRect.posY_, static_cast<int32_t>(statusBarWindowRect.height_));
383     if (posY != requestedRect.posY_) {
384         requestedRect.height_ = static_cast<uint32_t>(softInputWindowRect.posY_ - posY);
385         requestedRect.posY_ = posY;
386     }
387     callingWindowRestoringRect_ = callingWindowRect;
388     callingWindowId_ = callingWindow->GetWindowId();
389     ResizeRectAndFlush(callingWindowId_, requestedRect, WindowSizeChangeReason::DRAG);
390 }
391 
RestoreCallingWindowSizeIfNeed()392 void WindowController::RestoreCallingWindowSizeIfNeed()
393 {
394     auto callingWindow = windowRoot_->GetWindowNode(callingWindowId_);
395     if (!WindowHelper::IsEmptyRect(callingWindowRestoringRect_) && callingWindow != nullptr &&
396         callingWindow->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
397         ResizeRectAndFlush(callingWindowId_, callingWindowRestoringRect_, WindowSizeChangeReason::DRAG);
398     }
399     callingWindowRestoringRect_ = { 0, 0, 0, 0 };
400     callingWindowId_ = 0u;
401 }
402 
HandleTurnScreenOn(const sptr<WindowNode> & node)403 void WindowController::HandleTurnScreenOn(const sptr<WindowNode>& node)
404 {
405     if (node == nullptr) {
406         WLOGFE("window is invalid");
407         return;
408     }
409     WLOGFI("handle turn screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), node->IsTurnScreenOn());
410     // reset ipc identity
411     std::string identity = IPCSkeleton::ResetCallingIdentity();
412     if (node->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
413         WLOGFI("turn screen on");
414         PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
415     }
416     // set ipc identity to raw
417     IPCSkeleton::SetCallingIdentity(identity);
418 }
419 
RemoveWindowNode(uint32_t windowId,bool fromAnimation)420 WMError WindowController::RemoveWindowNode(uint32_t windowId, bool fromAnimation)
421 {
422     auto windowNode = windowRoot_->GetWindowNode(windowId);
423     if (windowNode == nullptr) {
424         WLOGFE("windowNode is nullptr");
425         return WMError::WM_ERROR_NULLPTR;
426     }
427     auto removeFunc = [this, windowId, windowNode, fromAnimation]() {
428         WMError res = windowRoot_->RemoveWindowNode(windowId, fromAnimation);
429         if (res != WMError::WM_OK) {
430             WLOGFE("RemoveWindowNode failed");
431             return res;
432         }
433         windowRoot_->FocusFaultDetection();
434         FlushWindowInfo(windowId);
435         std::vector<sptr<WindowNode>> nodes;
436         nodes.emplace_back(windowNode);
437         for (auto& child : windowNode->children_) {
438             nodes.emplace_back(child);
439         }
440         for (auto& iter : nodes) {
441             if ((iter->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
442                 (windowNode->abilityToken_ != iter->abilityToken_)) {
443                 iter->GetWindowToken()->NotifyBackground();
444             }
445         }
446         displayZoomController_->ClearZoomTransform(nodes);
447         accessibilityConnection_->NotifyAccessibilityWindowInfo(windowNode->GetDisplayId(), nodes,
448             WindowUpdateType::WINDOW_UPDATE_REMOVED);
449         return res;
450     };
451     WMError res = WMError::WM_ERROR_NO_REMOTE_ANIMATION;
452     if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
453         if (RemoteAnimation::NotifyAnimationScreenUnlock(removeFunc) == WMError::WM_OK) {
454             WLOGFI("NotifyAnimationScreenUnlock with remote animation");
455             res = WMError::WM_OK;
456         }
457     }
458     if (res != WMError::WM_OK) {
459         res = removeFunc();
460     }
461     if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
462         RestoreCallingWindowSizeIfNeed();
463     }
464     if (!windowNode->stateMachine_.IsHideAnimationPlaying()) {
465         windowNode->stateMachine_.TransitionTo(WindowNodeState::HIDDEN);
466     }
467     return res;
468 }
469 
DestroyWindow(uint32_t windowId,bool onlySelf)470 WMError WindowController::DestroyWindow(uint32_t windowId, bool onlySelf)
471 {
472     DisplayId displayId = DISPLAY_ID_INVALID;
473     auto node = windowRoot_->GetWindowNode(windowId);
474     if (node == nullptr) {
475         WLOGFE("destroy window id:%{public}u failed, because window node is not exist.", windowId);
476         return WMError::WM_ERROR_NULLPTR;
477     }
478     displayId = node->GetDisplayId();
479     WMError res = windowRoot_->DestroyWindow(windowId, onlySelf);
480     if (res != WMError::WM_OK) {
481         return res;
482     }
483     windowRoot_->FocusFaultDetection();
484     FlushWindowInfoWithDisplayId(displayId);
485     std::vector<sptr<WindowNode>> nodes;
486     nodes.emplace_back(node);
487     for (auto& child : node->children_) {
488         nodes.emplace_back(child);
489     }
490     accessibilityConnection_->NotifyAccessibilityWindowInfo(node->GetDisplayId(), nodes,
491         WindowUpdateType::WINDOW_UPDATE_REMOVED);
492     node->stateMachine_.TransitionTo(WindowNodeState::DESTROYED);
493     return res;
494 }
495 
ResizeRect(uint32_t windowId,const Rect & rect,WindowSizeChangeReason reason)496 WMError WindowController::ResizeRect(uint32_t windowId, const Rect& rect, WindowSizeChangeReason reason)
497 {
498     auto node = windowRoot_->GetWindowNode(windowId);
499     if (node == nullptr) {
500         WLOGFE("could not find window");
501         return WMError::WM_ERROR_NULLPTR;
502     }
503     if (node->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
504         WLOGFE("fullscreen window could not resize");
505         return WMError::WM_ERROR_INVALID_OPERATION;
506     }
507     auto property = node->GetWindowProperty();
508     node->SetWindowSizeChangeReason(reason);
509     Rect lastRect = property->GetWindowRect();
510     Rect newRect;
511     if (reason == WindowSizeChangeReason::MOVE) {
512         newRect = { rect.posX_, rect.posY_, lastRect.width_, lastRect.height_ };
513         if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
514             if (windowRoot_->IsForbidDockSliceMove(node->GetDisplayId())) {
515                 WLOGFI("dock slice is forbidden to move");
516                 newRect = lastRect;
517             } else if (windowRoot_->IsVerticalDisplay(node)) {
518                 newRect.posX_ = lastRect.posX_;
519             } else {
520                 newRect.posY_ = lastRect.posY_;
521             }
522         }
523     } else if (reason == WindowSizeChangeReason::RESIZE) {
524         newRect = { lastRect.posX_, lastRect.posY_, rect.width_, rect.height_ };
525     } else if (reason == WindowSizeChangeReason::DRAG || reason == WindowSizeChangeReason::ROTATION) {
526         newRect = rect;
527     }
528     property->SetRequestRect(newRect);
529     WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_RECT);
530     if (res != WMError::WM_OK) {
531         return res;
532     }
533     accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
534     return WMError::WM_OK;
535 }
536 
ResizeRectAndFlush(uint32_t windowId,const Rect & rect,WindowSizeChangeReason reason)537 WMError WindowController::ResizeRectAndFlush(uint32_t windowId, const Rect& rect, WindowSizeChangeReason reason)
538 {
539     WMError res = ResizeRect(windowId, rect, reason);
540     if (res != WMError::WM_OK) {
541         return res;
542     } else {
543         FlushWindowInfo(windowId);
544         return WMError::WM_OK;
545     }
546 }
547 
RequestFocus(uint32_t windowId)548 WMError WindowController::RequestFocus(uint32_t windowId)
549 {
550     if (windowRoot_ == nullptr) {
551         return WMError::WM_ERROR_NULLPTR;
552     }
553     WMError res = windowRoot_->RequestFocus(windowId);
554     FlushWindowInfo(windowId);
555     accessibilityConnection_->NotifyAccessibilityWindowInfo(windowRoot_->GetWindowNode(windowId),
556         WindowUpdateType::WINDOW_UPDATE_FOCUSED);
557     return res;
558 }
559 
SetWindowMode(uint32_t windowId,WindowMode dstMode)560 WMError WindowController::SetWindowMode(uint32_t windowId, WindowMode dstMode)
561 {
562     HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
563     auto node = windowRoot_->GetWindowNode(windowId);
564     if (node == nullptr) {
565         WLOGFE("could not find window");
566         return WMError::WM_ERROR_NULLPTR;
567     }
568     WMError ret = windowRoot_->SetWindowMode(node, dstMode);
569     if (ret != WMError::WM_OK) {
570         return ret;
571     }
572     FlushWindowInfo(windowId);
573     accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
574     if (!node->stateMachine_.IsShowAnimationPlaying()) {
575         if (WindowHelper::IsMainWindow(node->GetWindowType())) {
576             MinimizeApp::ExecuteMinimizeAll();
577             WLOGFI("id:%{public}u execute minimize all", node->GetWindowId());
578         }
579     }
580     return WMError::WM_OK;
581 }
582 
NotifyDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)583 void WindowController::NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
584     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
585 {
586     WLOGFD("NotifyDisplayStateChange start: %{public}u", type);
587     switch (type) {
588         case DisplayStateChangeType::BEFORE_SUSPEND: {
589             isScreenLocked_ = true;
590             windowRoot_->ProcessWindowStateChange(WindowState::STATE_FROZEN, WindowStateChangeReason::KEYGUARD);
591             break;
592         }
593         case DisplayStateChangeType::BEFORE_UNLOCK: {
594             windowRoot_->ProcessWindowStateChange(WindowState::STATE_UNFROZEN, WindowStateChangeReason::KEYGUARD);
595             isScreenLocked_ = false;
596             break;
597         }
598         case DisplayStateChangeType::CREATE: {
599             SetDefaultDisplayInfo(defaultDisplayId, displayInfo);
600             windowRoot_->ProcessDisplayCreate(defaultDisplayId, displayInfo, displayInfoMap);
601             FlushWindowInfoWithDisplayId(displayInfo->GetDisplayId());
602             break;
603         }
604         case DisplayStateChangeType::DESTROY: {
605             windowRoot_->ProcessDisplayDestroy(defaultDisplayId, displayInfo, displayInfoMap);
606             FlushWindowInfoWithDisplayId(defaultDisplayId);
607             break;
608         }
609         case DisplayStateChangeType::DISPLAY_COMPRESS:
610         case DisplayStateChangeType::SIZE_CHANGE:
611         case DisplayStateChangeType::UPDATE_ROTATION:
612         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
613             ProcessDisplayChange(defaultDisplayId, displayInfo, displayInfoMap, type);
614             /*
615              * Window tile num may change when display rotate or change size, need to execute minimize
616              */
617             MinimizeApp::ExecuteMinimizeTargetReasons(MinimizeReason::LAYOUT_TILE);
618             break;
619         }
620         default: {
621             WLOGFE("unknown DisplayStateChangeType:%{public}u", type);
622             return;
623         }
624     }
625     WLOGFD("NotifyDisplayStateChange end, type: %{public}u", type);
626 }
627 
SetDefaultDisplayInfo(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo)628 void WindowController::SetDefaultDisplayInfo(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo)
629 {
630     if (displayInfo == nullptr) {
631         WLOGFE("display is null");
632         return;
633     }
634     if (displayInfo->GetDisplayId() != defaultDisplayId) {
635         return;
636     }
637     WLOGFI("get default display info");
638     auto displayWidth = static_cast<uint32_t>(displayInfo->GetWidth());
639     auto displayHeight = static_cast<uint32_t>(displayInfo->GetHeight());
640     defaultDisplayRect_ = { 0, 0, displayWidth, displayHeight };
641 }
642 
ProcessSystemBarChange(const sptr<DisplayInfo> & displayInfo)643 void WindowController::ProcessSystemBarChange(const sptr<DisplayInfo>& displayInfo)
644 {
645     DisplayId displayId = displayInfo->GetDisplayId();
646     auto width = static_cast<uint32_t>(displayInfo->GetWidth());
647     auto height = static_cast<uint32_t>(displayInfo->GetHeight());
648     const auto& statusBarNode = windowRoot_->GetWindowNode(sysBarWinId_[WindowType::WINDOW_TYPE_STATUS_BAR]);
649     if (statusBarNode != nullptr && statusBarNode->GetDisplayId() == displayId) {
650         auto statusBarHeight = statusBarNode->GetWindowRect().height_;
651         Rect newRect = { 0, 0, width, statusBarHeight };
652         ResizeRect(sysBarWinId_[WindowType::WINDOW_TYPE_STATUS_BAR], newRect, WindowSizeChangeReason::ROTATION);
653     }
654     const auto& naviBarNode = windowRoot_->GetWindowNode(sysBarWinId_[WindowType::WINDOW_TYPE_NAVIGATION_BAR]);
655     if (naviBarNode != nullptr && naviBarNode->GetDisplayId() == displayId) {
656         auto naviBarHeight = naviBarNode->GetWindowRect().height_;
657         Rect newRect = { 0, static_cast<int32_t>(height - naviBarHeight), width, naviBarHeight };
658         ResizeRect(sysBarWinId_[WindowType::WINDOW_TYPE_NAVIGATION_BAR], newRect, WindowSizeChangeReason::ROTATION);
659     }
660 }
661 
ProcessDisplayChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)662 void WindowController::ProcessDisplayChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
663     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
664 {
665     if (displayInfo == nullptr) {
666         WLOGFE("get display failed");
667         return;
668     }
669     auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayInfo->GetDisplayId());
670     if (windowNodeContainer != nullptr) {
671         windowNodeContainer->BeforeProcessWindowAvoidAreaChangeWhenDisplayChange();
672         windowNodeContainer->UpdateDisplayInfo(displayInfo);
673     }
674     switch (type) {
675         case DisplayStateChangeType::DISPLAY_COMPRESS:
676             ProcessDisplayCompression(defaultDisplayId, displayInfo);
677             [[fallthrough]];
678         case DisplayStateChangeType::SIZE_CHANGE:
679         case DisplayStateChangeType::UPDATE_ROTATION:
680             windowRoot_->ProcessDisplayChange(defaultDisplayId, displayInfo, displayInfoMap, type);
681             ProcessSystemBarChange(displayInfo);
682             break;
683         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
684             windowRoot_->ProcessDisplayChange(defaultDisplayId, displayInfo, displayInfoMap, type);
685             break;
686         }
687         default: {
688             WLOGFE("unknown DisplayStateChangeType:%{public}u", type);
689             return;
690         }
691     }
692     auto displayId = displayInfo->GetDisplayId();
693     displayZoomController_->UpdateAllWindowsZoomInfo(displayId);
694     FlushWindowInfoWithDisplayId(displayId);
695     accessibilityConnection_->NotifyAccessibilityWindowInfo(displayId, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
696     if (windowNodeContainer != nullptr) {
697         windowNodeContainer->ProcessWindowAvoidAreaChangeWhenDisplayChange();
698     }
699 }
700 
ProcessDisplayCompression(DisplayId defaultDisplayId,const sptr<DisplayInfo> & displayInfo)701 void WindowController::ProcessDisplayCompression(DisplayId defaultDisplayId, const sptr<DisplayInfo>& displayInfo)
702 {
703     WLOGFI("Enter processDisplayCompress");
704     DisplayId displayId = displayInfo->GetDisplayId();
705     if (displayId != defaultDisplayId) {
706         WLOGFI("Not default display");
707         return;
708     }
709     auto& dms = DisplayManagerServiceInner::GetInstance();
710     if (!displayInfo->GetWaterfallDisplayCompressionStatus()) {
711         if (maskingSurfaceNode_ == nullptr) {
712             WLOGFD("MaskingSurfaceNode is not created");
713             return;
714         } else {
715             WLOGFD("Remove maskingSurfaceNode");
716             dms.UpdateRSTree(displayId, displayId, maskingSurfaceNode_, false, false);
717             maskingSurfaceNode_ = nullptr;
718             return;
719         }
720     }
721     WLOGFD("Add maskingSurfaceNode");
722     struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
723     rsSurfaceNodeConfig.SurfaceNodeName = "maskingSurface";
724     maskingSurfaceNode_ = RSSurfaceNode::Create(rsSurfaceNodeConfig);
725     if (maskingSurfaceNode_ == nullptr) {
726         WLOGFE("Create maskingSurfaceNode failed");
727         return;
728     }
729     auto displayWidth = displayInfo->GetWidth();
730     auto displayHeight = displayInfo->GetHeight();
731     auto maskingSizeX = displayInfo->GetOffsetX();
732     auto maskingSizeY = displayInfo->GetOffsetY();
733     auto fullDisplayWidth = displayWidth + maskingSizeX * 2; // *2: Get full width.
734     auto fullDisplayHeight = displayHeight + maskingSizeY * 2; // *2: Get full height.
735 
736     Rect screenRect = Rect {0, 0, fullDisplayWidth, fullDisplayHeight};
737     Rect transparentRect = Rect {maskingSizeX, maskingSizeY, displayWidth, displayHeight};
738     WLOGFD("ScreenRect: fullDisplayWidth: %{public}d, fullDisplayHeight: %{public}d",
739         fullDisplayWidth, fullDisplayHeight);
740     WLOGFD("TransparentRect: X: %{public}u, Y: %{public}u, Width: %{public}d, Height: %{public}d",
741         maskingSizeX, maskingSizeY, displayWidth, displayHeight);
742 
743     maskingSurfaceNode_->SetPositionZ(MASKING_SURFACE_NODE_Z_ORDER);
744 
745     if (!SurfaceDraw::DrawMasking(maskingSurfaceNode_, screenRect, transparentRect)) {
746         WLOGFE("Draw masking surface failed");
747         return;
748     }
749     maskingSurfaceNode_->SetBounds(0, 0, fullDisplayWidth, fullDisplayHeight);
750     dms.UpdateRSTree(displayId, displayId, maskingSurfaceNode_, true, false);
751 }
752 
StopBootAnimationIfNeed(const sptr<WindowNode> & node)753 void WindowController::StopBootAnimationIfNeed(const sptr<WindowNode>& node)
754 {
755     if (isBootAnimationStopped_) {
756         return;
757     }
758     if (node == nullptr) {
759         WLOGFE("could not find window");
760         return;
761     }
762     if (node->GetDisplayId() != DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId()) {
763         return;
764     }
765     auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
766     if (windowNodeContainer == nullptr) {
767         WLOGFE("window node container is null");
768         return;
769     }
770     std::vector<sptr<WindowNode>> windowNodes;
771     windowNodeContainer->TraverseContainer(windowNodes);
772     WmOcclusion::Rect defaultDisplayRect = { defaultDisplayRect_.posX_, defaultDisplayRect_.posY_,
773         defaultDisplayRect_.posX_ + static_cast<int32_t>(defaultDisplayRect_.width_),
774         defaultDisplayRect_.posY_ + static_cast<int32_t>(defaultDisplayRect_.height_)};
775     WmOcclusion::Region defaultDisplayRegion(defaultDisplayRect);
776     WmOcclusion::Region allRegion; // Counts the area of all shown windows
777     for (auto& node : windowNodes) {
778         if (node->GetWindowType() == WindowType::WINDOW_TYPE_BOOT_ANIMATION) {
779             continue;
780         }
781         auto windowRect = node->GetWindowRect();
782         WmOcclusion::Rect curRect = { windowRect.posX_, windowRect.posY_,
783             windowRect.posX_ + static_cast<int32_t>(windowRect.width_),
784             windowRect.posY_ + static_cast<int32_t>(windowRect.height_) };
785         WmOcclusion::Region curRegion(curRect);
786         allRegion = curRegion.Or(allRegion);
787         WmOcclusion::Region subResult = defaultDisplayRegion.Sub(allRegion);
788         if (subResult.GetSize() == 0) {
789             WLOGFI("stop boot animation");
790             system::SetParameter("bootevent.wms.fullscreen.ready", "true");
791             isBootAnimationStopped_ = true;
792             RecordBootAnimationEvent();
793         }
794     }
795 }
796 
RecordBootAnimationEvent() const797 void WindowController::RecordBootAnimationEvent() const
798 {
799     uint64_t time = static_cast<uint64_t>(std::chrono::time_point_cast<std::chrono::seconds>
800         (std::chrono::steady_clock::now()).time_since_epoch().count());
801     WLOGFI("boot animation done duration(s): %{public}" PRIu64"", time);
802     std::ostringstream os;
803     os << "boot animation done duration(s): " << time <<";";
804     int32_t ret = OHOS::HiviewDFX::HiSysEvent::Write(
805         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
806         "WINDOW_BOOT_ANIMATION_DONE",
807         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
808         "MSG", os.str());
809     if (ret != 0) {
810         WLOGFE("Write HiSysEvent error, ret:%{public}d", ret);
811     }
812 }
813 
SetWindowType(uint32_t windowId,WindowType type)814 WMError WindowController::SetWindowType(uint32_t windowId, WindowType type)
815 {
816     auto node = windowRoot_->GetWindowNode(windowId);
817     if (node == nullptr) {
818         WLOGFE("could not find window");
819         return WMError::WM_ERROR_NULLPTR;
820     }
821     auto property = node->GetWindowProperty();
822     property->SetWindowType(type);
823     UpdateWindowAnimation(node);
824     WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_TYPE);
825     if (res != WMError::WM_OK) {
826         return res;
827     }
828     FlushWindowInfo(windowId);
829     accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
830     WLOGFI("SetWindowType end");
831     return res;
832 }
833 
SetWindowFlags(uint32_t windowId,uint32_t flags)834 WMError WindowController::SetWindowFlags(uint32_t windowId, uint32_t flags)
835 {
836     auto node = windowRoot_->GetWindowNode(windowId);
837     if (node == nullptr) {
838         WLOGFE("could not find window");
839         return WMError::WM_ERROR_NULLPTR;
840     }
841     auto property = node->GetWindowProperty();
842     uint32_t oldFlags = property->GetWindowFlags();
843     property->SetWindowFlags(flags);
844     // only forbid_split_move flag change, just set property
845     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE)) {
846         return WMError::WM_OK;
847     }
848     WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_FLAGS);
849     if (res != WMError::WM_OK) {
850         return res;
851     }
852     FlushWindowInfo(windowId);
853     accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
854     WLOGFI("SetWindowFlags end");
855     return res;
856 }
857 
SetSystemBarProperty(uint32_t windowId,WindowType type,const SystemBarProperty & property)858 WMError WindowController::SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& property)
859 {
860     auto node = windowRoot_->GetWindowNode(windowId);
861     if (node == nullptr) {
862         WLOGFE("could not find window");
863         return WMError::WM_ERROR_NULLPTR;
864     }
865     node->SetSystemBarProperty(type, property);
866     WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_OTHER_PROPS);
867     if (res != WMError::WM_OK) {
868         return res;
869     }
870     FlushWindowInfo(windowId);
871     accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
872     WLOGFI("SetSystemBarProperty end");
873     return res;
874 }
875 
NotifySystemBarTints()876 void WindowController::NotifySystemBarTints()
877 {
878     windowRoot_->NotifySystemBarTints();
879 }
880 
SetWindowAnimationController(const sptr<RSIWindowAnimationController> & controller)881 WMError WindowController::SetWindowAnimationController(const sptr<RSIWindowAnimationController>& controller)
882 {
883     return RemoteAnimation::SetWindowAnimationController(controller);
884 }
885 
GetAvoidAreaByType(uint32_t windowId,AvoidAreaType avoidAreaType) const886 AvoidArea WindowController::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType avoidAreaType) const
887 {
888     return windowRoot_->GetAvoidAreaByType(windowId, avoidAreaType);
889 }
890 
ChangeMouseStyle(uint32_t windowId,sptr<MoveDragProperty> & moveDragProperty)891 WMError WindowController::ChangeMouseStyle(uint32_t windowId, sptr<MoveDragProperty>& moveDragProperty)
892 {
893     auto node = windowRoot_->GetWindowNode(windowId);
894     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
895         if (node->GetWindowRect().width_ > node->GetWindowRect().height_) {
896             MMI::InputManager::GetInstance()->SetPointerStyle(windowId, MMI::MOUSE_ICON::NORTH_SOUTH);
897         } else {
898             MMI::InputManager::GetInstance()->SetPointerStyle(windowId, MMI::MOUSE_ICON::WEST_EAST);
899         }
900         return WMError::WM_OK;
901     }
902     MMI::InputManager::GetInstance()->SetPointerStyle(windowId, STYLEID_MAP.at(moveDragProperty->dragType_));
903     return WMError::WM_OK;
904 }
905 
NotifyServerReadyToMoveOrDrag(uint32_t windowId,sptr<MoveDragProperty> & moveDragProperty)906 WMError WindowController::NotifyServerReadyToMoveOrDrag(uint32_t windowId, sptr<MoveDragProperty>& moveDragProperty)
907 {
908     auto node = windowRoot_->GetWindowNode(windowId);
909     if (node == nullptr) {
910         WLOGFW("could not find window");
911         return WMError::WM_ERROR_NULLPTR;
912     }
913     if (!node->currentVisibility_) {
914         WLOGFE("[NotifyServerReadyToMoveOrDrag] window is not visible, windowId: %{public}u", windowId);
915         return WMError::WM_ERROR_INVALID_OPERATION;
916     }
917 
918     // if start dragging or start moving dock_slice, need to update size change reason
919     if ((moveDragProperty->startMoveFlag_ && node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) ||
920         moveDragProperty->startDragFlag_) {
921         WMError res = windowRoot_->UpdateSizeChangeReason(windowId, WindowSizeChangeReason::DRAG_START);
922         ChangeMouseStyle(windowId, moveDragProperty);
923         return res;
924     }
925     return WMError::WM_OK;
926 }
927 
ProcessPointDown(uint32_t windowId,bool isPointDown)928 WMError WindowController::ProcessPointDown(uint32_t windowId, bool isPointDown)
929 {
930     auto node = windowRoot_->GetWindowNode(windowId);
931     if (node == nullptr) {
932         WLOGFW("could not find window");
933         return WMError::WM_ERROR_NULLPTR;
934     }
935     if (!node->currentVisibility_) {
936         WLOGFE("[ProcessPointDown] window is not visible, windowId: %{public}u", windowId);
937         return WMError::WM_ERROR_INVALID_OPERATION;
938     }
939 
940     /*
941      * If not point down, no need to notify touch outside
942      */
943     if (isPointDown) {
944         NotifyTouchOutside(node);
945         if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
946             windowRoot_->TakeWindowPairSnapshot(node->GetDisplayId());
947         }
948     }
949 
950     WLOGFI("process point down, windowId: %{public}u", windowId);
951     WMError zOrderRes = windowRoot_->RaiseZOrderForAppWindow(node);
952     WMError focusRes = windowRoot_->RequestFocus(windowId);
953     windowRoot_->RequestActiveWindow(windowId);
954     windowRoot_->FocusFaultDetection();
955     if (zOrderRes == WMError::WM_OK || focusRes == WMError::WM_OK) {
956         FlushWindowInfo(windowId);
957         accessibilityConnection_->NotifyAccessibilityWindowInfo(windowRoot_->GetWindowNode(windowId),
958             WindowUpdateType::WINDOW_UPDATE_FOCUSED);
959         WLOGFI("ProcessPointDown end");
960         return WMError::WM_OK;
961     }
962     return WMError::WM_ERROR_INVALID_OPERATION;
963 }
964 
ProcessPointUp(uint32_t windowId)965 WMError WindowController::ProcessPointUp(uint32_t windowId)
966 {
967     auto node = windowRoot_->GetWindowNode(windowId);
968     if (node == nullptr) {
969         WLOGFW("could not find window");
970         return WMError::WM_ERROR_NULLPTR;
971     }
972     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
973         DisplayId displayId = node->GetDisplayId();
974         if (windowRoot_->IsDockSliceInExitSplitModeArea(displayId)) {
975             windowRoot_->ExitSplitMode(displayId);
976         } else {
977             windowRoot_->ClearWindowPairSnapshot(node->GetDisplayId());
978             auto property = node->GetWindowProperty();
979             node->SetWindowSizeChangeReason(WindowSizeChangeReason::DRAG_END);
980             property->SetRequestRect(property->GetWindowRect());
981             WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_RECT);
982             if (res == WMError::WM_OK) {
983                 FlushWindowInfo(windowId);
984                 accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
985             }
986         }
987     }
988     WMError res = windowRoot_->UpdateSizeChangeReason(windowId, WindowSizeChangeReason::DRAG_END);
989     if (res != WMError::WM_OK) {
990         return res;
991     }
992     return WMError::WM_OK;
993 }
994 
InterceptInputEventToServer(uint32_t windowId)995 WMError WindowController::InterceptInputEventToServer(uint32_t windowId)
996 {
997     auto node = windowRoot_->GetWindowNode(windowId);
998     if (node == nullptr) {
999         WLOGFW("could not find window");
1000         return WMError::WM_ERROR_NULLPTR;
1001     }
1002     auto inputPidInServer = WindowInnerManager::GetInstance().GetPid();
1003     WLOGFI("InterceptInputEventToServer, windowId: %{public}u, inputPid: %{public}u", windowId, inputPidInServer);
1004     node->SetInputEventCallingPid(static_cast<int32_t>(inputPidInServer));
1005     FlushWindowInfo(windowId);
1006     return WMError::WM_OK;
1007 }
1008 
RecoverInputEventToClient(uint32_t windowId)1009 WMError WindowController::RecoverInputEventToClient(uint32_t windowId)
1010 {
1011     auto node = windowRoot_->GetWindowNode(windowId);
1012     if (node == nullptr) {
1013         WLOGFW("could not find window");
1014         return WMError::WM_ERROR_NULLPTR;
1015     }
1016     if (node->GetInputEventCallingPid() == node->GetCallingPid()) {
1017         WLOGFD("There is no need to recover input event to client");
1018         return WMError::WM_OK;
1019     }
1020     node->SetInputEventCallingPid(node->GetCallingPid());
1021     RecoverDefaultMouseStyle(windowId);
1022     AsyncFlushInputInfo(windowId);
1023     return WMError::WM_OK;
1024 }
1025 
AsyncFlushInputInfo(uint32_t windowId)1026 void WindowController::AsyncFlushInputInfo(uint32_t windowId)
1027 {
1028     WLOGFD("AsyncFlushWindowInfo");
1029     displayZoomController_->UpdateWindowZoomInfo(windowId);
1030     RSTransaction::FlushImplicitTransaction();
1031     MMI::DisplayGroupInfo displayInfo_ = inputWindowMonitor_->GetDisplayInfo(windowId);
1032     auto task = [this, displayInfo_]() {
1033         MMI::InputManager::GetInstance()->UpdateDisplayInfo(displayInfo_);
1034     };
1035     WindowInnerManager::GetInstance().PostTask(task, "UpdateDisplayInfo");
1036 }
1037 
RecoverDefaultMouseStyle(uint32_t windowId)1038 void WindowController::RecoverDefaultMouseStyle(uint32_t windowId)
1039 {
1040     // asynchronously calls SetMouseStyle of MultiModalInput
1041     auto task = [this, windowId]() {
1042         MMI::InputManager::GetInstance()->SetPointerStyle(windowId, MMI::MOUSE_ICON::DEFAULT);
1043     };
1044     WindowInnerManager::GetInstance().PostTask(task, "RecoverDefaultMouseStyle");
1045 }
1046 
NotifyWindowClientPointUp(uint32_t windowId,const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1047 WMError WindowController::NotifyWindowClientPointUp(uint32_t windowId,
1048     const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1049 {
1050     auto node = windowRoot_->GetWindowNode(windowId);
1051     if (node == nullptr) {
1052         WLOGFW("could not find window");
1053         return WMError::WM_ERROR_NULLPTR;
1054     }
1055     if (node->GetWindowToken() != nullptr) {
1056         WLOGFI("notify client when receive point_up event, windowId: %{public}u", windowId);
1057         node->GetWindowToken()->NotifyWindowClientPointUp(pointerEvent);
1058     }
1059     return WMError::WM_OK;
1060 }
1061 
MinimizeAllAppWindows(DisplayId displayId)1062 void WindowController::MinimizeAllAppWindows(DisplayId displayId)
1063 {
1064     windowRoot_->MinimizeAllAppWindows(displayId);
1065     if (RemoteAnimation::NotifyAnimationByHome() != WMError::WM_OK) {
1066         MinimizeApp::ExecuteMinimizeAll();
1067     }
1068 }
1069 
ToggleShownStateForAllAppWindows()1070 WMError WindowController::ToggleShownStateForAllAppWindows()
1071 {
1072     if (isScreenLocked_) {
1073         return WMError::WM_DO_NOTHING;
1074     }
1075     return windowRoot_->ToggleShownStateForAllAppWindows();
1076 }
1077 
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)1078 WMError WindowController::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
1079 {
1080     return windowRoot_->GetTopWindowId(mainWinId, topWinId);
1081 }
1082 
FlushWindowInfo(uint32_t windowId)1083 void WindowController::FlushWindowInfo(uint32_t windowId)
1084 {
1085     WLOGFD("FlushWindowInfo");
1086     displayZoomController_->UpdateWindowZoomInfo(windowId);
1087     RSTransaction::FlushImplicitTransaction();
1088     inputWindowMonitor_->UpdateInputWindow(windowId);
1089 }
1090 
FlushWindowInfoWithDisplayId(DisplayId displayId)1091 void WindowController::FlushWindowInfoWithDisplayId(DisplayId displayId)
1092 {
1093     WLOGFI("FlushWindowInfoWithDisplayId, displayId: %{public}" PRIu64"", displayId);
1094     RSTransaction::FlushImplicitTransaction();
1095     inputWindowMonitor_->UpdateInputWindowByDisplayId(displayId);
1096 }
1097 
UpdateWindowAnimation(const sptr<WindowNode> & node)1098 void WindowController::UpdateWindowAnimation(const sptr<WindowNode>& node)
1099 {
1100     if (node == nullptr || (node->leashWinSurfaceNode_ == nullptr && node->surfaceNode_ == nullptr)) {
1101         WLOGFE("windowNode or surfaceNode is nullptr");
1102         return;
1103     }
1104     const auto& windowAnimationConfig = WindowNodeContainer::GetAnimationConfigRef().windowAnimationConfig_;
1105 
1106     uint32_t animationFlag = node->GetWindowProperty()->GetAnimationFlag();
1107     uint32_t windowId = node->GetWindowProperty()->GetWindowId();
1108     WLOGFI("windowId: %{public}u, animationFlag: %{public}u", windowId, animationFlag);
1109     std::shared_ptr<const RSTransitionEffect> effect = nullptr;
1110     if (animationFlag == static_cast<uint32_t>(WindowAnimation::DEFAULT)) {
1111         effect = RSTransitionEffect::Create()
1112             ->Scale(windowAnimationConfig.scale_)
1113             ->Rotate(windowAnimationConfig.rotation_)
1114             ->Translate(windowAnimationConfig.translate_)
1115             ->Opacity(windowAnimationConfig.opacity_);
1116     } else if (animationFlag == static_cast<uint32_t>(WindowAnimation::INPUTE)) {
1117         float translateY = static_cast<float>(node->GetWindowRect().height_);
1118         if (!node->GetWindowRect().height_) {
1119             translateY = static_cast<float>(node->GetRequestRect().height_);
1120         }
1121         effect = RSTransitionEffect::Create()->Translate(Vector3f(0, translateY, 0))->Opacity(0.0f);
1122     };
1123     if (node->leashWinSurfaceNode_) {
1124         node->leashWinSurfaceNode_->SetTransitionEffect(effect);
1125     }
1126     if (node->surfaceNode_) {
1127         node->surfaceNode_->SetTransitionEffect(effect);
1128     }
1129 }
1130 
SetWindowLayoutMode(WindowLayoutMode mode)1131 WMError WindowController::SetWindowLayoutMode(WindowLayoutMode mode)
1132 {
1133     WMError res = WMError::WM_OK;
1134     auto displayIds = windowRoot_->GetAllDisplayIds();
1135     for (auto displayId : displayIds) {
1136         res = windowRoot_->SetWindowLayoutMode(displayId, mode);
1137         if (res != WMError::WM_OK) {
1138             return res;
1139         }
1140         displayZoomController_->UpdateAllWindowsZoomInfo(displayId);
1141         FlushWindowInfoWithDisplayId(displayId);
1142         accessibilityConnection_->NotifyAccessibilityWindowInfo(displayId, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1143     }
1144     MinimizeApp::ExecuteMinimizeAll();
1145     return res;
1146 }
1147 
UpdateProperty(sptr<WindowProperty> & property,PropertyChangeAction action)1148 WMError WindowController::UpdateProperty(sptr<WindowProperty>& property, PropertyChangeAction action)
1149 {
1150     if (property == nullptr) {
1151         WLOGFE("property is invalid");
1152         return WMError::WM_ERROR_NULLPTR;
1153     }
1154     uint32_t windowId = property->GetWindowId();
1155     auto node = windowRoot_->GetWindowNode(windowId);
1156     if (node == nullptr) {
1157         WLOGFE("window is invalid");
1158         return WMError::WM_ERROR_NULLPTR;
1159     }
1160     WLOGFI("window: [%{public}s, %{public}u] update property for action: %{public}u", node->GetWindowName().c_str(),
1161         node->GetWindowId(), static_cast<uint32_t>(action));
1162     WMError ret = WMError::WM_OK;
1163     switch (action) {
1164         case PropertyChangeAction::ACTION_UPDATE_RECT: {
1165             node->SetDecoStatus(property->GetDecoStatus());
1166             node->SetOriginRect(property->GetOriginRect());
1167             node->SetDragType(property->GetDragType());
1168             ret = ResizeRectAndFlush(windowId, property->GetRequestRect(), property->GetWindowSizeChangeReason());
1169             if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING && ret == WMError::WM_OK &&
1170                 callingWindowId_ == windowId && !WindowHelper::IsEmptyRect(callingWindowRestoringRect_)) {
1171                 if (property->GetWindowSizeChangeReason() != WindowSizeChangeReason::MOVE) {
1172                     callingWindowId_ = 0u;
1173                     callingWindowRestoringRect_ = { 0, 0, 0, 0 };
1174                 } else {
1175                     auto windowRect = node->GetWindowRect();
1176                     callingWindowRestoringRect_.posX_ = windowRect.posX_;
1177                     callingWindowRestoringRect_.posY_ = windowRect.posY_;
1178                 }
1179             }
1180             break;
1181         }
1182         case PropertyChangeAction::ACTION_UPDATE_MODE: {
1183             ret = SetWindowMode(windowId, property->GetWindowMode());
1184             break;
1185         }
1186         case PropertyChangeAction::ACTION_UPDATE_FLAGS: {
1187             ret = SetWindowFlags(windowId, property->GetWindowFlags());
1188             break;
1189         }
1190         case PropertyChangeAction::ACTION_UPDATE_OTHER_PROPS: {
1191             auto& props = property->GetSystemBarProperty();
1192             for (auto& iter : props) {
1193                 SetSystemBarProperty(windowId, iter.first, iter.second);
1194             }
1195             break;
1196         }
1197         case PropertyChangeAction::ACTION_UPDATE_FOCUSABLE: {
1198             node->SetFocusable(property->GetFocusable());
1199             windowRoot_->UpdateFocusableProperty(windowId);
1200             FlushWindowInfo(windowId);
1201             accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1202             break;
1203         }
1204         case PropertyChangeAction::ACTION_UPDATE_TOUCHABLE: {
1205             node->SetTouchable(property->GetTouchable());
1206             FlushWindowInfo(windowId);
1207             accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1208             break;
1209         }
1210         case PropertyChangeAction::ACTION_UPDATE_CALLING_WINDOW: {
1211             node->SetCallingWindow(property->GetCallingWindow());
1212             break;
1213         }
1214         case PropertyChangeAction::ACTION_UPDATE_ORIENTATION: {
1215             node->SetRequestedOrientation(property->GetRequestedOrientation());
1216             if (WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
1217                 DisplayManagerServiceInner::GetInstance().
1218                     SetOrientationFromWindow(node->GetDisplayId(), property->GetRequestedOrientation());
1219             }
1220             break;
1221         }
1222         case PropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON: {
1223             node->SetTurnScreenOn(property->IsTurnScreenOn());
1224             HandleTurnScreenOn(node);
1225             break;
1226         }
1227         case PropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON: {
1228             node->SetKeepScreenOn(property->IsKeepScreenOn());
1229             windowRoot_->HandleKeepScreenOn(node->GetWindowId(), node->IsKeepScreenOn());
1230             break;
1231         }
1232         case PropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS: {
1233             node->SetBrightness(property->GetBrightness());
1234             windowRoot_->SetBrightness(node->GetWindowId(), node->GetBrightness());
1235             break;
1236         }
1237         case PropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO: {
1238             node->SetModeSupportInfo(property->GetModeSupportInfo());
1239             break;
1240         }
1241         case PropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA: {
1242             std::vector<Rect> rects;
1243             property->GetTouchHotAreas(rects);
1244             ret = UpdateTouchHotAreas(node, rects);
1245             break;
1246         }
1247         case PropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG: {
1248             node->GetWindowProperty()->SetAnimationFlag(property->GetAnimationFlag());
1249             UpdateWindowAnimation(node);
1250             break;
1251         }
1252         case PropertyChangeAction::ACTION_UPDATE_TRANSFORM_PROPERTY: {
1253             node->SetTransform(property->GetTransform());
1254             node->SetWindowSizeChangeReason(WindowSizeChangeReason::TRANSFORM);
1255             node->GetWindowProperty()->SetAnimateWindowFlag(true);
1256             ret = UpdateTransform(windowId);
1257             break;
1258         }
1259         case PropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE: {
1260             node->GetWindowProperty()->SetPrivacyMode(property->GetPrivacyMode());
1261             break;
1262         }
1263         default:
1264             break;
1265     }
1266     return ret;
1267 }
1268 
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos) const1269 WMError WindowController::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos) const
1270 {
1271     accessibilityConnection_->GetAccessibilityWindowInfo(infos);
1272     return WMError::WM_OK;
1273 }
1274 
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos) const1275 WMError WindowController::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos) const
1276 {
1277     windowRoot_->GetVisibilityWindowInfo(infos);
1278     return WMError::WM_OK;
1279 }
1280 
GetModeChangeHotZones(DisplayId displayId,ModeChangeHotZones & hotZones,const ModeChangeHotZonesConfig & config)1281 WMError WindowController::GetModeChangeHotZones(DisplayId displayId,
1282     ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config)
1283 {
1284     return windowRoot_->GetModeChangeHotZones(displayId, hotZones, config);
1285 }
1286 
UpdateTouchHotAreas(const sptr<WindowNode> & node,const std::vector<Rect> & rects)1287 WMError WindowController::UpdateTouchHotAreas(const sptr<WindowNode>& node, const std::vector<Rect>& rects)
1288 {
1289     std::ostringstream oss;
1290     int index = 0;
1291     for (const auto& rect : rects) {
1292         oss << "[ " << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_ << " ]";
1293         index++;
1294         if (index < static_cast<int32_t>(rects.size())) {
1295             oss <<", ";
1296         }
1297     }
1298     WLOGFI("windowId: %{public}u, size: %{public}d, rects: %{public}s",
1299         node->GetWindowId(), static_cast<int32_t>(rects.size()), oss.str().c_str());
1300     if (rects.size() > TOUCH_HOT_AREA_MAX_NUM) {
1301         WLOGFE("the number of touch hot areas exceeds the maximum");
1302         return WMError::WM_ERROR_INVALID_PARAM;
1303     }
1304 
1305     std::vector<Rect> touchHotAreas;
1306     std::vector<Rect> pointerHotAreas;
1307     if (rects.empty()) {
1308         touchHotAreas.emplace_back(node->GetEntireWindowTouchHotArea());
1309         pointerHotAreas.emplace_back(node->GetEntireWindowPointerHotArea());
1310     } else {
1311         Rect windowRect = node->GetWindowRect();
1312         if (!WindowHelper::CalculateTouchHotAreas(windowRect, rects, touchHotAreas)) {
1313             WLOGFE("the requested touch hot areas are incorrect");
1314             return WMError::WM_ERROR_INVALID_PARAM;
1315         }
1316         pointerHotAreas = touchHotAreas;
1317     }
1318     node->GetWindowProperty()->SetTouchHotAreas(rects);
1319     node->SetTouchHotAreas(touchHotAreas);
1320     node->SetPointerHotAreas(pointerHotAreas);
1321     FlushWindowInfo(node->GetWindowId());
1322     accessibilityConnection_->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1323     return WMError::WM_OK;
1324 }
1325 
UpdateTransform(uint32_t windowId)1326 WMError WindowController::UpdateTransform(uint32_t windowId)
1327 {
1328     WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_TRANSFORM);
1329     if (res != WMError::WM_OK) {
1330         return res;
1331     }
1332     FlushWindowInfo(windowId);
1333     accessibilityConnection_->NotifyAccessibilityWindowInfo(windowRoot_->GetWindowNode(windowId),
1334         WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1335     return WMError::WM_OK;
1336 }
1337 
NotifyTouchOutside(const sptr<WindowNode> & node)1338 void WindowController::NotifyTouchOutside(const sptr<WindowNode>& node)
1339 {
1340     auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
1341     if (windowNodeContainer == nullptr) {
1342         WLOGFE("window node container is null");
1343         return;
1344     }
1345 
1346     std::vector<sptr<WindowNode>> windowNodes;
1347     windowNodeContainer->TraverseContainer(windowNodes);
1348     uint32_t skipNodeId = GetEmbedNodeId(windowNodes, node);
1349     for (const auto& windowNode : windowNodes) {
1350         if (windowNode == nullptr || windowNode->GetWindowToken() == nullptr ||
1351             windowNode->GetWindowId() == skipNodeId ||
1352             windowNode->GetWindowId() == node->GetWindowId()) {
1353             WLOGFD("continue %{public}s", windowNode == nullptr ? "nullptr" : windowNode->GetWindowName().c_str());
1354             continue;
1355         }
1356         WLOGFD("notify %{public}s id %{public}d", windowNode->GetWindowName().c_str(), windowNode->GetWindowId());
1357         windowNode->GetWindowToken()->NotifyTouchOutside();
1358     }
1359 }
1360 
GetEmbedNodeId(const std::vector<sptr<WindowNode>> & windowNodes,const sptr<WindowNode> & node)1361 uint32_t WindowController::GetEmbedNodeId(const std::vector<sptr<WindowNode>>& windowNodes,
1362     const sptr<WindowNode>& node)
1363 {
1364     if (node->GetWindowType() != WindowType::WINDOW_TYPE_APP_COMPONENT) {
1365         return 0;
1366     }
1367 
1368     Rect nodeRect = node->GetWindowRect();
1369     bool isSkip = true;
1370     for (auto& windowNode : windowNodes) {
1371         if (windowNode == nullptr) {
1372             continue;
1373         }
1374         if (windowNode->GetWindowId() == node->GetWindowId()) {
1375             isSkip = false;
1376             continue;
1377         }
1378         if (isSkip) {
1379             continue;
1380         }
1381         if (nodeRect.IsInsideOf(windowNode->GetWindowRect())) {
1382             WLOGI("TouchOutside window type is component %{public}s windowNode %{public}d",
1383                 windowNode->GetWindowName().c_str(), windowNode->GetWindowId());
1384             return windowNode->GetWindowId();
1385         }
1386     }
1387     return 0;
1388 }
1389 
MinimizeWindowsByLauncher(std::vector<uint32_t> & windowIds,bool isAnimated,sptr<RSIWindowAnimationFinishedCallback> & finishCallback)1390 void WindowController::MinimizeWindowsByLauncher(std::vector<uint32_t>& windowIds, bool isAnimated,
1391     sptr<RSIWindowAnimationFinishedCallback>& finishCallback)
1392 {
1393     windowRoot_->MinimizeTargetWindows(windowIds);
1394     auto func = []() {
1395         MinimizeApp::ExecuteMinimizeTargetReasons(MinimizeReason::GESTURE_ANIMATION);
1396     };
1397     if (!isAnimated) {
1398         func();
1399     } else {
1400         finishCallback = RemoteAnimation::CreateAnimationFinishedCallback(func);
1401         if (finishCallback == nullptr) {
1402             return;
1403         }
1404     }
1405 }
1406 
OnScreenshot(DisplayId displayId)1407 void WindowController::OnScreenshot(DisplayId displayId)
1408 {
1409     sptr<WindowNode> windowNode;
1410     WMError res = GetFocusWindowNode(displayId, windowNode);
1411     if (res != WMError::WM_OK) {
1412         return;
1413     }
1414     auto windowToken = windowNode->GetWindowToken();
1415     if (windowToken == nullptr) {
1416         WLOGFE("notify screenshot failed: window token is null.");
1417         return;
1418     }
1419     windowToken->NotifyScreenshot();
1420 }
1421 
SetAnchorOffset(int32_t deltaX,int32_t deltaY)1422 void WindowController::SetAnchorOffset(int32_t deltaX, int32_t deltaY)
1423 {
1424     displayZoomController_->SetAnchorOffset(deltaX, deltaY);
1425     DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
1426     FlushWindowInfoWithDisplayId(displayId);
1427 }
1428 
OffWindowZoom()1429 void WindowController::OffWindowZoom()
1430 {
1431     displayZoomController_->OffWindowZoom();
1432     DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
1433     FlushWindowInfoWithDisplayId(displayId);
1434 }
1435 
SetAnchorAndScale(int32_t x,int32_t y,float scale)1436 void WindowController::SetAnchorAndScale(int32_t x, int32_t y, float scale)
1437 {
1438     displayZoomController_->SetAnchorAndScale(x, y, scale);
1439     DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
1440     FlushWindowInfoWithDisplayId(displayId);
1441 }
1442 
BindDialogTarget(uint32_t & windowId,sptr<IRemoteObject> targetToken)1443 WMError WindowController::BindDialogTarget(uint32_t& windowId, sptr<IRemoteObject> targetToken)
1444 {
1445     auto node = windowRoot_->GetWindowNode(windowId);
1446     if (node == nullptr) {
1447         WLOGFE("could not find window");
1448         return WMError::WM_ERROR_NULLPTR;
1449     }
1450     if (windowRoot_->CheckMultiDialogWindows(node->GetWindowType(), targetToken)) {
1451         return WMError::WM_ERROR_INVALID_WINDOW;
1452     }
1453 
1454     node->dialogTargetToken_ = targetToken;
1455 
1456     sptr<WindowNode> parentNode = windowRoot_->FindDialogCallerNode(node->GetWindowType(), node->dialogTargetToken_);
1457     if (parentNode != nullptr) {
1458         auto position = parentNode->children_.end();
1459         for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
1460             if ((*iter)->priority_ > node->priority_) {
1461                 position = iter;
1462                 break;
1463             }
1464         }
1465         parentNode->children_.insert(position, node);
1466     }
1467 
1468     return WMError::WM_OK;
1469 }
1470 } // namespace OHOS
1471 } // namespace Rosen
1472