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