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