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#include "drag_controller.h" 16 17#include <vector> 18 19#include "display.h" 20#include "window_helper.h" 21#include "window_inner_manager.h" 22#include "window_manager_hilog.h" 23#include "window_manager_service.h" 24#include "window_node.h" 25#include "window_node_container.h" 26#include "window_property.h" 27#include "wm_common.h" 28#include "wm_math.h" 29#include "xcollie/watchdog.h" 30 31namespace OHOS { 32namespace Rosen { 33namespace { 34constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DragController"}; 35} 36 37void DragController::UpdateDragInfo(uint32_t windowId) 38{ 39 PointInfo point; 40 if (!GetHitPoint(windowId, point)) { 41 return; 42 } 43 sptr<WindowNode> dragNode = windowRoot_->GetWindowNode(windowId); 44 if (dragNode == nullptr) { 45 return; 46 } 47 sptr<WindowNode> hitWindowNode = GetHitWindow(dragNode->GetDisplayId(), point); 48 if (hitWindowNode == nullptr) { 49 WLOGFE("Get point failed %{public}d %{public}d", point.x, point.y); 50 return; 51 } 52 auto token = hitWindowNode->GetWindowToken(); 53 if (token) { 54 if (hitWindowNode->GetWindowId() == hitWindowId_) { 55 token->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_MOVE); 56 return; 57 } 58 token->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_IN); 59 } 60 sptr<WindowNode> oldHitWindow = windowRoot_->GetWindowNode(hitWindowId_); 61 if (oldHitWindow != nullptr && oldHitWindow->GetWindowToken()) { 62 oldHitWindow->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_OUT); 63 } 64 hitWindowId_ = hitWindowNode->GetWindowId(); 65} 66 67void DragController::StartDrag(uint32_t windowId) 68{ 69 PointInfo point; 70 if (!GetHitPoint(windowId, point)) { 71 WLOGFE("Get hit point failed"); 72 return; 73 } 74 sptr<WindowNode> dragNode = windowRoot_->GetWindowNode(windowId); 75 if (dragNode == nullptr) { 76 return; 77 } 78 sptr<WindowNode> hitWindow = GetHitWindow(dragNode->GetDisplayId(), point); 79 if (hitWindow == nullptr) { 80 WLOGFE("Get point failed %{public}d %{public}d", point.x, point.y); 81 return; 82 } 83 if (hitWindow->GetWindowToken()) { 84 hitWindow->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_IN); 85 } 86 hitWindowId_ = windowId; 87 WLOGI("start Drag"); 88} 89 90void DragController::FinishDrag(uint32_t windowId) 91{ 92 sptr<WindowNode> node = windowRoot_->GetWindowNode(windowId); 93 if (node == nullptr) { 94 WLOGFE("get node failed"); 95 return; 96 } 97 if (node->GetWindowType() != WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { 98 return; 99 } 100 101 sptr<WindowNode> hitWindow = windowRoot_->GetWindowNode(hitWindowId_); 102 if (hitWindow != nullptr) { 103 auto property = node->GetWindowProperty(); 104 PointInfo point = {property->GetWindowRect().posX_ + property->GetHitOffset().x, 105 property->GetWindowRect().posY_ + property->GetHitOffset().y}; 106 if (hitWindow->GetWindowToken()) { 107 hitWindow->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_END); 108 } 109 } 110 WLOGI("end drag"); 111} 112 113sptr<WindowNode> DragController::GetHitWindow(DisplayId id, PointInfo point) 114{ 115 // Need get display by point 116 if (id == DISPLAY_ID_INVALID) { 117 WLOGFE("Get invalid display"); 118 return nullptr; 119 } 120 sptr<WindowNodeContainer> container = windowRoot_->GetOrCreateWindowNodeContainer(id); 121 if (container == nullptr) { 122 WLOGFE("get container failed %{public}" PRIu64"", id); 123 return nullptr; 124 } 125 126 std::vector<sptr<WindowNode>> windowNodes; 127 container->TraverseContainer(windowNodes); 128 for (auto windowNode : windowNodes) { 129 if (windowNode->GetWindowType() >= WindowType::WINDOW_TYPE_PANEL) { 130 continue; 131 } 132 if (WindowHelper::IsPointInTargetRect(point.x, point.y, windowNode->GetWindowRect())) { 133 return windowNode; 134 } 135 } 136 return nullptr; 137} 138 139bool DragController::GetHitPoint(uint32_t windowId, PointInfo& point) 140{ 141 sptr<WindowNode> windowNode = windowRoot_->GetWindowNode(windowId); 142 if (windowNode == nullptr || windowNode->GetWindowType() != WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { 143 WLOGFE("Get hit point failed"); 144 return false; 145 } 146 sptr<WindowProperty> property = windowNode->GetWindowProperty(); 147 point.x = property->GetWindowRect().posX_ + property->GetHitOffset().x; 148 point.y = property->GetWindowRect().posY_ + property->GetHitOffset().y; 149 return true; 150} 151 152void DragInputEventListener::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const 153{ 154 if (keyEvent == nullptr) { 155 WLOGFE("KeyEvent is nullptr"); 156 return; 157 } 158 uint32_t windowId = static_cast<uint32_t>(keyEvent->GetAgentWindowId()); 159 WLOGFD("[WMS] Receive keyEvent, windowId: %{public}u", windowId); 160 keyEvent->MarkProcessed(); 161} 162 163void DragInputEventListener::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const 164{ 165 if (axisEvent == nullptr) { 166 WLOGFE("AxisEvent is nullptr"); 167 return; 168 }; 169 WLOGFD("[WMS] Receive axisEvent, windowId: %{public}u", axisEvent->GetAgentWindowId()); 170 axisEvent->MarkProcessed(); 171} 172 173void DragInputEventListener::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const 174{ 175 if (pointerEvent == nullptr) { 176 WLOGFE("PointerEvent is nullptr"); 177 return; 178 } 179 uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId()); 180 WLOGFD("[WMS] Receive pointerEvent, windowId: %{public}u", windowId); 181 182 WindowInnerManager::GetInstance().ConsumePointerEvent(pointerEvent); 183} 184 185void MoveDragController::SetInputEventConsumer() 186{ 187 if (!inputListener_ || !inputEventHandler_) { 188 WLOGFE("InputListener or inputEventHandler is nullptr"); 189 return; 190 } 191 MMI::InputManager::GetInstance()->SetWindowInputEventConsumer(inputListener_, inputEventHandler_); 192} 193 194void MoveDragController::SetWindowRoot(const sptr<WindowRoot>& windowRoot) 195{ 196 windowRoot_ = windowRoot; 197} 198 199bool MoveDragController::Init() 200{ 201 // create handler for input event 202 inputEventHandler_ = std::make_shared<AppExecFwk::EventHandler>( 203 AppExecFwk::EventRunner::Create(INNER_WM_INPUT_THREAD_NAME)); 204 if (inputEventHandler_ == nullptr) { 205 return false; 206 } 207 int ret = HiviewDFX::Watchdog::GetInstance().AddThread(INNER_WM_INPUT_THREAD_NAME, inputEventHandler_); 208 if (ret != 0) { 209 WLOGFE("Add watchdog thread failed"); 210 } 211 inputListener_ = std::make_shared<DragInputEventListener>(DragInputEventListener()); 212 SetInputEventConsumer(); 213 return true; 214} 215 216void MoveDragController::Stop() 217{ 218 if (inputEventHandler_ != nullptr) { 219 inputEventHandler_.reset(); 220 } 221} 222 223void MoveDragController::HandleReadyToMoveOrDrag(uint32_t windowId, sptr<WindowProperty>& windowProperty, 224 sptr<MoveDragProperty>& moveDragProperty) 225{ 226 SetActiveWindowId(windowId); 227 SetWindowProperty(windowProperty); 228 SetDragProperty(moveDragProperty); 229} 230 231void MoveDragController::HandleEndUpMovingOrDragging(uint32_t windowId) 232{ 233 if (activeWindowId_ != windowId) { 234 WLOGFE("end up moving or dragging failed, windowId: %{public}u", windowId); 235 return; 236 } 237 ResetMoveOrDragState(); 238} 239 240void MoveDragController::HandleWindowRemovedOrDestroyed(uint32_t windowId) 241{ 242 if (GetMoveDragProperty() == nullptr) { 243 return; 244 } 245 if (!(GetMoveDragProperty()->startMoveFlag_ || GetMoveDragProperty()->startDragFlag_)) { 246 return; 247 } 248 249 { 250 std::lock_guard<std::mutex> lock(mtx_); 251 auto iter = vsyncStationMap_.find(windowId); 252 if (iter != vsyncStationMap_.end()) { 253 auto vsyncStation = iter->second; 254 vsyncStation->RemoveCallback(); 255 vsyncStationMap_.erase(windowId); 256 } 257 } 258 259 ResetMoveOrDragState(); 260} 261 262void MoveDragController::ConvertPointerPosToDisplayGroupPos(DisplayId displayId, int32_t& posX, int32_t& posY) 263{ 264 auto displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId); 265 posX += displayRect.posX_; 266 posY += displayRect.posY_; 267} 268 269void MoveDragController::HandleDisplayLimitRectChange(const std::map<DisplayId, Rect>& limitRectMap) 270{ 271 limitRectMap_.clear(); 272 for (auto& elem : limitRectMap) { 273 limitRectMap_.insert(elem); 274 } 275} 276 277void MoveDragController::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) 278{ 279 if (pointerEvent == nullptr) { 280 WLOGFE("pointerEvent is nullptr or is handling pointer event"); 281 return; 282 } 283 if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_MOVE) { 284 moveEvent_ = pointerEvent; 285 uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId()); 286 auto vsyncStation = GetVsyncStationByWindowId(windowId); 287 if (vsyncStation != nullptr) { 288 vsyncStation->RequestVsync(vsyncCallback_); 289 } 290 } else { 291 WLOGFD("[WMS] Dispatch non-move event, action: %{public}d", pointerEvent->GetPointerAction()); 292 HandlePointerEvent(pointerEvent); 293 pointerEvent->MarkProcessed(); 294 } 295} 296 297void MoveDragController::OnReceiveVsync(int64_t timeStamp) 298{ 299 if (moveEvent_ == nullptr) { 300 WLOGFE("moveEvent is nullptr"); 301 return; 302 } 303 WLOGFD("[OnReceiveVsync] receive move event, action: %{public}d", moveEvent_->GetPointerAction()); 304 HandlePointerEvent(moveEvent_); 305 moveEvent_->MarkProcessed(); 306} 307 308Rect MoveDragController::GetHotZoneRect() 309{ 310 auto startPointPosX = moveDragProperty_->startPointPosX_; 311 auto startPointPosY = moveDragProperty_->startPointPosY_; 312 ConvertPointerPosToDisplayGroupPos(moveDragProperty_->targetDisplayId_, startPointPosX, startPointPosY); 313 314 Rect hotZoneRect; 315 const auto& startRectExceptCorner = moveDragProperty_->startRectExceptCorner_; 316 const auto& startRectExceptFrame = moveDragProperty_->startRectExceptFrame_; 317 if ((startPointPosX > startRectExceptCorner.posX_ && 318 (startPointPosX < startRectExceptCorner.posX_ + 319 static_cast<int32_t>(startRectExceptCorner.width_))) && 320 (startPointPosY > startRectExceptCorner.posY_ && 321 (startPointPosY < startRectExceptCorner.posY_ + 322 static_cast<int32_t>(startRectExceptCorner.height_)))) { 323 hotZoneRect = startRectExceptFrame; // drag type: left/right/top/bottom 324 } else { 325 hotZoneRect = startRectExceptCorner; // drag type: left_top/right_top/left_bottom/right_bottom 326 } 327 return hotZoneRect; 328} 329 330bool MoveDragController::CheckWindowRect(DisplayId displayId, float vpr, const Rect& rect) 331{ 332 uint32_t titleBarHeight = static_cast<uint32_t>(WINDOW_TITLE_BAR_HEIGHT * vpr); 333 auto iter = limitRectMap_.find(displayId); 334 Rect limitRect; 335 if (iter != limitRectMap_.end()) { 336 limitRect = iter->second; 337 } 338 if (WindowHelper::IsEmptyRect(limitRect) || MathHelper::NearZero(vpr)) { 339 return true; // If limitRect is empty, we can't use limitRect to check window rect 340 } 341 342 if ((rect.posX_ > static_cast<int32_t>(limitRect.posX_ + limitRect.width_ - titleBarHeight)) || 343 (rect.posX_ + static_cast<int32_t>(rect.width_) < 344 static_cast<int32_t>(limitRect.posX_ + titleBarHeight)) || 345 (rect.posY_ < limitRect.posY_) || 346 (rect.posY_ > static_cast<int32_t>(limitRect.posY_ + limitRect.height_ - titleBarHeight))) { 347 WLOGFD("[WMS] Invalid window rect, id: %{public}u, rect: [%{public}d, %{public}d, %{public}d, %{public}d]", 348 windowProperty_->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); 349 return false; 350 } 351 return true; 352} 353 354void MoveDragController::CalculateNewWindowRect(Rect& newRect, DisplayId displayId, int32_t posX, int32_t posY) 355{ 356 auto startPointPosX = moveDragProperty_->startPointPosX_; 357 auto startPointPosY = moveDragProperty_->startPointPosY_; 358 ConvertPointerPosToDisplayGroupPos(moveDragProperty_->targetDisplayId_, startPointPosX, startPointPosY); 359 const auto& startPointRect = moveDragProperty_->startPointRect_; 360 Rect hotZoneRect = GetHotZoneRect(); 361 int32_t diffX = posX - startPointPosX; 362 int32_t diffY = posY - startPointPosY; 363 364 float vpr = DisplayGroupInfo::GetInstance().GetDisplayVirtualPixelRatio(displayId); 365 if (MathHelper::NearZero(vpr)) { 366 return; 367 } 368 uint32_t minWidth = static_cast<uint32_t>(MIN_FLOATING_WIDTH * vpr); 369 uint32_t minHeight = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * vpr); 370 if (startPointPosX <= hotZoneRect.posX_) { 371 if (diffX > static_cast<int32_t>(startPointRect.width_ - minWidth)) { 372 diffX = static_cast<int32_t>(startPointRect.width_ - minWidth); 373 } 374 newRect.posX_ += diffX; 375 newRect.width_ = static_cast<uint32_t>(static_cast<int32_t>(newRect.width_) - diffX); 376 } else if (startPointPosX >= hotZoneRect.posX_ + static_cast<int32_t>(hotZoneRect.width_)) { 377 if (diffX < 0 && (-diffX > static_cast<int32_t>(startPointRect.width_ - minWidth))) { 378 diffX = -(static_cast<int32_t>(startPointRect.width_ - minWidth)); 379 } 380 newRect.width_ = static_cast<uint32_t>(static_cast<int32_t>(newRect.width_) + diffX); 381 } 382 if (startPointPosY <= hotZoneRect.posY_) { 383 if (diffY > static_cast<int32_t>(startPointRect.height_ - minHeight)) { 384 diffY = static_cast<int32_t>(startPointRect.height_ - minHeight); 385 } 386 newRect.posY_ += diffY; 387 newRect.height_ = static_cast<uint32_t>(static_cast<int32_t>(newRect.height_) - diffY); 388 } else if (startPointPosY >= hotZoneRect.posY_ + static_cast<int32_t>(hotZoneRect.height_)) { 389 if (diffY < 0 && (-diffY > static_cast<int32_t>(startPointRect.height_ - minHeight))) { 390 diffY = -(static_cast<int32_t>(startPointRect.height_ - minHeight)); 391 } 392 newRect.height_ = static_cast<uint32_t>(static_cast<int32_t>(newRect.height_) + diffY); 393 } 394} 395 396void MoveDragController::HandleDragEvent(DisplayId displayId, int32_t posX, int32_t posY, 397 int32_t pointId, int32_t sourceType) 398{ 399 if (moveDragProperty_ == nullptr || !moveDragProperty_->startDragFlag_ || 400 (pointId != moveDragProperty_->startPointerId_) || (sourceType != moveDragProperty_->sourceType_)) { 401 return; 402 } 403 404 Rect newRect = moveDragProperty_->startPointRect_; 405 CalculateNewWindowRect(newRect, displayId, posX, posY); 406 407 if (!CheckWindowRect(displayId, DisplayGroupInfo::GetInstance().GetDisplayVirtualPixelRatio(displayId), newRect)) { 408 return; 409 } 410 411 WLOGFD("[WMS] HandleDragEvent, id: %{public}u, newRect: [%{public}d, %{public}d, %{public}d, %{public}d]", 412 windowProperty_->GetWindowId(), newRect.posX_, newRect.posY_, newRect.width_, newRect.height_); 413 windowProperty_->SetRequestRect(newRect); 414 windowProperty_->SetWindowSizeChangeReason(WindowSizeChangeReason::DRAG); 415 windowProperty_->SetDragType(moveDragProperty_->dragType_); 416 WindowManagerService::GetInstance().UpdateProperty(windowProperty_, PropertyChangeAction::ACTION_UPDATE_RECT, true); 417} 418 419void MoveDragController::HandleMoveEvent(DisplayId displayId, int32_t posX, int32_t posY, 420 int32_t pointId, int32_t sourceType) 421{ 422 if (moveDragProperty_ == nullptr) { 423 return; 424 } 425 if (!moveDragProperty_->startMoveFlag_ || 426 (pointId != moveDragProperty_->startPointerId_) || 427 (sourceType != moveDragProperty_->sourceType_)) { 428 return; 429 } 430 auto startPointPosX = moveDragProperty_->startPointPosX_; 431 auto startPointPosY = moveDragProperty_->startPointPosY_; 432 ConvertPointerPosToDisplayGroupPos(moveDragProperty_->targetDisplayId_, startPointPosX, startPointPosY); 433 int32_t targetX = moveDragProperty_->startPointRect_.posX_ + (posX - startPointPosX); 434 int32_t targetY = moveDragProperty_->startPointRect_.posY_ + (posY - startPointPosY); 435 436 const Rect& oriRect = moveDragProperty_->startPointRect_; 437 Rect newRect = { targetX, targetY, oriRect.width_, oriRect.height_ }; 438 if (limitRectMap_.find(displayId) != limitRectMap_.end()) { 439 newRect.posY_ = std::max(newRect.posY_, limitRectMap_[displayId].posY_); 440 } 441 WLOGFD("[WMS] HandleMoveEvent, id: %{public}u, newRect: [%{public}d, %{public}d, %{public}d, %{public}d]", 442 windowProperty_->GetWindowId(), newRect.posX_, newRect.posY_, newRect.width_, newRect.height_); 443 windowProperty_->SetRequestRect(newRect); 444 windowProperty_->SetWindowSizeChangeReason(WindowSizeChangeReason::MOVE); 445 WindowManagerService::GetInstance().UpdateProperty(windowProperty_, PropertyChangeAction::ACTION_UPDATE_RECT, true); 446} 447 448void MoveDragController::HandlePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) 449{ 450 if (windowProperty_) { 451 windowProperty_->UpdatePointerEvent(pointerEvent); 452 } 453 MMI::PointerEvent::PointerItem pointerItem; 454 int32_t pointId = pointerEvent->GetPointerId(); 455 int32_t sourceType = pointerEvent->GetSourceType(); 456 if (!pointerEvent->GetPointerItem(pointId, pointerItem) || 457 (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE && 458 pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT)) { 459 WLOGFW("invalid pointerEvent"); 460 return; 461 } 462 463 int32_t pointPosX = pointerItem.GetDisplayX(); 464 int32_t pointPosY = pointerItem.GetDisplayY(); 465 int32_t action = pointerEvent->GetPointerAction(); 466 int32_t targetDisplayId = pointerEvent->GetTargetDisplayId(); 467 ConvertPointerPosToDisplayGroupPos(targetDisplayId, pointPosX, pointPosY); 468 switch (action) { 469 case MMI::PointerEvent::POINTER_ACTION_DOWN: 470 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN: { 471 if (pointId == moveDragProperty_->startPointerId_ && sourceType == moveDragProperty_->sourceType_) { 472 moveDragProperty_->startMoveFlag_ = false; 473 moveDragProperty_->startDragFlag_ = false; 474 } 475 TLOGD(WmsLogTag::WMS_EVENT, "windowId:%{public}u, pointId:%{public}d, sourceType:%{public}d, " 476 "hasPointStarted:%{public}d, startMove:%{public}d, startDrag:%{public}d, targetDisplayId:" 477 "%{public}d, pointPos:[%{private}d, %{private}d]", activeWindowId_, pointId, sourceType, 478 moveDragProperty_->pointEventStarted_, moveDragProperty_->startMoveFlag_, 479 moveDragProperty_->startDragFlag_, targetDisplayId, pointPosX, pointPosY); 480 break; 481 } 482 // ready to move or drag 483 case MMI::PointerEvent::POINTER_ACTION_MOVE: { 484 HandleMoveEvent(targetDisplayId, pointPosX, pointPosY, pointId, sourceType); 485 HandleDragEvent(targetDisplayId, pointPosX, pointPosY, pointId, sourceType); 486 break; 487 } 488 // End move or drag 489 case MMI::PointerEvent::POINTER_ACTION_UP: 490 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP: 491 case MMI::PointerEvent::POINTER_ACTION_CANCEL: { 492 WindowManagerService::GetInstance().NotifyWindowClientPointUp(activeWindowId_, pointerEvent); 493 WLOGFD("[Server Point Up/Cancel]: windowId: %{public}u, action: %{public}d, sourceType: %{public}d", 494 activeWindowId_, action, sourceType); 495 break; 496 } 497 default: 498 break; 499 } 500} 501 502void MoveDragController::SetDragProperty(const sptr<MoveDragProperty>& moveDragProperty) 503{ 504 moveDragProperty_->CopyFrom(moveDragProperty); 505} 506 507void MoveDragController::SetWindowProperty(const sptr<WindowProperty>& windowProperty) 508{ 509 windowProperty_->CopyFrom(windowProperty); 510} 511 512const sptr<MoveDragProperty>& MoveDragController::GetMoveDragProperty() const 513{ 514 return moveDragProperty_; 515} 516 517const sptr<WindowProperty>& MoveDragController::GetWindowProperty() const 518{ 519 return windowProperty_; 520} 521 522void MoveDragController::ResetMoveOrDragState() 523{ 524 activeWindowId_ = INVALID_WINDOW_ID; 525 auto moveDragProperty = new MoveDragProperty(); 526 SetDragProperty(moveDragProperty); 527} 528 529void MoveDragController::SetActiveWindowId(uint32_t activeWindowId) 530{ 531 activeWindowId_ = activeWindowId; 532} 533 534uint32_t MoveDragController::GetActiveWindowId() const 535{ 536 return activeWindowId_; 537} 538 539std::shared_ptr<VsyncStation> MoveDragController::GetVsyncStationByWindowId(uint32_t windowId) 540{ 541 { 542 std::lock_guard<std::mutex> lock(mtx_); 543 auto iter = vsyncStationMap_.find(windowId); 544 if (iter != vsyncStationMap_.end()) { 545 return iter->second; 546 } 547 } 548 549 if (windowRoot_ == nullptr) { 550 TLOGE(WmsLogTag::WMS_MAIN, "Get vsync station failed, windowRoot is nullptr"); 551 return nullptr; 552 } 553 554 sptr<WindowNode> node = windowRoot_->GetWindowNode(windowId); 555 if (node == nullptr || node->surfaceNode_ == nullptr) { 556 TLOGE(WmsLogTag::WMS_MAIN, "Get vsync station failed, surfaceNode is nullptr"); 557 return nullptr; 558 } 559 560 auto vsyncStation = std::make_shared<VsyncStation>(node->surfaceNode_->GetId(), inputEventHandler_); 561 if (vsyncStation == nullptr) { 562 TLOGE(WmsLogTag::WMS_MAIN, "Get vsync station failed, create vsyncStation is nullptr"); 563 return nullptr; 564 } 565 566 { 567 std::lock_guard<std::mutex> lock(mtx_); 568 vsyncStationMap_.emplace(windowId, vsyncStation); 569 } 570 571 return vsyncStation; 572} 573} 574} 575