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