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