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