• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "session/host/include/move_drag_controller.h"
17 
18 #include <hitrace_meter.h>
19 #include <pointer_event.h>
20 #include <transaction/rs_transaction.h>
21 #include <ui/rs_surface_node.h>
22 
23 #include <cinttypes>
24 
25 #include "display_manager.h"
26 #include "input_manager.h"
27 #include "screen_session_manager_client/include/screen_session_manager_client.h"
28 #include "session/host/include/scene_persistent_storage.h"
29 #include "session/host/include/scene_session.h"
30 #include "session/host/include/session_utils.h"
31 #include "session_helper.h"
32 #include "window_helper.h"
33 #include "window_manager_hilog.h"
34 #include "wm_common_inner.h"
35 
36 #ifdef RES_SCHED_ENABLE
37 #include "res_sched_client.h"
38 #include "res_type.h"
39 #endif
40 
41 namespace OHOS::Rosen {
42 namespace {
43 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "MoveDragController"};
44 }
45 
MoveDragController(int32_t persistentId,WindowType winType)46 MoveDragController::MoveDragController(int32_t persistentId, WindowType winType)
47 {
48     persistentId_ = persistentId;
49     winType_ = winType;
50 }
51 
OnConnect(ScreenId id)52 void MoveDragController::OnConnect(ScreenId id)
53 {
54     TLOGW(WmsLogTag::WMS_LAYOUT, "Moving or dragging is interrupt due to new screen %{public}" PRIu64 " connection.",
55         id);
56     moveDragIsInterrupted_ = true;
57 }
58 
OnDisconnect(ScreenId id)59 void MoveDragController::OnDisconnect(ScreenId id)
60 {
61     TLOGW(WmsLogTag::WMS_LAYOUT, "Moving or dragging is interrupt due to screen %{public}" PRIu64 " disconnection.",
62         id);
63     moveDragIsInterrupted_ = true;
64 }
65 
OnChange(ScreenId id)66 void MoveDragController::OnChange(ScreenId id)
67 {
68     TLOGW(WmsLogTag::WMS_LAYOUT, "Moving or dragging is interrupt due to screen %{public}" PRIu64 " change.", id);
69     moveDragIsInterrupted_ = true;
70 }
71 
RegisterMoveDragCallback(const MoveDragCallback & callBack)72 void MoveDragController::RegisterMoveDragCallback(const MoveDragCallback& callBack)
73 {
74     moveDragCallback_ = callBack;
75 }
76 
NotifyWindowInputPidChange(bool isServerPid)77 void MoveDragController::NotifyWindowInputPidChange(bool isServerPid)
78 {
79     if (pidChangeCallback_) {
80         pidChangeCallback_(persistentId_, isServerPid);
81         WLOGFI("id: %{public}d, isServerPid:%{public}d", persistentId_, isServerPid);
82     }
83 }
84 
HasPointDown()85 bool MoveDragController::HasPointDown()
86 {
87     return hasPointDown_;
88 }
89 
SetStartMoveFlag(bool flag)90 void MoveDragController::SetStartMoveFlag(bool flag)
91 {
92     if (flag && (!hasPointDown_ || isStartDrag_)) {
93         WLOGFD("StartMove, but has not pointed down or is dragging, hasPointDown_: %{public}d, isStartFlag: %{public}d",
94             hasPointDown_, isStartDrag_);
95         return;
96     }
97     NotifyWindowInputPidChange(flag);
98     isStartMove_ = flag;
99     ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_MOVE_WINDOW, flag);
100     WLOGFI("SetStartMoveFlag, isStartMove_: %{public}d id:%{public}d", isStartMove_, persistentId_);
101 }
102 
SetMovable(bool isMovable)103 void MoveDragController::SetMovable(bool isMovable)
104 {
105     isMovable_ = isMovable;
106 }
107 
SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback & callback)108 void MoveDragController::SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback& callback)
109 {
110     pidChangeCallback_ = callback;
111 }
112 
GetStartMoveFlag() const113 bool MoveDragController::GetStartMoveFlag() const
114 {
115     WLOGFD("GetStartMoveFlag, isStartMove_: %{public}d id:%{public}d", isStartMove_, persistentId_);
116     return isStartMove_;
117 }
118 
GetStartDragFlag() const119 bool MoveDragController::GetStartDragFlag() const
120 {
121     return isStartDrag_;
122 }
123 
GetMoveDragStartDisplayId() const124 uint64_t MoveDragController::GetMoveDragStartDisplayId() const
125 {
126     return moveDragStartDisplayId_;
127 }
128 
GetMoveDragEndDisplayId() const129 uint64_t MoveDragController::GetMoveDragEndDisplayId() const
130 {
131     return moveDragEndDisplayId_;
132 }
133 
GetInitParentNodeId() const134 uint64_t MoveDragController::GetInitParentNodeId() const
135 {
136     return initParentNodeId_;
137 }
138 
GetDisplayIdsDuringMoveDrag()139 std::set<uint64_t> MoveDragController::GetDisplayIdsDuringMoveDrag()
140 {
141     std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
142     return displayIdSetDuringMoveDrag_;
143 }
144 
GetMovable() const145 bool MoveDragController::GetMovable() const
146 {
147     return isMovable_;
148 }
149 
SetTargetRect(const WSRect & rect)150 void MoveDragController::SetTargetRect(const WSRect& rect)
151 {
152     moveDragProperty_.targetRect_ = rect;
153 }
154 
GetOriginalRect() const155 WSRect MoveDragController::GetOriginalRect() const
156 {
157     return moveDragProperty_.originalRect_;
158 }
159 
GetTargetRect(TargetRectCoordinate coordinate) const160 WSRect MoveDragController::GetTargetRect(TargetRectCoordinate coordinate) const
161 {
162     DisplayId relatedDisplayId = DISPLAY_ID_INVALID;
163     switch (coordinate) {
164         case TargetRectCoordinate::GLOBAL:
165             return {moveDragProperty_.targetRect_.posX_ + originalDisplayOffsetX_,
166                     moveDragProperty_.targetRect_.posY_ + originalDisplayOffsetY_,
167                     moveDragProperty_.targetRect_.width_,
168                     moveDragProperty_.targetRect_.height_};
169         case TargetRectCoordinate::RELATED_TO_START_DISPLAY:
170             return moveDragProperty_.targetRect_;
171         case TargetRectCoordinate::RELATED_TO_END_DISPLAY:
172             relatedDisplayId = moveDragEndDisplayId_;
173             break;
174         default:
175             return moveDragProperty_.targetRect_;
176     }
177     return GetTargetRectByDisplayId(relatedDisplayId);
178 }
179 
GetTargetRectByDisplayId(DisplayId displayId) const180 WSRect MoveDragController::GetTargetRectByDisplayId(DisplayId displayId) const
181 {
182     sptr<ScreenSession> screenSession =
183         ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
184     if (!screenSession) {
185         TLOGW(WmsLogTag::WMS_LAYOUT, "Screen session is null, return relative coordinates.");
186         return moveDragProperty_.targetRect_;
187     }
188     ScreenProperty screenProperty = screenSession->GetScreenProperty();
189     int32_t currentDisplayOffsetX = static_cast<int32_t>(screenProperty.GetStartX());
190     int32_t currentDisplayOffsetY = static_cast<int32_t>(screenProperty.GetStartY());
191     return {moveDragProperty_.targetRect_.posX_ + originalDisplayOffsetX_ - currentDisplayOffsetX,
192             moveDragProperty_.targetRect_.posY_ + originalDisplayOffsetY_ - currentDisplayOffsetY,
193             moveDragProperty_.targetRect_.width_,
194             moveDragProperty_.targetRect_.height_};
195 }
196 
UpdateSubWindowGravityWhenFollow(const sptr<MoveDragController> & followedController,const std::shared_ptr<RSSurfaceNode> & surfaceNode)197 void MoveDragController::UpdateSubWindowGravityWhenFollow(const sptr<MoveDragController>& followedController,
198     const std::shared_ptr<RSSurfaceNode>& surfaceNode)
199 {
200     if (surfaceNode == nullptr || followedController == nullptr) {
201         TLOGE(WmsLogTag::WMS_LAYOUT, "surfaceNode or followedController is null");
202         return;
203     }
204     auto type = followedController->GetAreaType();
205     if (type == AreaType::UNDEFINED) {
206         TLOGI(WmsLogTag::WMS_LAYOUT, "type undefined");
207         return;
208     }
209     Gravity dragGravity = GRAVITY_MAP.at(type);
210     if (dragGravity >= Gravity::TOP && dragGravity <= Gravity::BOTTOM_RIGHT) {
211         TLOGI(WmsLogTag::WMS_LAYOUT, "begin SetFrameGravity when follow, gravity:%{public}d, type:%{public}d",
212             dragGravity, type);
213         surfaceNode->SetFrameGravity(dragGravity);
214         RSTransaction::FlushImplicitTransaction();
215     }
216 }
217 
218 /** @note @window.drag */
InitMoveDragProperty()219 void MoveDragController::InitMoveDragProperty()
220 {
221     moveDragProperty_ = {-1, -1, -1, -1, -1, -1, {0, 0, 0, 0}, {0, 0, 0, 0}};
222 }
223 
InitCrossDisplayProperty(DisplayId displayId,uint64_t initParentNodeId)224 void MoveDragController::InitCrossDisplayProperty(DisplayId displayId, uint64_t initParentNodeId)
225 {
226     DMError error = ScreenManager::GetInstance().RegisterScreenListener(this);
227     if (error != DMError::DM_OK) {
228         TLOGW(WmsLogTag::WMS_LAYOUT, "Register ScreenListener false.");
229     }
230     {
231         std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
232         displayIdSetDuringMoveDrag_.insert(displayId);
233     }
234     moveDragStartDisplayId_ = displayId;
235     initParentNodeId_ = initParentNodeId;
236     sptr<ScreenSession> screenSession =
237         ScreenSessionManagerClient::GetInstance().GetScreenSessionById(moveDragStartDisplayId_);
238     if (!screenSession) {
239         return;
240     }
241     ScreenProperty screenProperty = screenSession->GetScreenProperty();
242     originalDisplayOffsetX_ = static_cast<int32_t>(screenProperty.GetStartX());
243     originalDisplayOffsetY_ = static_cast<int32_t>(screenProperty.GetStartY());
244     TLOGI(WmsLogTag::WMS_LAYOUT, "moveDragStartDisplayId: %{public}" PRIu64 ", "
245         "originalDisplayOffsetX: %{public}d, originalDisplayOffsetY: %{public}d",
246         moveDragStartDisplayId_, originalDisplayOffsetX_, originalDisplayOffsetY_);
247 }
248 
249 /** @note @window.drag */
ResetCrossMoveDragProperty()250 void MoveDragController::ResetCrossMoveDragProperty()
251 {
252     moveDragProperty_ = {-1, -1, -1, -1, -1, -1, {0, 0, 0, 0}, {0, 0, 0, 0}};
253     DMError error = ScreenManager::GetInstance().UnregisterScreenListener(this);
254     if (error != DMError::DM_OK) {
255         TLOGW(WmsLogTag::WMS_LAYOUT, "Register ScreenListener false.");
256     }
257     {
258         std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
259         displayIdSetDuringMoveDrag_.clear();
260     }
261     moveDragStartDisplayId_ = DISPLAY_ID_INVALID;
262     moveInputBarStartDisplayId_ = DISPLAY_ID_INVALID;
263     moveDragEndDisplayId_ = DISPLAY_ID_INVALID;
264     initParentNodeId_ = -1;
265     originalDisplayOffsetX_ = 0;
266     originalDisplayOffsetY_ = 0;
267     moveDragIsInterrupted_ = false;
268 }
269 
SetOriginalMoveDragPos(int32_t pointerId,int32_t pointerType,int32_t pointerPosX,int32_t pointerPosY,int32_t pointerWindowX,int32_t pointerWindowY,const WSRect & winRect)270 void MoveDragController::SetOriginalMoveDragPos(int32_t pointerId, int32_t pointerType, int32_t pointerPosX,
271     int32_t pointerPosY, int32_t pointerWindowX, int32_t pointerWindowY, const WSRect& winRect)
272 {
273     moveDragProperty_.pointerId_ = pointerId;
274     moveDragProperty_.pointerType_ = pointerType;
275     moveDragProperty_.originalPointerPosX_ = pointerPosX;
276     moveDragProperty_.originalPointerPosY_ = pointerPosY;
277     moveDragProperty_.originalPointerWindowX_ = pointerWindowX;
278     moveDragProperty_.originalPointerWindowY_ = pointerWindowY;
279     moveDragProperty_.originalRect_ = winRect;
280 }
281 
282 /** @note @window.drag */
GetFullScreenToFloatingRect(const WSRect & originalRect,const WSRect & windowRect)283 WSRect MoveDragController::GetFullScreenToFloatingRect(const WSRect& originalRect, const WSRect& windowRect)
284 {
285     if (moveTempProperty_.isEmpty()) {
286         TLOGI(WmsLogTag::WMS_LAYOUT, "move temporary property is empty");
287         return originalRect;
288     }
289     if (originalRect.width_ == 0) {
290         TLOGI(WmsLogTag::WMS_LAYOUT, "original rect witch is zero");
291         return windowRect;
292     }
293     // Drag and drop to full screen in proportion
294     float newPosX = static_cast<float>(windowRect.width_) / static_cast<float>(originalRect.width_) *
295         static_cast<float>(moveTempProperty_.lastDownPointerPosX_ - originalRect.posX_);
296     WSRect targetRect = {
297         moveTempProperty_.lastDownPointerPosX_ - static_cast<int32_t>(newPosX),
298         originalRect.posY_,
299         windowRect.width_,
300         windowRect.height_,
301     };
302     TLOGI(WmsLogTag::WMS_LAYOUT, "target rect [%{public}d,%{public}d,%{public}u,%{public}u]", targetRect.posX_,
303         targetRect.posY_, targetRect.width_, targetRect.height_);
304     return targetRect;
305 }
306 
SetAspectRatio(float ratio)307 void MoveDragController::SetAspectRatio(float ratio)
308 {
309     aspectRatio_ = ratio;
310 }
311 
ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)312 bool MoveDragController::ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
313     const WSRect& originalRect)
314 {
315     if (pointerEvent == nullptr) {
316         WLOGE("ConsumeMoveEvent stop because of nullptr");
317         return false;
318     }
319     if (GetStartDragFlag()) {
320         WLOGFI("the window is being resized");
321         return false;
322     }
323     int32_t pointerId = pointerEvent->GetPointerId();
324     int32_t startPointerId = moveDragProperty_.pointerId_;
325     int32_t startPointerType = moveDragProperty_.pointerType_;
326     if ((startPointerId != -1 && startPointerId != pointerId) ||
327         (startPointerType != -1 && pointerEvent->GetSourceType() != startPointerType)) {
328         WLOGFI("block unnecessary pointer event inside the window");
329         return false;
330     }
331     MMI::PointerEvent::PointerItem pointerItem;
332     int32_t sourceType = pointerEvent->GetSourceType();
333     if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
334         (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
335          (pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT && !GetStartMoveFlag()))) {
336         WLOGFD("invalid pointerEvent id: %{public}d", persistentId_);
337         return false;
338     }
339 
340     UpdateMoveTempProperty(pointerEvent);
341 
342     int32_t action = pointerEvent->GetPointerAction();
343     if (!GetStartMoveFlag()) {
344         if (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
345             action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
346             WLOGFD("Move event hasPointDown");
347             hasPointDown_ = true;
348         } else if (action == MMI::PointerEvent::POINTER_ACTION_UP ||
349             action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
350             action == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
351             WLOGFD("Reset hasPointDown_ when point up or cancel");
352             hasPointDown_ = false;
353         }
354         WLOGFD("No need to move action id: %{public}d", action);
355         return false;
356     }
357 
358     SizeChangeReason reason = SizeChangeReason::DRAG_MOVE;
359     bool ret = true;
360     switch (action) {
361         case MMI::PointerEvent::POINTER_ACTION_MOVE: {
362             if (moveDragIsInterrupted_) {
363                 MoveDragInterrupted();
364                 return true;
365             }
366             reason = SizeChangeReason::DRAG_MOVE;
367             uint32_t oldWindowDragHotAreaType = windowDragHotAreaType_;
368             moveDragEndDisplayId_ = static_cast<uint64_t>(pointerEvent->GetTargetDisplayId());
369             UpdateHotAreaType(pointerEvent);
370             ProcessWindowDragHotAreaFunc(oldWindowDragHotAreaType != windowDragHotAreaType_, reason);
371             break;
372         }
373         case MMI::PointerEvent::POINTER_ACTION_UP:
374         case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
375         case MMI::PointerEvent::POINTER_ACTION_CANCEL:
376         case MMI::PointerEvent::POINTER_ACTION_DOWN:
377         case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN: {
378             if (!hasPointDown_) {
379                 return true;
380             }
381             if (moveDragIsInterrupted_) {
382                 MoveDragInterrupted();
383                 return true;
384             }
385             reason = SizeChangeReason::DRAG_END;
386             SetStartMoveFlag(false);
387             hasPointDown_ = false;
388             moveDragEndDisplayId_ = static_cast<uint64_t>(pointerEvent->GetTargetDisplayId());
389             UpdateHotAreaType(pointerEvent);
390             ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
391             isMoveDragHotAreaCrossDisplay_ = windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED;
392             // The Pointer up event sent to the ArkUI.
393             ret = false;
394             break;
395         }
396         default:
397             break;
398     }
399 
400     if (WindowHelper::IsInputWindow(winType_) && CalcMoveInputBarRect(pointerEvent, originalRect)) {
401         ProcessSessionRectChange(reason);
402         return ret;
403     }
404 
405     if (CalcMoveTargetRect(pointerEvent, originalRect)) {
406         ProcessSessionRectChange(reason);
407     }
408     return ret;
409 }
410 
411 /** @note @window.drag */
ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage,SizeChangeReason reason)412 void MoveDragController::ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage, SizeChangeReason reason)
413 {
414     if (isSendHotAreaMessage) {
415         WLOGFI("ProcessWindowDragHotAreaFunc start, isSendHotAreaMessage: %{public}u, reason: %{public}d",
416             isSendHotAreaMessage, reason);
417     }
418     if (windowDragHotAreaFunc_ && isSendHotAreaMessage) {
419         windowDragHotAreaFunc_(hotAreaDisplayId_, windowDragHotAreaType_, reason);
420     }
421 }
422 
423 /** @note @window.drag */
UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const std::shared_ptr<RSSurfaceNode> & surfaceNode)424 void MoveDragController::UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
425     const std::shared_ptr<RSSurfaceNode>& surfaceNode)
426 {
427     if (surfaceNode == nullptr || pointerEvent == nullptr || type_ == AreaType::UNDEFINED) {
428         return;
429     }
430     if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN ||
431         pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
432         Gravity dragGravity = GRAVITY_MAP.at(type_);
433         if (dragGravity >= Gravity::TOP && dragGravity <= Gravity::BOTTOM_RIGHT) {
434             WLOGFI("begin SetFrameGravity:%{public}d, type:%{public}d", dragGravity, type_);
435             surfaceNode->SetFrameGravity(dragGravity);
436             RSTransaction::FlushImplicitTransaction();
437         }
438         return;
439     }
440 }
441 
442 /** @note @window.drag */
CalcDragTargetRect(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,SizeChangeReason reason)443 void MoveDragController::CalcDragTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
444                                             SizeChangeReason reason)
445 {
446     if (reason == SizeChangeReason::DRAG_START) {
447         moveDragProperty_.targetRect_ = moveDragProperty_.originalRect_;
448         TLOGD(WmsLogTag::WMS_LAYOUT, "drag rect:%{public}s", moveDragProperty_.targetRect_.ToString().c_str());
449         return;
450     }
451     std::pair<int32_t, int32_t> trans = CalcUnifiedTranslate(pointerEvent);
452     if (!WindowHelper::IsSystemWindow(winType_) ||
453         static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()) == moveDragStartDisplayId_) {
454         moveDragProperty_.targetRect_ =
455             MathHelper::GreatNotEqual(aspectRatio_, NEAR_ZERO) ?
456             CalcFixedAspectRatioTargetRect(type_, trans.first, trans.second,
457             aspectRatio_, moveDragProperty_.originalRect_):
458             CalcFreeformTargetRect(type_, trans.first, trans.second, moveDragProperty_.originalRect_);
459     }
460     TLOGD(WmsLogTag::WMS_LAYOUT, "drag rect:%{public}s, tranX:%{public}d, tranY:%{public}d",
461         moveDragProperty_.targetRect_.ToString().c_str(), trans.first, trans.second);
462 }
463 
464 /** @note @window.drag */
ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)465 bool MoveDragController::ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
466     const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
467 {
468     if (!CheckDragEventLegal(pointerEvent, property)) {
469         return false;
470     }
471     int32_t pointerId = pointerEvent->GetPointerId();
472     int32_t startPointerId = moveDragProperty_.pointerId_;
473     int32_t startPointerType = moveDragProperty_.pointerType_;
474     if ((startPointerId != -1 && startPointerId != pointerId) ||
475         (startPointerType != -1 && pointerEvent->GetSourceType() != startPointerType)) {
476         TLOGE(WmsLogTag::WMS_LAYOUT, "block unnecessary pointer event inside the window");
477         return false;
478     }
479     MMI::PointerEvent::PointerItem pointerItem;
480     if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
481         WLOGE("Get PointerItem failed");
482         return false;
483     }
484     SizeChangeReason reason = SizeChangeReason::UNDEFINED;
485     switch (pointerEvent->GetPointerAction()) {
486         case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
487         case MMI::PointerEvent::POINTER_ACTION_DOWN: {
488             if (!EventDownInit(pointerEvent, originalRect, property, sysConfig)) {
489                 return false;
490             }
491             reason = SizeChangeReason::DRAG_START;
492             ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, true);
493             break;
494         }
495         case MMI::PointerEvent::POINTER_ACTION_MOVE: {
496             if (moveDragIsInterrupted_) {
497                 MoveDragInterrupted();
498                 return true;
499             }
500             reason = SizeChangeReason::DRAG;
501             break;
502         }
503         case MMI::PointerEvent::POINTER_ACTION_UP:
504         case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
505         case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
506             if (!hasPointDown_) {
507                 return true;
508             }
509             auto screenRect = GetScreenRectById(moveDragStartDisplayId_);
510             if (moveDragIsInterrupted_ || screenRect == WSRect{-1, -1, -1, -1}) {
511                 MoveDragInterrupted();
512                 return true;
513             }
514             reason = SizeChangeReason::DRAG_END;
515             isStartDrag_ = false;
516             hasPointDown_ = false;
517             moveDragEndDisplayId_ = GetTargetRect(TargetRectCoordinate::GLOBAL).IsOverlap(screenRect) ?
518                 moveDragStartDisplayId_ : static_cast<uint64_t>(pointerEvent->GetTargetDisplayId());
519             ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, false);
520             NotifyWindowInputPidChange(isStartDrag_);
521             break;
522         }
523         default:
524             return false;
525     }
526     CalcDragTargetRect(pointerEvent, reason);
527     ProcessSessionRectChange(reason);
528     return true;
529 }
530 
MoveDragInterrupted(bool resetPosition)531 void MoveDragController::MoveDragInterrupted(bool resetPosition)
532 {
533     TLOGI(WmsLogTag::WMS_LAYOUT, "Screen anomaly, MoveDrag has been interrupted.");
534     SizeChangeReason reason = SizeChangeReason::DRAG_END;
535     hasPointDown_ = false;
536     if (isStartDrag_) {
537         isStartDrag_ = false;
538         ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, false);
539         NotifyWindowInputPidChange(isStartDrag_);
540     };
541     if (GetStartMoveFlag()) {
542         SetStartMoveFlag(false);
543         ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
544     };
545     if (resetPosition) {
546         moveDragEndDisplayId_ = moveDragStartDisplayId_;
547         moveDragProperty_.targetRect_ = moveDragProperty_.originalRect_;
548     }
549     ProcessSessionRectChange(reason);
550 }
551 
StopMoving()552 void MoveDragController::StopMoving()
553 {
554     TLOGD(WmsLogTag::WMS_LAYOUT_PC, "in");
555     SizeChangeReason reason = SizeChangeReason::DRAG_END;
556     hasPointDown_ = false;
557     if (GetStartMoveFlag()) {
558         SetStartMoveFlag(false);
559         ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
560     };
561     ProcessSessionRectChange(reason);
562 }
563 
GetScreenRectById(DisplayId displayId)564 WSRect MoveDragController::GetScreenRectById(DisplayId displayId)
565 {
566     sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
567     if (!screenSession) {
568         TLOGI(WmsLogTag::WMS_LAYOUT, "ScreenSession id null.");
569         return WSRect{-1, -1, -1, -1};
570     }
571     ScreenProperty screenProperty = screenSession->GetScreenProperty();
572     WSRect screenRect = {
573         screenProperty.GetStartX(),
574         screenProperty.GetStartY(),
575         screenProperty.GetBounds().rect_.GetWidth(),
576         screenProperty.GetBounds().rect_.GetHeight(),
577     };
578     return screenRect;
579 }
580 
SetMoveAvailableArea(const DMRect & area)581 void MoveDragController::SetMoveAvailableArea(const DMRect& area)
582 {
583     moveAvailableArea_.posX_ = area.posX_;
584     moveAvailableArea_.posY_ = area.posY_;
585     moveAvailableArea_.width_ = area.width_;
586     moveAvailableArea_.height_ = area.height_;
587 }
588 
UpdateMoveAvailableArea(DisplayId targetDisplayId)589 void MoveDragController::UpdateMoveAvailableArea(DisplayId targetDisplayId)
590 {
591     sptr<Display> display = DisplayManager::GetInstance().GetDisplayById(targetDisplayId);
592     if (display == nullptr) {
593         TLOGD(WmsLogTag::WMS_KEYBOARD, "Failed to get display");
594         return;
595     }
596     DMRect availableArea;
597     DMError ret = display->GetAvailableArea(availableArea);
598     if (ret != DMError::DM_OK) {
599         return;
600     }
601     SetMoveAvailableArea(availableArea);
602 }
603 
SetMoveInputBarStartDisplayId(DisplayId displayId)604 void MoveDragController::SetMoveInputBarStartDisplayId(DisplayId displayId)
605 {
606     moveInputBarStartDisplayId_ = displayId;
607 }
608 
GetMoveInputBarStartDisplayId()609 DisplayId MoveDragController::GetMoveInputBarStartDisplayId()
610 {
611     return moveInputBarStartDisplayId_;
612 }
613 
SetCurrentScreenProperty(DisplayId targetDisplayId)614 void MoveDragController::SetCurrentScreenProperty(DisplayId targetDisplayId)
615 {
616     sptr<ScreenSession> currentScreenSession =
617         ScreenSessionManagerClient::GetInstance().GetScreenSessionById(targetDisplayId);
618     if (currentScreenSession == nullptr) {
619         TLOGW(WmsLogTag::WMS_KEYBOARD, "Screen session is null");
620         return;
621     }
622     ScreenProperty currentScreenProperty = currentScreenSession->GetScreenProperty();
623     screenSizeProperty_.currentDisplayStartX = currentScreenProperty.GetStartX();
624     screenSizeProperty_.currentDisplayStartY = currentScreenProperty.GetStartY();
625     screenSizeProperty_.currentDisplayLeft = currentScreenProperty.GetBounds().rect_.left_;
626     screenSizeProperty_.currentDisplayTop = currentScreenProperty.GetBounds().rect_.top_;
627     screenSizeProperty_.width = currentScreenProperty.GetBounds().rect_.width_;
628     screenSizeProperty_.height = currentScreenProperty.GetBounds().rect_.height_;
629 }
630 
CalcUnifiedTranslate(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)631 std::pair<int32_t, int32_t> MoveDragController::CalcUnifiedTranslate(
632     const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
633 {
634     int32_t pointerId = pointerEvent->GetPointerId();
635     MMI::PointerEvent::PointerItem pointerItem;
636     pointerEvent->GetPointerItem(pointerId, pointerItem);
637     sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(
638         static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()));
639     if (!screenSession) {
640         return std::make_pair(0, 0);
641     }
642     ScreenProperty screenProperty = screenSession->GetScreenProperty();
643     // calculate trans in unified coordinates
644     int32_t currentDisplayTranX = static_cast<int32_t>(screenProperty.GetStartX());
645     int32_t currentDisplayTranY = static_cast<int32_t>(screenProperty.GetStartY());
646     int32_t tranX = (pointerItem.GetDisplayX() + currentDisplayTranX) -
647         (moveDragProperty_.originalPointerPosX_ + originalDisplayOffsetX_);
648     int32_t tranY = (pointerItem.GetDisplayY() + currentDisplayTranY) -
649         (moveDragProperty_.originalPointerPosY_ + originalDisplayOffsetY_);
650     return std::make_pair(tranX, tranY);
651 }
652 
AdjustTargetPositionByAvailableArea(int32_t & moveDragFinalX,int32_t & moveDragFinalY)653 void MoveDragController::AdjustTargetPositionByAvailableArea(int32_t& moveDragFinalX, int32_t& moveDragFinalY)
654 {
655     moveDragFinalX = std::max(moveAvailableArea_.posX_, moveDragFinalX);
656     moveDragFinalY = std::max(moveAvailableArea_.posY_, moveDragFinalY);
657 
658     int32_t rightBoundsLimit = moveAvailableArea_.posX_ + static_cast<int32_t>(moveAvailableArea_.width_) -
659                                moveDragProperty_.originalRect_.width_;
660     int32_t bottomBoundsLimit = moveAvailableArea_.posY_ + static_cast<int32_t>(moveAvailableArea_.height_) -
661                                 moveDragProperty_.originalRect_.height_;
662 
663     if (moveDragFinalX >= rightBoundsLimit) {
664         moveDragFinalX = rightBoundsLimit;
665     }
666     if (moveDragFinalY >= bottomBoundsLimit) {
667         moveDragFinalY = bottomBoundsLimit;
668     }
669 }
670 
CalcMoveDirection(DisplayId lastDisplayId,DisplayId currentDisplayId)671 MoveDirection MoveDragController::CalcMoveDirection(DisplayId lastDisplayId, DisplayId currentDisplayId)
672 {
673     sptr<ScreenSession> lastScreenSession =
674         ScreenSessionManagerClient::GetInstance().GetScreenSessionById(lastDisplayId);
675     sptr<ScreenSession> currentScreenSession =
676         ScreenSessionManagerClient::GetInstance().GetScreenSessionById(currentDisplayId);
677     if (!lastScreenSession || !currentScreenSession) {
678         TLOGW(WmsLogTag::WMS_KEYBOARD, "Screen session is null, return default mouse move direction.");
679         return MoveDirection::UNKNOWN;
680     }
681 
682     ScreenProperty lastScreenProperty = lastScreenSession->GetScreenProperty();
683     ScreenProperty currentScreenProperty = currentScreenSession->GetScreenProperty();
684 
685     uint32_t lastOriginStartX = lastScreenProperty.GetStartX();
686     uint32_t lastOriginStartY = lastScreenProperty.GetStartY();
687     uint32_t currentOriginStartX = currentScreenProperty.GetStartX();
688     uint32_t currentOriginStartY = currentScreenProperty.GetStartY();
689 
690     uint32_t lastScreenWidth = lastScreenProperty.GetBounds().rect_.width_;
691     uint32_t lastScreenHeight = lastScreenProperty.GetBounds().rect_.height_;
692     uint32_t currentScreenWidth = currentScreenProperty.GetBounds().rect_.width_;
693     uint32_t currentScreenHeight = currentScreenProperty.GetBounds().rect_.height_;
694 
695     if (currentOriginStartX == lastOriginStartX + lastScreenWidth) {
696         return MoveDirection::LEFT_TO_RIGHT;
697     } else if (currentOriginStartX == lastOriginStartX - currentScreenWidth) {
698         return MoveDirection::RIGHT_TO_LEFT;
699     } else if (currentOriginStartY == lastOriginStartY + lastScreenHeight) {
700         return MoveDirection::UP_TO_BOTTOM;
701     } else if (currentOriginStartY == lastOriginStartY - currentScreenHeight) {
702         return MoveDirection::BOTTOM_TO_UP;
703     }
704 
705     return MoveDirection::UNKNOWN;
706 }
707 
SetOriginalDisplayOffset(int32_t offsetX,int32_t offsetY)708 void MoveDragController::SetOriginalDisplayOffset(int32_t offsetX, int32_t offsetY)
709 {
710     originalDisplayOffsetX_ = offsetX;
711     originalDisplayOffsetY_ = offsetY;
712 }
713 
SetInputBarCrossAttr(MoveDirection moveDirection,DisplayId targetDisplayId)714 void MoveDragController::SetInputBarCrossAttr(MoveDirection moveDirection, DisplayId targetDisplayId)
715 {
716     if (moveDirection == MoveDirection::LEFT_TO_RIGHT ||
717         moveDirection == MoveDirection::RIGHT_TO_LEFT) {
718         UpdateMoveAvailableArea(targetDisplayId);
719     }
720     moveInputBarStartDisplayId_ = targetDisplayId;
721     SetOriginalDisplayOffset(screenSizeProperty_.currentDisplayStartX, screenSizeProperty_.currentDisplayStartY);
722     screenSizeProperty_.Reset();
723 }
724 
InitializeMoveDragPropertyNotValid(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)725 void MoveDragController::InitializeMoveDragPropertyNotValid(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
726                                                             const WSRect& originalRect)
727 {
728     MMI::PointerEvent::PointerItem pointerItem;
729     int32_t pointerId = pointerEvent->GetPointerId();
730     pointerEvent->GetPointerItem(pointerId, pointerItem);
731 
732     int32_t pointerDisplayX = pointerItem.GetDisplayX();
733     int32_t pointerDisplayY = pointerItem.GetDisplayY();
734     moveDragProperty_.pointerId_ = pointerId;
735     moveDragProperty_.pointerType_ = pointerEvent->GetSourceType();
736     moveDragProperty_.originalPointerPosX_ = pointerDisplayX;
737     moveDragProperty_.originalPointerPosY_ = pointerDisplayY;
738     int32_t pointerWindowX = pointerItem.GetWindowX();
739     int32_t pointerWindowY = pointerItem.GetWindowY();
740     moveDragProperty_.originalRect_ = originalRect;
741     moveDragProperty_.originalRect_.posX_ = pointerDisplayX - pointerWindowX;
742     moveDragProperty_.originalRect_.posY_ = pointerDisplayY - pointerWindowY;
743 }
744 
CheckAndInitializeMoveDragProperty(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)745 bool MoveDragController::CheckAndInitializeMoveDragProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
746                                                             const WSRect& originalRect)
747 {
748     if (moveDragProperty_.isEmpty()) {
749         InitializeMoveDragPropertyNotValid(pointerEvent, originalRect);
750         return false;
751     }
752     return true;
753 }
754 
HandleLeftToRightCross(DisplayId targetDisplayId,int32_t pointerDisplayX,int32_t pointerDisplayY,int32_t & moveDragFinalX,int32_t & moveDragFinalY)755 void MoveDragController::HandleLeftToRightCross(DisplayId targetDisplayId,
756                                                 int32_t pointerDisplayX,
757                                                 int32_t pointerDisplayY,
758                                                 int32_t& moveDragFinalX,
759                                                 int32_t& moveDragFinalY)
760 {
761     if (pointerDisplayX > moveDragProperty_.originalPointerWindowX_) {
762         moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
763     } else {
764         moveDragFinalX = 0;
765     }
766     moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
767     SetInputBarCrossAttr(MoveDirection::LEFT_TO_RIGHT, targetDisplayId);
768 }
769 
HandleRightToLeftCross(DisplayId targetDisplayId,int32_t pointerDisplayX,int32_t pointerDisplayY,int32_t & moveDragFinalX,int32_t & moveDragFinalY)770 void MoveDragController::HandleRightToLeftCross(DisplayId targetDisplayId,
771                                                 int32_t pointerDisplayX,
772                                                 int32_t pointerDisplayY,
773                                                 int32_t& moveDragFinalX,
774                                                 int32_t& moveDragFinalY)
775 {
776     int32_t boundaryPos = screenSizeProperty_.width -
777         moveDragProperty_.originalRect_.width_ + moveDragProperty_.originalPointerWindowX_;
778     if (pointerDisplayX <= boundaryPos) {
779         moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
780     } else {
781         moveDragFinalX = screenSizeProperty_.width - moveDragProperty_.originalRect_.width_;
782     }
783     moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
784     SetInputBarCrossAttr(MoveDirection::RIGHT_TO_LEFT, targetDisplayId);
785 }
786 
HandleUpToBottomCross(DisplayId targetDisplayId,int32_t pointerDisplayX,int32_t pointerDisplayY,int32_t & moveDragFinalX,int32_t & moveDragFinalY)787 void MoveDragController::HandleUpToBottomCross(DisplayId targetDisplayId,
788                                                int32_t pointerDisplayX,
789                                                int32_t pointerDisplayY,
790                                                int32_t& moveDragFinalX,
791                                                int32_t& moveDragFinalY)
792 {
793     UpdateMoveAvailableArea(targetDisplayId);
794     int32_t statusBarHeight = moveAvailableArea_.posY_ - screenSizeProperty_.currentDisplayTop;
795     if (pointerDisplayY >= statusBarHeight + moveDragProperty_.originalPointerWindowY_) {
796         moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
797     } else {
798         moveDragFinalY = statusBarHeight;
799     }
800     moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
801     SetInputBarCrossAttr(MoveDirection::UP_TO_BOTTOM, targetDisplayId);
802 }
803 
HandleBottomToUpCross(DisplayId targetDisplayId,int32_t pointerDisplayX,int32_t pointerDisplayY,int32_t & moveDragFinalX,int32_t & moveDragFinalY)804 void MoveDragController::HandleBottomToUpCross(DisplayId targetDisplayId,
805                                                int32_t pointerDisplayX,
806                                                int32_t pointerDisplayY,
807                                                int32_t& moveDragFinalX,
808                                                int32_t& moveDragFinalY)
809 {
810     UpdateMoveAvailableArea(targetDisplayId);
811     int32_t dockBarHeight = screenSizeProperty_.currentDisplayTop - moveAvailableArea_.posY_ -
812                             static_cast<int32_t>(moveAvailableArea_.height_);
813     int32_t boundaryPos =
814         screenSizeProperty_.height - dockBarHeight - moveDragProperty_.originalPointerWindowY_;
815     if (pointerDisplayY <= boundaryPos) {
816         moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
817     } else {
818         moveDragFinalY = screenSizeProperty_.height - dockBarHeight - moveDragProperty_.originalPointerWindowY_;
819     }
820     moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
821     SetInputBarCrossAttr(MoveDirection::BOTTOM_TO_UP, targetDisplayId);
822 }
823 
CalcMoveForSameDisplay(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,int32_t & moveDragFinalX,int32_t & moveDragFinalY)824 void MoveDragController::CalcMoveForSameDisplay(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
825                                                 int32_t& moveDragFinalX, int32_t& moveDragFinalY)
826 {
827     MMI::PointerEvent::PointerItem pointerItem;
828     int32_t pointerId = pointerEvent->GetPointerId();
829     pointerEvent->GetPointerItem(pointerId, pointerItem);
830     int32_t pointerDisplayX = pointerItem.GetDisplayX();
831     int32_t pointerDisplayY = pointerItem.GetDisplayY();
832     moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
833     moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
834     AdjustTargetPositionByAvailableArea(moveDragFinalX, moveDragFinalY);
835 }
836 
CalcMoveInputBarRect(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)837 bool MoveDragController::CalcMoveInputBarRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
838                                               const WSRect& originalRect)
839 {
840     if (!CheckAndInitializeMoveDragProperty(pointerEvent, originalRect)) {
841         return false;
842     }
843 
844     MMI::PointerEvent::PointerItem pointerItem;
845     int32_t pointerId = pointerEvent->GetPointerId();
846     pointerEvent->GetPointerItem(pointerId, pointerItem);
847     DisplayId targetDisplayId = static_cast<DisplayId>(pointerEvent->GetTargetDisplayId());
848     int32_t moveDragFinalX = 0;
849     int32_t moveDragFinalY = 0;
850     int32_t pointerDisplayX = pointerItem.GetDisplayX();
851     int32_t pointerDisplayY = pointerItem.GetDisplayY();
852 
853     if (targetDisplayId == moveInputBarStartDisplayId_) {
854         CalcMoveForSameDisplay(pointerEvent, moveDragFinalX, moveDragFinalY);
855     } else {
856         MoveDirection moveDirection =
857             CalcMoveDirection(moveInputBarStartDisplayId_, pointerEvent->GetTargetDisplayId());
858         if (screenSizeProperty_.IsEmpty()) {
859             SetCurrentScreenProperty(targetDisplayId);
860         }
861 
862         switch (moveDirection) {
863             case MoveDirection::LEFT_TO_RIGHT:
864                 HandleLeftToRightCross(
865                     targetDisplayId, pointerDisplayX, pointerDisplayY, moveDragFinalX, moveDragFinalY);
866                 break;
867             case MoveDirection::RIGHT_TO_LEFT:
868                 HandleRightToLeftCross(
869                     targetDisplayId, pointerDisplayX, pointerDisplayY, moveDragFinalX, moveDragFinalY);
870                 break;
871             case MoveDirection::UP_TO_BOTTOM:
872                 HandleUpToBottomCross(
873                     targetDisplayId, pointerDisplayX, pointerDisplayY, moveDragFinalX, moveDragFinalY);
874                 break;
875             case MoveDirection::BOTTOM_TO_UP:
876                 HandleBottomToUpCross(
877                     targetDisplayId, pointerDisplayX, pointerDisplayY, moveDragFinalX, moveDragFinalY);
878                 break;
879             default:
880                 moveDragFinalX = moveDragProperty_.targetRect_.posX_;
881                 moveDragFinalY = moveDragProperty_.targetRect_.posY_;
882                 break;
883         }
884     }
885     moveDragProperty_.targetRect_ = { moveDragFinalX, moveDragFinalY, originalRect.width_, originalRect.height_ };
886     TLOGD(WmsLogTag::WMS_KEYBOARD, "move rect: %{public}s", moveDragProperty_.targetRect_.ToString().c_str());
887     return true;
888 }
889 
CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)890 bool MoveDragController::CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
891     const WSRect& originalRect)
892 {
893     MMI::PointerEvent::PointerItem pointerItem;
894     int32_t pointerId = pointerEvent->GetPointerId();
895     pointerEvent->GetPointerItem(pointerId, pointerItem);
896     if (moveDragProperty_.isEmpty()) {
897         InitializeMoveDragPropertyNotValid(pointerEvent, originalRect);
898         return false;
899     };
900     if (!WindowHelper::IsSystemWindow(winType_) ||
901         static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()) == moveDragStartDisplayId_) {
902         std::pair<int32_t, int32_t> trans = CalcUnifiedTranslate(pointerEvent);
903         moveDragProperty_.targetRect_ = {
904             moveDragProperty_.originalRect_.posX_ + trans.first,
905             moveDragProperty_.originalRect_.posY_ + trans.second,
906             originalRect.width_,
907             originalRect.height_
908         };
909     }
910     TLOGD(WmsLogTag::WMS_LAYOUT, "move rect: %{public}s", moveDragProperty_.targetRect_.ToString().c_str());
911     return true;
912 }
913 
914 /** @note @window.drag */
EventDownInit(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)915 bool MoveDragController::EventDownInit(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
916     const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
917 {
918     const auto& sourceType = pointerEvent->GetSourceType();
919     if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
920         pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT) {
921         TLOGD(WmsLogTag::WMS_LAYOUT, "Mouse click event but not left click");
922         return false;
923     }
924     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "MoveDragController::EventDownInit");
925     int32_t pointerId = pointerEvent->GetPointerId();
926     MMI::PointerEvent::PointerItem pointerItem;
927     pointerEvent->GetPointerItem(pointerId, pointerItem);
928     InitMoveDragProperty();
929     hasPointDown_ = true;
930     moveDragProperty_.originalRect_ = originalRect;
931     auto display = DisplayManager::GetInstance().GetDisplayById(
932         static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()));
933     if (display) {
934         vpr_ = display->GetVirtualPixelRatio();
935     } else {
936         vpr_ = 1.5f;  // 1.5f: default virtual pixel ratio
937     }
938     int outside = (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) ? HOTZONE_POINTER * vpr_ : HOTZONE_TOUCH * vpr_;
939     type_ = SessionHelper::GetAreaType(pointerItem.GetWindowX(), pointerItem.GetWindowY(), sourceType, outside, vpr_,
940         moveDragProperty_.originalRect_);
941     if (type_ == AreaType::UNDEFINED) {
942         return false;
943     }
944     InitDecorValue(property, sysConfig);
945     limits_ = property->GetWindowLimits();
946     moveDragProperty_.pointerId_ = pointerEvent->GetPointerId();
947     moveDragProperty_.pointerType_ = sourceType;
948     moveDragProperty_.originalPointerPosX_ = pointerItem.GetDisplayX();
949     moveDragProperty_.originalPointerPosY_ = pointerItem.GetDisplayY();
950     if (aspectRatio_ <= NEAR_ZERO) {
951         CalcFreeformTranslateLimits(type_);
952     }
953     moveDragProperty_.originalRect_.posX_ = pointerItem.GetDisplayX() - pointerItem.GetWindowX();
954     moveDragProperty_.originalRect_.posY_ = pointerItem.GetDisplayY() - pointerItem.GetWindowY();
955     mainMoveAxis_ = AxisType::UNDEFINED;
956     isStartDrag_ = true;
957     NotifyWindowInputPidChange(isStartDrag_);
958     return true;
959 }
960 
961 /** @note @window.drag */
CalcFreeformTargetRect(AreaType type,int32_t tranX,int32_t tranY,WSRect originalRect)962 WSRect MoveDragController::CalcFreeformTargetRect(AreaType type, int32_t tranX, int32_t tranY, WSRect originalRect)
963 {
964     WSRect targetRect = originalRect;
965     FixTranslateByLimits(tranX, tranY);
966     TLOGD(WmsLogTag::WMS_LAYOUT, "areaType:%{public}u", type);
967     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
968         targetRect.posX_ += tranX;
969         targetRect.width_ -= tranX;
970     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
971         targetRect.width_ += tranX;
972     }
973     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
974         targetRect.posY_ += tranY;
975         targetRect.height_ -= tranY;
976     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
977         targetRect.height_ += tranY;
978     }
979     // check current ratio limits
980     if (targetRect.height_ == 0) {
981         return targetRect;
982     }
983     float curRatio = static_cast<float>(targetRect.width_) / static_cast<float>(targetRect.height_);
984     if (!MathHelper::GreatNotEqual(limits_.minRatio_, curRatio) &&
985         !MathHelper::GreatNotEqual(curRatio, limits_.maxRatio_)) {
986         return targetRect;
987     }
988     float newRatio = MathHelper::LessNotEqual(curRatio, limits_.minRatio_) ? limits_.minRatio_ : limits_.maxRatio_;
989     if (MathHelper::NearZero(newRatio)) {
990         return targetRect;
991     }
992     if ((static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) ||
993         (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT))) {
994         targetRect.height_ = static_cast<int32_t>(static_cast<float>(targetRect.width_) / newRatio);
995     } else {
996         targetRect.width_ = static_cast<int32_t>(static_cast<float>(targetRect.height_) * newRatio);
997     }
998     TLOGD(WmsLogTag::WMS_LAYOUT, "curRatio:%{public}f, newRatio:%{public}f", curRatio, newRatio);
999     return targetRect;
1000 }
1001 
CalcFixedAspectRatioTargetRect(AreaType type,int32_t tranX,int32_t tranY,float aspectRatio,WSRect originalRect)1002 WSRect MoveDragController::CalcFixedAspectRatioTargetRect(AreaType type, int32_t tranX, int32_t tranY,
1003     float aspectRatio, WSRect originalRect)
1004 {
1005     TLOGD(WmsLogTag::WMS_LAYOUT, "in");
1006     int32_t posX = originalRect.posX_;
1007     int32_t posY = originalRect.posY_;
1008     int32_t width = static_cast<int32_t>(originalRect.width_);
1009     int32_t height = static_cast<int32_t>(originalRect.height_);
1010     if (mainMoveAxis_ == AxisType::UNDEFINED) {
1011         if (!InitMainAxis(type, tranX, tranY)) {
1012             return originalRect;
1013         }
1014     }
1015 
1016     TLOGD(WmsLogTag::WMS_LAYOUT, "ratio:%{public}f, areaType:%{public}u", aspectRatio, type);
1017     ConvertXYByAspectRatio(tranX, tranY, aspectRatio);
1018     FixTranslateByLimits(tranX, tranY);
1019     switch (type) {
1020         // tranX and tranY is signed
1021         case AreaType::LEFT_TOP: {
1022             return {posX + tranX, posY + tranY, width - tranX, height - tranY};
1023         }
1024         case AreaType::RIGHT_TOP: {
1025             return {posX, posY + tranY, width + tranX, height - tranY};
1026         }
1027         case AreaType::RIGHT_BOTTOM: {
1028             return {posX, posY, width + tranX, height + tranY};
1029         }
1030         case AreaType::LEFT_BOTTOM: {
1031             return {posX + tranX, posY, width - tranX, height + tranY};
1032         }
1033         case AreaType::LEFT: {
1034             return {posX + tranX, posY, width - tranX, height + tranY};
1035         }
1036         case AreaType::TOP: {
1037             return {posX, posY + tranY, width + tranX, height - tranY};
1038         }
1039         case AreaType::RIGHT: {
1040             return {posX, posY, width + tranX, height + tranY};
1041         }
1042         case AreaType::BOTTOM: {
1043             return {posX, posY, width + tranX, height + tranY};
1044         }
1045         default:
1046             break;
1047     }
1048     return originalRect;
1049 }
1050 
CalcFreeformTranslateLimits(AreaType type)1051 void MoveDragController::CalcFreeformTranslateLimits(AreaType type)
1052 {
1053     TLOGD(WmsLogTag::WMS_LAYOUT, "areaType:%{public}u, minWidth:%{public}u, maxWidth:%{public}u, "
1054         "minHeight:%{public}u, maxHeight:%{public}u", type,
1055         limits_.minWidth_, limits_.maxWidth_, limits_.minHeight_, limits_.maxHeight_);
1056     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
1057         minTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.maxWidth_);
1058         maxTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.minWidth_);
1059     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
1060         minTranX_ = static_cast<int32_t>(limits_.minWidth_) - moveDragProperty_.originalRect_.width_;
1061         maxTranX_ = static_cast<int32_t>(limits_.maxWidth_) - moveDragProperty_.originalRect_.width_;
1062     }
1063     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
1064         minTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.maxHeight_);
1065         maxTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.minHeight_);
1066     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
1067         minTranY_ = static_cast<int32_t>(limits_.minHeight_) - moveDragProperty_.originalRect_.height_;
1068         maxTranY_ = static_cast<int32_t>(limits_.maxHeight_) - moveDragProperty_.originalRect_.height_;
1069     }
1070 }
1071 
CalcFixedAspectRatioTranslateLimits(AreaType type)1072 void MoveDragController::CalcFixedAspectRatioTranslateLimits(AreaType type)
1073 {
1074     int32_t minW = static_cast<int32_t>(limits_.minWidth_);
1075     int32_t maxW = static_cast<int32_t>(limits_.maxWidth_);
1076     int32_t minH = static_cast<int32_t>(limits_.minHeight_);
1077     int32_t maxH = static_cast<int32_t>(limits_.maxHeight_);
1078     if (isDecorEnable_) {
1079         if (SessionUtils::ToLayoutWidth(minW, vpr_) < SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_) {
1080             minW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_, vpr_);
1081             minH = SessionUtils::ToLayoutHeight(minH, vpr_);
1082         } else {
1083             minH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(minW, vpr_) / aspectRatio_, vpr_);
1084             minW = SessionUtils::ToLayoutWidth(minW, vpr_);
1085         }
1086         if (SessionUtils::ToLayoutWidth(maxW, vpr_) < SessionUtils::ToLayoutHeight(maxH, vpr_) * aspectRatio_) {
1087             maxH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(maxW, vpr_) / aspectRatio_, vpr_);
1088             maxW = SessionUtils::ToLayoutWidth(maxW, vpr_);
1089         } else {
1090             maxW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(maxH, vpr_) * aspectRatio_, vpr_);
1091             maxH = SessionUtils::ToLayoutHeight(maxH, vpr_);
1092         }
1093     } else {
1094         // width = height * aspectRatio
1095         if (minW < minH * aspectRatio_) {
1096             minW = minH * aspectRatio_;
1097         } else {
1098             minH = minW / aspectRatio_;
1099         }
1100         if (maxW < maxH * aspectRatio_) {
1101             maxH = maxW / aspectRatio_;
1102         } else {
1103             maxW = maxH * aspectRatio_;
1104         }
1105     }
1106 
1107     const static std::map<AreaType, std::function<void(int32_t, int32_t, int32_t, int32_t)>> calcMinMaxTranMap = {
1108         { AreaType::LEFT, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1109             minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
1110             maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
1111             minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1112             maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1113         }},
1114         { AreaType::LEFT_TOP, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1115             minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
1116             maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
1117             minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
1118             maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
1119         }},
1120         { AreaType::LEFT_BOTTOM, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1121             minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
1122             maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
1123             minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1124             maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1125         }},
1126         { AreaType::RIGHT, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1127             minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1128             maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1129             minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1130             maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1131         }},
1132         { AreaType::RIGHT_TOP, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1133             minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1134             maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1135             minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
1136             maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
1137         }},
1138         { AreaType::RIGHT_BOTTOM, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1139             minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1140             maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1141             minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1142             maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1143         }},
1144         { AreaType::TOP, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1145             minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1146             maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1147             minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
1148             maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
1149         }},
1150         { AreaType::BOTTOM, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1151             minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1152             maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1153             minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1154             maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1155         }},
1156     };
1157     if (calcMinMaxTranMap.find(type) == calcMinMaxTranMap.end()) {
1158         TLOGE(WmsLogTag::WMS_LAYOUT, "not find type:%{public}d", type);
1159         return;
1160     }
1161     calcMinMaxTranMap.at(type)(maxW, minW, maxH, minH);
1162 }
1163 
FixTranslateByLimits(int32_t & tranX,int32_t & tranY)1164 void MoveDragController::FixTranslateByLimits(int32_t& tranX, int32_t& tranY)
1165 {
1166     if (tranX < minTranX_) {
1167         tranX = minTranX_;
1168     } else if (tranX > maxTranX_) {
1169         tranX = maxTranX_;
1170     }
1171     if (tranY < minTranY_) {
1172         tranY = minTranY_;
1173     } else if (tranY > maxTranY_) {
1174         tranY = maxTranY_;
1175     }
1176     TLOGD(WmsLogTag::WMS_LAYOUT, "tranX:%{public}d, tranY:%{public}d, minTranX:%{public}d, maxTranX:%{public}d, "
1177         "minTranY:%{public}d, maxTranY:%{public}d", tranX, tranY, minTranX_, maxTranX_, minTranY_, maxTranY_);
1178 }
1179 
InitMainAxis(AreaType type,int32_t tranX,int32_t tranY)1180 bool MoveDragController::InitMainAxis(AreaType type, int32_t tranX, int32_t tranY)
1181 {
1182     if (type == AreaType::LEFT || type == AreaType::RIGHT) {
1183         mainMoveAxis_ = AxisType::X_AXIS;
1184     } else if (type == AreaType::TOP || type == AreaType::BOTTOM) {
1185         mainMoveAxis_ = AxisType::Y_AXIS;
1186     } else if (tranX == 0 && tranY == 0) {
1187         return false;
1188     } else {
1189         mainMoveAxis_ = (std::abs(tranX) > std::abs(tranY)) ? AxisType::X_AXIS : AxisType::Y_AXIS;
1190     }
1191     CalcFixedAspectRatioTranslateLimits(type);
1192     return true;
1193 }
1194 
ConvertByAreaType(int32_t tran) const1195 int32_t MoveDragController::ConvertByAreaType(int32_t tran) const
1196 {
1197     const static std::map<AreaType, int32_t> areaTypeMap = {
1198         { AreaType::LEFT, NEGATIVE_CORRELATION },
1199         { AreaType::RIGHT, POSITIVE_CORRELATION },
1200         { AreaType::TOP, NEGATIVE_CORRELATION },
1201         { AreaType::BOTTOM, POSITIVE_CORRELATION },
1202         { AreaType::LEFT_TOP, POSITIVE_CORRELATION },
1203         { AreaType::RIGHT_TOP, NEGATIVE_CORRELATION },
1204         { AreaType::LEFT_BOTTOM, NEGATIVE_CORRELATION },
1205         { AreaType::RIGHT_BOTTOM, POSITIVE_CORRELATION },
1206     };
1207     if (areaTypeMap.find(type_) == areaTypeMap.end()) {
1208         TLOGE(WmsLogTag::WMS_LAYOUT, "not find type:%{public}d", type_);
1209         return tran;
1210     }
1211     return areaTypeMap.at(type_) * tran;
1212 }
1213 
ConvertXYByAspectRatio(int32_t & tx,int32_t & ty,float aspectRatio)1214 void MoveDragController::ConvertXYByAspectRatio(int32_t& tx, int32_t& ty, float aspectRatio)
1215 {
1216     if (mainMoveAxis_ == AxisType::X_AXIS) {
1217         ty = tx / aspectRatio;
1218         ty = ConvertByAreaType(ty);
1219     } else if (mainMoveAxis_ == AxisType::Y_AXIS) {
1220         tx = ty * aspectRatio;
1221         tx = ConvertByAreaType(tx);
1222     }
1223 }
1224 
InitDecorValue(const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)1225 void MoveDragController::InitDecorValue(const sptr<WindowSessionProperty> property,
1226     const SystemSessionConfig& sysConfig)
1227 {
1228     auto windowType = property->GetWindowType();
1229     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
1230     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
1231     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
1232     isDecorEnable_ = (isMainWindow || ((isSubWindow || isDialogWindow) && property->IsDecorEnable())) &&
1233         sysConfig.isSystemDecorEnable_ &&
1234         WindowHelper::IsWindowModeSupported(sysConfig.decorWindowModeSupportType_, property->GetWindowMode());
1235 }
1236 
1237 /** @note @window.drag */
ProcessSessionRectChange(SizeChangeReason reason)1238 void MoveDragController::ProcessSessionRectChange(SizeChangeReason reason)
1239 {
1240     if (moveDragCallback_) {
1241         moveDragCallback_(reason);
1242     }
1243 }
1244 
GetVirtualPixelRatio() const1245 float MoveDragController::GetVirtualPixelRatio() const
1246 {
1247     float vpr = 1.5;
1248     auto displayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
1249     if (displayInfo != nullptr) {
1250         vpr = displayInfo->GetVirtualPixelRatio();
1251     }
1252     WLOGFD("vpr: %{public}f", vpr);
1253     return vpr;
1254 }
1255 
UpdateDragType(int32_t startPointPosX,int32_t startPointPosY)1256 void MoveDragController::UpdateDragType(int32_t startPointPosX, int32_t startPointPosY)
1257 {
1258     if (startPointPosX > rectExceptCorner_.posX_ &&
1259         (startPointPosX < rectExceptCorner_.posX_ + static_cast<int32_t>(rectExceptCorner_.width_))) {
1260         dragType_ = DragType::DRAG_BOTTOM_OR_TOP;
1261     } else if (startPointPosY > rectExceptCorner_.posY_ &&
1262         (startPointPosY < rectExceptCorner_.posY_ + static_cast<int32_t>(rectExceptCorner_.height_))) {
1263         dragType_ = DragType::DRAG_LEFT_OR_RIGHT;
1264     } else if ((startPointPosX <= rectExceptCorner_.posX_ && startPointPosY <= rectExceptCorner_.posY_) ||
1265         (startPointPosX >= rectExceptCorner_.posX_ + static_cast<int32_t>(rectExceptCorner_.width_) &&
1266         startPointPosY >= rectExceptCorner_.posY_ + static_cast<int32_t>(rectExceptCorner_.height_))) {
1267         dragType_ = DragType::DRAG_LEFT_TOP_CORNER;
1268     } else {
1269         dragType_ = DragType::DRAG_RIGHT_TOP_CORNER;
1270     }
1271 }
1272 
IsPointInDragHotZone(int32_t startPointPosX,int32_t startPointPosY,int32_t sourceType,const WSRect & winRect)1273 bool MoveDragController::IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY, int32_t sourceType,
1274     const WSRect& winRect)
1275 {
1276     // calculate rect with hotzone
1277     Rect rectWithHotzone;
1278     rectWithHotzone.posX_ = winRect.posX_ - static_cast<int32_t>(HOTZONE_POINTER);
1279     rectWithHotzone.posY_ = winRect.posY_ - static_cast<int32_t>(HOTZONE_POINTER);
1280     rectWithHotzone.width_ = winRect.width_ + HOTZONE_POINTER * 2u;    // double hotZone
1281     rectWithHotzone.height_ = winRect.height_ + HOTZONE_POINTER * 2u;  // double hotZone
1282 
1283     if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
1284         !WindowHelper::IsPointInTargetRectWithBound(startPointPosX, startPointPosY, rectWithHotzone)) {
1285         return false;
1286     } else if ((!WindowHelper::IsPointInTargetRect(startPointPosX, startPointPosY, rectExceptFrame_)) ||
1287         (!WindowHelper::IsPointInWindowExceptCorner(startPointPosX, startPointPosY, rectExceptCorner_))) {
1288         return true;
1289     }
1290     return false;
1291 }
1292 
CalculateStartRectExceptHotZone(float vpr,const WSRect & winRect)1293 void MoveDragController::CalculateStartRectExceptHotZone(float vpr, const WSRect& winRect)
1294 {
1295     rectExceptFrame_.posX_ = winRect.posX_ + static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
1296     rectExceptFrame_.posY_ = winRect.posY_ + static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
1297     rectExceptFrame_.width_ = winRect.width_ - static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
1298     rectExceptFrame_.height_ = winRect.height_ - static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
1299 
1300     rectExceptCorner_.posX_ = winRect.posX_ + static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
1301     rectExceptCorner_.posY_ = winRect.posY_ + static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
1302     rectExceptCorner_.width_ =
1303         winRect.width_ - static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
1304     rectExceptCorner_.height_ =
1305         winRect.height_ - static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
1306 }
1307 
UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1308 WSError MoveDragController::UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1309 {
1310     int32_t pointerId = pointerEvent->GetPointerId();
1311     int32_t startPointerId = moveTempProperty_.pointerId_;
1312     int32_t pointerType = pointerEvent->GetSourceType();
1313     int32_t startPointerType = moveDragProperty_.pointerType_;
1314     MMI::PointerEvent::PointerItem pointerItem;
1315     int32_t sourceType = pointerEvent->GetSourceType();
1316     if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
1317         (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
1318         pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT)) {
1319         WLOGFW("invalid pointerEvent");
1320         return WSError::WS_ERROR_NULLPTR;
1321     }
1322 
1323     int32_t pointerDisplayX = pointerItem.GetDisplayX();
1324     int32_t pointerDisplayY = pointerItem.GetDisplayY();
1325     int32_t pointerDisplayWindowX = pointerItem.GetWindowX();
1326     int32_t pointerDisplayWindowY = pointerItem.GetWindowY();
1327     switch (pointerEvent->GetPointerAction()) {
1328         case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
1329         case MMI::PointerEvent::POINTER_ACTION_DOWN:
1330             moveTempProperty_.pointerId_ = pointerId;
1331             moveTempProperty_.pointerType_ = pointerType;
1332             moveTempProperty_.lastDownPointerPosX_ = pointerDisplayX;
1333             moveTempProperty_.lastDownPointerPosY_ = pointerDisplayY;
1334             moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
1335             moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
1336             moveTempProperty_.lastDownPointerWindowX_ = pointerItem.GetWindowX();
1337             moveTempProperty_.lastDownPointerWindowY_ = pointerItem.GetWindowY();
1338             break;
1339         case MMI::PointerEvent::POINTER_ACTION_MOVE:
1340             if ((startPointerId != -1 && startPointerId != pointerId) ||
1341                 (startPointerType != -1 && pointerType != startPointerType)) {
1342                 WLOGFI("block unnecessary pointer event inside the window");
1343                 return WSError::WS_DO_NOTHING;
1344             }
1345             moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
1346             moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
1347             lastMovePointerPosX_ = pointerDisplayX;
1348             break;
1349         case MMI::PointerEvent::POINTER_ACTION_UP:
1350         case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
1351         case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
1352             moveTempProperty_ = {-1, -1, -1, -1, -1, -1, -1, -1};
1353             break;
1354         }
1355         default:
1356             break;
1357     }
1358     return WSError::WS_OK;
1359 }
1360 
HandleStartMovingWithCoordinate(int32_t offsetX,int32_t offsetY,int32_t pointerPosX,int32_t pointerPosY,const WSRect & winRect)1361 void MoveDragController::HandleStartMovingWithCoordinate(int32_t offsetX, int32_t offsetY,
1362     int32_t pointerPosX, int32_t pointerPosY, const WSRect& winRect)
1363 {
1364     moveTempProperty_.lastDownPointerPosX_ = pointerPosX;
1365     moveTempProperty_.lastDownPointerPosY_ = pointerPosY;
1366     moveTempProperty_.lastMovePointerPosX_ = pointerPosX;
1367     moveTempProperty_.lastMovePointerPosY_ = pointerPosY;
1368     moveTempProperty_.lastDownPointerWindowX_ = offsetX;
1369     moveTempProperty_.lastDownPointerWindowY_ = offsetY;
1370 
1371     moveDragProperty_.targetRect_ = winRect;
1372     ProcessSessionRectChange(SizeChangeReason::DRAG_END);
1373 }
1374 
1375 /** @note @window.drag */
CalcFirstMoveTargetRect(const WSRect & windowRect,bool isFullToFloating)1376 void MoveDragController::CalcFirstMoveTargetRect(const WSRect& windowRect, bool isFullToFloating)
1377 {
1378     if (!GetStartMoveFlag() || moveTempProperty_.isEmpty()) {
1379         return;
1380     }
1381 
1382     WSRect originalRect = {
1383         moveTempProperty_.lastDownPointerPosX_ - moveTempProperty_.lastDownPointerWindowX_,
1384         moveTempProperty_.lastDownPointerPosY_ - moveTempProperty_.lastDownPointerWindowY_,
1385         windowRect.width_,
1386         windowRect.height_
1387     };
1388     if (isFullToFloating) {
1389         originalRect.posX_ = windowRect.posX_;
1390         originalRect.posY_ = windowRect.posY_;
1391     }
1392     SetOriginalMoveDragPos(moveTempProperty_.pointerId_,
1393                            moveTempProperty_.pointerType_,
1394                            moveTempProperty_.lastDownPointerPosX_,
1395                            moveTempProperty_.lastDownPointerPosY_,
1396                            moveTempProperty_.lastDownPointerWindowX_,
1397                            moveTempProperty_.lastDownPointerWindowY_,
1398                            originalRect);
1399 
1400     int32_t offsetX = moveTempProperty_.lastMovePointerPosX_ - moveTempProperty_.lastDownPointerPosX_;
1401     int32_t offsetY = moveTempProperty_.lastMovePointerPosY_ - moveTempProperty_.lastDownPointerPosY_;
1402     WSRect targetRect = {
1403         originalRect.posX_ + offsetX,
1404         originalRect.posY_ + offsetY,
1405         originalRect.width_,
1406         originalRect.height_
1407     };
1408     TLOGI(WmsLogTag::WMS_LAYOUT, "first move rect: [%{public}d, %{public}d, %{public}u, %{public}u]", targetRect.posX_,
1409         targetRect.posY_, targetRect.width_, targetRect.height_);
1410     moveDragProperty_.targetRect_ = targetRect;
1411     ProcessSessionRectChange(SizeChangeReason::DRAG_MOVE);
1412 }
1413 
CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const sptr<WindowSessionProperty> property)1414 bool MoveDragController::CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1415     const sptr<WindowSessionProperty> property)
1416 {
1417     if (pointerEvent == nullptr || property == nullptr) {
1418         WLOGE("ConsumeDragEvent stop because of nullptr");
1419         return false;
1420     }
1421     if (GetStartMoveFlag()) {
1422         WLOGFD("the window is being moved");
1423         return false;
1424     }
1425     if (!GetStartDragFlag() && pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_DOWN &&
1426         pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
1427         return false;
1428     }
1429     int32_t pointerId = pointerEvent->GetPointerId();
1430     int32_t startPointerId = moveDragProperty_.pointerId_;
1431     if (GetStartDragFlag() && startPointerId != -1 && startPointerId != pointerId) {
1432         WLOGFI("block unnecessary pointer event inside the window");
1433         return false;
1434     }
1435     return true;
1436 }
1437 
1438 /** @note @window.drag */
UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1439 void MoveDragController::UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1440 {
1441     int32_t pointerId = pointerEvent->GetPointerId();
1442     MMI::PointerEvent::PointerItem pointerItem;
1443     if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
1444         WLOGFW("invalid pointerEvent");
1445         return;
1446     }
1447     int32_t pointerDisplayX = pointerItem.GetDisplayX();
1448     int32_t pointerDisplayY = pointerItem.GetDisplayY();
1449     DisplayId displayId = static_cast<uint64_t>(pointerEvent->GetTargetDisplayId());
1450     uint32_t windowDragHotAreaType = SceneSession::GetWindowDragHotAreaType(displayId, WINDOW_HOT_AREA_TYPE_UNDEFINED,
1451         pointerDisplayX, pointerDisplayY);
1452     if (windowDragHotAreaType_ != windowDragHotAreaType) {
1453         WLOGFI("the pointerEvent is window drag hot area, old type is: %{public}d, new type is: %{public}d",
1454             windowDragHotAreaType_, windowDragHotAreaType);
1455     }
1456     if (hotAreaDisplayId_ != displayId) {
1457         TLOGI(WmsLogTag::WMS_LAYOUT, "displayId is changed, old: %{public}" PRIu64 ", new: %{public}" PRIu64,
1458             moveDragStartDisplayId_, displayId);
1459         hotAreaDisplayId_ = displayId;
1460     }
1461     windowDragHotAreaType_ = windowDragHotAreaType;
1462 }
1463 
GetOriginalPointerPosX()1464 int32_t MoveDragController::GetOriginalPointerPosX()
1465 {
1466     return moveDragProperty_.originalPointerPosX_;
1467 }
1468 
GetOriginalPointerPosY()1469 int32_t MoveDragController::GetOriginalPointerPosY()
1470 {
1471     return moveDragProperty_.originalPointerPosY_;
1472 }
1473 
GetPointerType() const1474 int32_t MoveDragController::GetPointerType() const
1475 {
1476     return moveDragProperty_.pointerType_;
1477 }
1478 
SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc & func)1479 void MoveDragController::SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc& func)
1480 {
1481     windowDragHotAreaFunc_ = func;
1482 }
1483 
OnLostFocus()1484 void MoveDragController::OnLostFocus()
1485 {
1486     TLOGW(WmsLogTag::WMS_LAYOUT, "window id %{public}d lost focus, should stop MoveDrag isMove: %{public}d,"
1487         "isDrag: %{public}d", persistentId_, isStartMove_, isStartDrag_);
1488     if (isStartMove_ || isStartDrag_) {
1489         MoveDragInterrupted(false);
1490     }
1491 }
1492 
GetNewAddedDisplayIdsDuringMoveDrag()1493 std::set<uint64_t> MoveDragController::GetNewAddedDisplayIdsDuringMoveDrag()
1494 {
1495     std::set<uint64_t> newAddedDisplayIdSet;
1496     WSRect windowRect = GetTargetRect(TargetRectCoordinate::GLOBAL);
1497     std::map<ScreenId, ScreenProperty> screenProperties =
1498         ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
1499     std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
1500     for (const auto& [screenId, screenProperty] : screenProperties) {
1501         if (displayIdSetDuringMoveDrag_.find(screenId) != displayIdSetDuringMoveDrag_.end()) {
1502             continue;
1503         }
1504         WSRect screenRect = {
1505             screenProperty.GetStartX(),
1506             screenProperty.GetStartY(),
1507             screenProperty.GetBounds().rect_.GetWidth(),
1508             screenProperty.GetBounds().rect_.GetHeight(),
1509         };
1510         if (windowRect.IsOverlap(screenRect)) {
1511             displayIdSetDuringMoveDrag_.insert(screenId);
1512             newAddedDisplayIdSet.insert(screenId);
1513         }
1514     }
1515     return newAddedDisplayIdSet;
1516 }
1517 
ResSchedReportData(int32_t type,bool onOffTag)1518 void MoveDragController::ResSchedReportData(int32_t type, bool onOffTag)
1519 {
1520 #ifdef RES_SCHED_ENABLE
1521     std::unordered_map<std::string, std::string> payload;
1522     // 0 is start, 1 is end
1523     if (onOffTag) {
1524         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
1525     } else {
1526         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 1, payload);
1527     }
1528     WLOGFD("ResSchedReportData success type: %{public}d onOffTag: %{public}d", type, onOffTag);
1529 #endif
1530 }
1531 
GetLastMovePointerPosX() const1532 int32_t MoveDragController::GetLastMovePointerPosX() const
1533 {
1534     return lastMovePointerPosX_;
1535 }
1536 
SetLastMovePointerPosX(int32_t lastMovePointerPosX)1537 void MoveDragController::SetLastMovePointerPosX(int32_t lastMovePointerPosX)
1538 {
1539     lastMovePointerPosX_ = lastMovePointerPosX;
1540 }
1541 
IsMoveDragHotAreaCrossDisplay() const1542 bool MoveDragController::IsMoveDragHotAreaCrossDisplay() const
1543 {
1544     return isMoveDragHotAreaCrossDisplay_;
1545 }
1546 
SetMoveDragHotAreaCrossDisplay(bool isMoveDragHotAreaCrossDisplay)1547 void MoveDragController::SetMoveDragHotAreaCrossDisplay(bool isMoveDragHotAreaCrossDisplay)
1548 {
1549     isMoveDragHotAreaCrossDisplay_ = isMoveDragHotAreaCrossDisplay;
1550 }
1551 }  // namespace OHOS::Rosen
1552