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 
31 namespace OHOS {
32 namespace Rosen {
33 namespace {
34 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DragController"};
35 }
36 
UpdateDragInfo(uint32_t windowId)37 void 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 
StartDrag(uint32_t windowId)67 void 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 
FinishDrag(uint32_t windowId)90 void 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 
GetHitWindow(DisplayId id,PointInfo point)113 sptr<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 
GetHitPoint(uint32_t windowId,PointInfo & point)139 bool 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 
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const152 void 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 
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const163 void 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 
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const173 void 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 
SetInputEventConsumer()185 void 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 
SetWindowRoot(const sptr<WindowRoot> & windowRoot)194 void MoveDragController::SetWindowRoot(const sptr<WindowRoot>& windowRoot)
195 {
196     windowRoot_ = windowRoot;
197 }
198 
Init()199 bool 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 
Stop()216 void MoveDragController::Stop()
217 {
218     if (inputEventHandler_ != nullptr) {
219         inputEventHandler_.reset();
220     }
221 }
222 
HandleReadyToMoveOrDrag(uint32_t windowId,sptr<WindowProperty> & windowProperty,sptr<MoveDragProperty> & moveDragProperty)223 void MoveDragController::HandleReadyToMoveOrDrag(uint32_t windowId, sptr<WindowProperty>& windowProperty,
224     sptr<MoveDragProperty>& moveDragProperty)
225 {
226     SetActiveWindowId(windowId);
227     SetWindowProperty(windowProperty);
228     SetDragProperty(moveDragProperty);
229 }
230 
HandleEndUpMovingOrDragging(uint32_t windowId)231 void 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 
HandleWindowRemovedOrDestroyed(uint32_t windowId)240 void 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 
ConvertPointerPosToDisplayGroupPos(DisplayId displayId,int32_t & posX,int32_t & posY)262 void 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 
HandleDisplayLimitRectChange(const std::map<DisplayId,Rect> & limitRectMap)269 void MoveDragController::HandleDisplayLimitRectChange(const std::map<DisplayId, Rect>& limitRectMap)
270 {
271     limitRectMap_.clear();
272     for (auto& elem : limitRectMap) {
273         limitRectMap_.insert(elem);
274     }
275 }
276 
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)277 void 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 
OnReceiveVsync(int64_t timeStamp)297 void 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 
GetHotZoneRect()308 Rect 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 
CheckWindowRect(DisplayId displayId,float vpr,const Rect & rect)330 bool 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 
CalculateNewWindowRect(Rect & newRect,DisplayId displayId,int32_t posX,int32_t posY)354 void 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 
HandleDragEvent(DisplayId displayId,int32_t posX,int32_t posY,int32_t pointId,int32_t sourceType)396 void 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 
HandleMoveEvent(DisplayId displayId,int32_t posX,int32_t posY,int32_t pointId,int32_t sourceType)419 void 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::DRAG_MOVE);
445     WindowManagerService::GetInstance().UpdateProperty(windowProperty_, PropertyChangeAction::ACTION_UPDATE_RECT, true);
446 }
447 
HandlePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)448 void 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 
SetDragProperty(const sptr<MoveDragProperty> & moveDragProperty)502 void MoveDragController::SetDragProperty(const sptr<MoveDragProperty>& moveDragProperty)
503 {
504     moveDragProperty_->CopyFrom(moveDragProperty);
505 }
506 
SetWindowProperty(const sptr<WindowProperty> & windowProperty)507 void MoveDragController::SetWindowProperty(const sptr<WindowProperty>& windowProperty)
508 {
509     windowProperty_->CopyFrom(windowProperty);
510 }
511 
GetMoveDragProperty() const512 const sptr<MoveDragProperty>& MoveDragController::GetMoveDragProperty() const
513 {
514     return moveDragProperty_;
515 }
516 
GetWindowProperty() const517 const sptr<WindowProperty>& MoveDragController::GetWindowProperty() const
518 {
519     return windowProperty_;
520 }
521 
ResetMoveOrDragState()522 void MoveDragController::ResetMoveOrDragState()
523 {
524     activeWindowId_ = INVALID_WINDOW_ID;
525     auto moveDragProperty = new MoveDragProperty();
526     SetDragProperty(moveDragProperty);
527 }
528 
SetActiveWindowId(uint32_t activeWindowId)529 void MoveDragController::SetActiveWindowId(uint32_t activeWindowId)
530 {
531     activeWindowId_ = activeWindowId;
532 }
533 
GetActiveWindowId() const534 uint32_t MoveDragController::GetActiveWindowId() const
535 {
536     return activeWindowId_;
537 }
538 
GetVsyncStationByWindowId(uint32_t windowId)539 std::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