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