• 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 "input_manager.h"
21 #include <transaction/rs_transaction.h>
22 #include <ui/rs_surface_node.h>
23 
24 #include "display_manager.h"
25 #include "session/host/include/scene_persistent_storage.h"
26 #include "session/host/include/scene_session.h"
27 #include "session/host/include/session_utils.h"
28 #include "window_helper.h"
29 #include "session_helper.h"
30 #include "window_manager_hilog.h"
31 #include "wm_common_inner.h"
32 
33 #ifdef RES_SCHED_ENABLE
34 #include "res_type.h"
35 #include "res_sched_client.h"
36 #endif
37 
38 namespace OHOS::Rosen {
39 namespace {
40 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "MoveDragController" };
41 }
42 
MoveDragController(int32_t persistentId)43 MoveDragController::MoveDragController(int32_t persistentId)
44 {
45     persistentId_ = persistentId;
46 }
47 
RegisterMoveDragCallback(const MoveDragCallback & callBack)48 void MoveDragController::RegisterMoveDragCallback(const MoveDragCallback& callBack)
49 {
50     moveDragCallback_ = callBack;
51 }
52 
NotifyWindowInputPidChange(bool isServerPid)53 void MoveDragController::NotifyWindowInputPidChange(bool isServerPid)
54 {
55     if (pidChangeCallback_) {
56         pidChangeCallback_(persistentId_, isServerPid);
57         WLOGFI("id: %{public}d, isServerPid:%{public}d", persistentId_, isServerPid);
58     }
59 }
60 
HasPointDown()61 bool MoveDragController::HasPointDown()
62 {
63     return hasPointDown_;
64 }
65 
SetStartMoveFlag(bool flag)66 void MoveDragController::SetStartMoveFlag(bool flag)
67 {
68     if (flag && (!hasPointDown_ || isStartDrag_)) {
69         WLOGFD("StartMove, but has not pointed down or is dragging, hasPointDown_: %{public}d, isStartFlag: %{public}d",
70             hasPointDown_, isStartDrag_);
71         return;
72     }
73     NotifyWindowInputPidChange(flag);
74     isStartMove_ = flag;
75     ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_MOVE_WINDOW, flag);
76     WLOGFI("SetStartMoveFlag, isStartMove_: %{public}d id:%{public}d", isStartMove_, persistentId_);
77 }
78 
SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback & callback)79 void MoveDragController::SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback& callback)
80 {
81     pidChangeCallback_ = callback;
82 }
83 
GetStartMoveFlag() const84 bool MoveDragController::GetStartMoveFlag() const
85 {
86     WLOGFD("GetStartMoveFlag, isStartMove_: %{public}d id:%{public}d", isStartMove_, persistentId_);
87     return isStartMove_;
88 }
89 
GetStartDragFlag() const90 bool MoveDragController::GetStartDragFlag() const
91 {
92     return isStartDrag_;
93 }
94 
GetTargetRect() const95 WSRect MoveDragController::GetTargetRect() const
96 {
97     return moveDragProperty_.targetRect_;
98 }
99 
InitMoveDragProperty()100 void MoveDragController::InitMoveDragProperty()
101 {
102     moveDragProperty_ = { -1, -1, -1, -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
103 }
104 
SetOriginalValue(int32_t pointerId,int32_t pointerType,int32_t pointerPosX,int32_t pointerPosY,const WSRect & winRect)105 void MoveDragController::SetOriginalValue(int32_t pointerId, int32_t pointerType,
106     int32_t pointerPosX, int32_t pointerPosY, const WSRect& winRect)
107 {
108     moveDragProperty_.pointerId_ = pointerId;
109     moveDragProperty_.pointerType_ = pointerType;
110     moveDragProperty_.originalPointerPosX_ = pointerPosX;
111     moveDragProperty_.originalPointerPosY_ = pointerPosY;
112     moveDragProperty_.originalRect_ = winRect;
113 }
114 
GetFullScreenToFloatingRect(const WSRect & originalRect,const WSRect & windowRect)115 WSRect MoveDragController::GetFullScreenToFloatingRect(const WSRect& originalRect, const WSRect& windowRect)
116 {
117     if (moveTempProperty_.isEmpty()) {
118         TLOGI(WmsLogTag::WMS_LAYOUT, "move temporary property is empty");
119         return originalRect;
120     }
121     if (originalRect.width_ == 0) {
122         TLOGI(WmsLogTag::WMS_LAYOUT, "original rect witch is zero");
123         return windowRect;
124     }
125     // Drag and drop to full screen in proportion
126     float newPosX = static_cast<float>(windowRect.width_) / static_cast<float>(originalRect.width_) *
127         static_cast<float>(moveTempProperty_.lastDownPointerPosX_ - originalRect.posX_);
128     WSRect targetRect = {
129         moveTempProperty_.lastDownPointerPosX_ - static_cast<int32_t>(newPosX),
130         originalRect.posY_,
131         windowRect.width_,
132         windowRect.height_,
133     };
134     TLOGI(WmsLogTag::WMS_LAYOUT, "target rect [%{public}d,%{public}d,%{public}u,%{public}u]", targetRect.posX_,
135         targetRect.posY_, targetRect.width_, targetRect.height_);
136     return targetRect;
137 }
138 
SetAspectRatio(float ratio)139 void MoveDragController::SetAspectRatio(float ratio)
140 {
141     aspectRatio_ = ratio;
142 }
143 
ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)144 bool MoveDragController::ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
145     const WSRect& originalRect)
146 {
147     if (pointerEvent == nullptr) {
148         WLOGE("ConsumeMoveEvent stop because of nullptr");
149         return false;
150     }
151     if (GetStartDragFlag()) {
152         WLOGFI("the window is being resized");
153         return false;
154     }
155     int32_t pointerId = pointerEvent->GetPointerId();
156     int32_t startPointerId = moveDragProperty_.pointerId_;
157     int32_t startPointerType = moveDragProperty_.pointerType_;
158     if ((startPointerId != -1 && startPointerId != pointerId) ||
159         (startPointerType != -1 && pointerEvent->GetSourceType() != startPointerType)) {
160         WLOGFI("block unnecessary pointer event inside the window");
161         return false;
162     }
163     MMI::PointerEvent::PointerItem pointerItem;
164     int32_t sourceType = pointerEvent->GetSourceType();
165     if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
166         (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
167         (pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT &&
168         !GetStartMoveFlag()))) {
169         WLOGFD("invalid pointerEvent id: %{public}d", persistentId_);
170         return false;
171     }
172 
173     UpdateMoveTempProperty(pointerEvent);
174 
175     int32_t action = pointerEvent->GetPointerAction();
176     if (!GetStartMoveFlag()) {
177         if (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
178             action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
179             WLOGFD("Move event hasPointDown");
180             hasPointDown_ = true;
181         } else if (action == MMI::PointerEvent::POINTER_ACTION_UP ||
182             action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
183             action == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
184             WLOGFD("Reset hasPointDown_ when point up or cancel");
185             hasPointDown_ = false;
186         }
187         WLOGFD("No need to move action id: %{public}d", action);
188         return false;
189     }
190 
191     SizeChangeReason reason = SizeChangeReason::MOVE;
192     bool ret = true;
193     switch (action) {
194         case MMI::PointerEvent::POINTER_ACTION_MOVE: {
195             reason = SizeChangeReason::MOVE;
196             uint32_t oldWindowDragHotAreaType = windowDragHotAreaType_;
197             UpdateHotAreaType(pointerEvent);
198             ProcessWindowDragHotAreaFunc(oldWindowDragHotAreaType != windowDragHotAreaType_, reason);
199             break;
200         }
201         case MMI::PointerEvent::POINTER_ACTION_UP:
202         case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
203         case MMI::PointerEvent::POINTER_ACTION_CANCEL:
204         case MMI::PointerEvent::POINTER_ACTION_DOWN:
205         case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN: {
206             reason = SizeChangeReason::DRAG_END;
207             SetStartMoveFlag(false);
208             hasPointDown_ = false;
209             ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
210             // The Pointer up event sent to the ArkUI.
211             ret = false;
212             break;
213         }
214         default:
215             break;
216     }
217     if (CalcMoveTargetRect(pointerEvent, originalRect)) {
218         ProcessSessionRectChange(reason);
219     }
220     return ret;
221 }
222 
ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage,const SizeChangeReason & reason)223 void MoveDragController::ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage, const SizeChangeReason& reason)
224 {
225     if (isSendHotAreaMessage) {
226         WLOGFI("ProcessWindowDragHotAreaFunc start, isSendHotAreaMessage: %{public}u, reason: %{public}d",
227             isSendHotAreaMessage, reason);
228     }
229     if (windowDragHotAreaFunc_ && isSendHotAreaMessage) {
230         windowDragHotAreaFunc_(windowDragHotAreaType_, reason);
231     }
232 }
233 
UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const std::shared_ptr<RSSurfaceNode> & surfaceNode)234 void MoveDragController::UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
235     const std::shared_ptr<RSSurfaceNode>& surfaceNode)
236 {
237     if (surfaceNode == nullptr || pointerEvent == nullptr || type_ == AreaType::UNDEFINED) {
238         return;
239     }
240     if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN ||
241         pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
242         Gravity dragGravity = GRAVITY_MAP.at(type_);
243         if (dragGravity >= Gravity::TOP && dragGravity <= Gravity::BOTTOM_RIGHT) {
244             WLOGFI("begin SetFrameGravity:%{public}d, type:%{public}d", dragGravity, type_);
245             surfaceNode->SetFrameGravity(dragGravity);
246             RSTransaction::FlushImplicitTransaction();
247         }
248         return;
249     }
250     if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
251         pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP ||
252         pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
253         surfaceNode->SetFrameGravity(Gravity::TOP_LEFT);
254         RSTransaction::FlushImplicitTransaction();
255         WLOGFI("recover gravity to TOP_LEFT");
256     }
257 }
258 
ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)259 bool MoveDragController::ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
260     const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
261 {
262     if (!CheckDragEventLegal(pointerEvent, property)) {
263         return false;
264     }
265 
266     int32_t pointerId = pointerEvent->GetPointerId();
267     MMI::PointerEvent::PointerItem pointerItem;
268     if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
269         WLOGE("Get PointerItem failed");
270         return false;
271     }
272 
273     SizeChangeReason reason = SizeChangeReason::UNDEFINED;
274     switch (pointerEvent->GetPointerAction()) {
275         case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
276         case MMI::PointerEvent::POINTER_ACTION_DOWN: {
277             if (!EventDownInit(pointerEvent, originalRect, property, sysConfig)) {
278                 return false;
279             }
280             reason = SizeChangeReason::DRAG_START;
281             ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, true);
282             break;
283         }
284         case MMI::PointerEvent::POINTER_ACTION_MOVE: {
285             reason = SizeChangeReason::DRAG;
286             break;
287         }
288         case MMI::PointerEvent::POINTER_ACTION_UP:
289         case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
290         case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
291             reason = SizeChangeReason::DRAG_END;
292             isStartDrag_ = false;
293             hasPointDown_ = false;
294             ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, false);
295             NotifyWindowInputPidChange(isStartDrag_);
296             break;
297         }
298         default:
299             return false;
300     }
301     int32_t tranX = pointerItem.GetDisplayX() - moveDragProperty_.originalPointerPosX_;
302     int32_t tranY = pointerItem.GetDisplayY() - moveDragProperty_.originalPointerPosY_;
303 
304     if (aspectRatio_ > NEAR_ZERO) {
305         moveDragProperty_.targetRect_ = CalcFixedAspectRatioTargetRect(type_, tranX, tranY, aspectRatio_,
306             moveDragProperty_.originalRect_);
307     } else {
308         moveDragProperty_.targetRect_ = CalcFreeformTargetRect(type_, tranX, tranY, moveDragProperty_.originalRect_);
309     }
310     ProcessSessionRectChange(reason);
311     return true;
312 }
313 
CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)314 bool MoveDragController::CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
315     const WSRect& originalRect)
316 {
317     MMI::PointerEvent::PointerItem pointerItem;
318     int32_t pointerId = pointerEvent->GetPointerId();
319     pointerEvent->GetPointerItem(pointerId, pointerItem);
320     int32_t pointerDisplayX = pointerItem.GetDisplayX();
321     int32_t pointerDisplayY = pointerItem.GetDisplayY();
322     if (moveDragProperty_.isEmpty()) {
323         moveDragProperty_.pointerId_ = pointerId;
324         moveDragProperty_.pointerType_ = pointerEvent->GetSourceType();
325         moveDragProperty_.originalPointerPosX_ = pointerDisplayX;
326         moveDragProperty_.originalPointerPosY_ = pointerDisplayY;
327         int32_t pointerWindowX = pointerItem.GetWindowX();
328         int32_t pointerWindowY = pointerItem.GetWindowY();
329         moveDragProperty_.originalRect_ = originalRect;
330         moveDragProperty_.originalRect_.posX_ = pointerDisplayX - pointerWindowX;
331         moveDragProperty_.originalRect_.posY_ = pointerDisplayY - pointerWindowY;
332         return false;
333     } else {
334         int32_t offsetX = pointerDisplayX - moveDragProperty_.originalPointerPosX_;
335         int32_t offsetY = pointerDisplayY - moveDragProperty_.originalPointerPosY_;
336         moveDragProperty_.targetRect_ = {
337             moveDragProperty_.originalRect_.posX_ + offsetX,
338             moveDragProperty_.originalRect_.posY_ + offsetY,
339             originalRect.width_,
340             originalRect.height_};
341         WLOGFD("move rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
342             moveDragProperty_.targetRect_.posX_, moveDragProperty_.targetRect_.posY_,
343             moveDragProperty_.targetRect_.width_, moveDragProperty_.targetRect_.height_);
344         return true;
345     }
346 }
347 
EventDownInit(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)348 bool MoveDragController::EventDownInit(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
349     const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
350 {
351     const auto& sourceType = pointerEvent->GetSourceType();
352     if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
353         pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT) {
354         return false;
355     }
356     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "MoveDragController::EventDownInit");
357     int32_t pointerId = pointerEvent->GetPointerId();
358     MMI::PointerEvent::PointerItem pointerItem;
359     pointerEvent->GetPointerItem(pointerId, pointerItem);
360     InitMoveDragProperty();
361     hasPointDown_ = true;
362     moveDragProperty_.originalRect_ = originalRect;
363     auto display = DisplayManager::GetInstance().GetDisplayById(pointerEvent->GetTargetDisplayId());
364     if (display) {
365         vpr_ = display->GetVirtualPixelRatio();
366     } else {
367         vpr_ = 1.5f; // 1.5f: default virtual pixel ratio
368     }
369     int outside = (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) ? HOTZONE_POINTER * vpr_ :
370         HOTZONE_TOUCH * vpr_;
371     type_ = SessionHelper::GetAreaType(pointerItem.GetWindowX(), pointerItem.GetWindowY(), sourceType, outside, vpr_,
372         moveDragProperty_.originalRect_);
373     if (type_ == AreaType::UNDEFINED) {
374         return false;
375     }
376     InitDecorValue(property, sysConfig);
377     limits_ = property->GetWindowLimits();
378     moveDragProperty_.pointerId_ = pointerEvent->GetPointerId();
379     moveDragProperty_.pointerType_ = sourceType;
380     moveDragProperty_.originalPointerPosX_ = pointerItem.GetDisplayX();
381     moveDragProperty_.originalPointerPosY_ = pointerItem.GetDisplayY();
382     if (aspectRatio_ <= NEAR_ZERO) {
383         CalcFreeformTranslateLimits(type_);
384     }
385     moveDragProperty_.originalRect_.posX_ = pointerItem.GetDisplayX() - pointerItem.GetWindowX();
386     moveDragProperty_.originalRect_.posY_ = pointerItem.GetDisplayY() - pointerItem.GetWindowY();
387     mainMoveAxis_ = AxisType::UNDEFINED;
388     isStartDrag_ = true;
389     NotifyWindowInputPidChange(isStartDrag_);
390     return true;
391 }
392 
CalcFreeformTargetRect(AreaType type,int32_t tranX,int32_t tranY,WSRect originalRect)393 WSRect MoveDragController::CalcFreeformTargetRect(AreaType type, int32_t tranX, int32_t tranY, WSRect originalRect)
394 {
395     WSRect targetRect = originalRect;
396     FixTranslateByLimits(tranX, tranY);
397     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
398         targetRect.posX_ += tranX;
399         targetRect.width_ -= tranX;
400     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
401         targetRect.width_ += tranX;
402     }
403     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
404         targetRect.posY_ += tranY;
405         targetRect.height_ -= tranY;
406     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
407         targetRect.height_ += tranY;
408     }
409     // check current ratio limits
410     if (targetRect.height_ == 0) {
411         return targetRect;
412     }
413     float curRatio = static_cast<float>(targetRect.width_) / static_cast<float>(targetRect.height_);
414     if (!MathHelper::GreatNotEqual(limits_.minRatio_, curRatio) &&
415         !MathHelper::GreatNotEqual(curRatio, limits_.maxRatio_)) {
416         return targetRect;
417     }
418     float newRatio = MathHelper::LessNotEqual(curRatio, limits_.minRatio_) ? limits_.minRatio_ : limits_.maxRatio_;
419     if (MathHelper::NearZero(newRatio)) {
420         return targetRect;
421     }
422     if ((static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) ||
423         (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT))) {
424         targetRect.height_ = static_cast<int32_t>(static_cast<float>(targetRect.width_) / newRatio);
425     } else {
426         targetRect.width_ = static_cast<int32_t>(static_cast<float>(targetRect.height_) * newRatio);
427     }
428     return targetRect;
429 }
430 
CalcFixedAspectRatioTargetRect(AreaType type,int32_t tranX,int32_t tranY,float aspectRatio,WSRect originalRect)431 WSRect MoveDragController::CalcFixedAspectRatioTargetRect(AreaType type, int32_t tranX, int32_t tranY,
432     float aspectRatio, WSRect originalRect)
433 {
434     int32_t posX = originalRect.posX_;
435     int32_t posY = originalRect.posY_;
436     int32_t width = static_cast<int32_t>(originalRect.width_);
437     int32_t height = static_cast<int32_t>(originalRect.height_);
438     FixTranslateByLimits(tranX, tranY);
439     if (mainMoveAxis_ == AxisType::UNDEFINED) {
440         if (!InitMainAxis(type, tranX, tranY)) {
441             return originalRect;
442         }
443     }
444 
445     ConvertXYByAspectRatio(tranX, tranY, aspectRatio);
446     switch (type) {
447         case AreaType::LEFT_TOP: {
448             return { posX + tranX, posY + tranY, width - tranX, height - tranY };
449         }
450         case AreaType::RIGHT_TOP: {
451             return { posX, posY + (mainMoveAxis_ == AxisType::X_AXIS ? (-tranY) : (tranY)),
452                      width + (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)),
453                      height + (mainMoveAxis_ == AxisType::X_AXIS ? (tranY) : (-tranY)) };
454         }
455         case AreaType::RIGHT_BOTTOM: {
456             return { posX, posY, width + tranX, height + tranY };
457         }
458         case AreaType::LEFT_BOTTOM: {
459             return { posX + (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)), posY,
460                      width - (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)),
461                      height - (mainMoveAxis_ == AxisType::X_AXIS ? (tranY) : (-tranY)) };
462         }
463         case AreaType::LEFT: {
464             return { posX + tranX, posY, width - tranX, height - tranY };
465         }
466         case AreaType::TOP: {
467             return { posX, posY + tranY, width - tranX, height - tranY };
468         }
469         case AreaType::RIGHT: {
470             return { posX, posY, width + tranX, height + tranY };
471         }
472         case AreaType::BOTTOM: {
473             return { posX, posY, width + tranX, height + tranY };
474         }
475         default:
476             break;
477     }
478     return originalRect;
479 }
480 
CalcFreeformTranslateLimits(AreaType type)481 void MoveDragController::CalcFreeformTranslateLimits(AreaType type)
482 {
483     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
484         minTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.maxWidth_);
485         maxTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.minWidth_);
486     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
487         minTranX_ = static_cast<int32_t>(limits_.minWidth_) - moveDragProperty_.originalRect_.width_;
488         maxTranX_ = static_cast<int32_t>(limits_.maxWidth_) - moveDragProperty_.originalRect_.width_;
489     }
490     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
491         minTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.maxHeight_);
492         maxTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.minHeight_);
493     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
494         minTranY_ = static_cast<int32_t>(limits_.minHeight_) - moveDragProperty_.originalRect_.height_;
495         maxTranY_ = static_cast<int32_t>(limits_.maxHeight_) - moveDragProperty_.originalRect_.height_;
496     }
497 }
498 
CalcFixedAspectRatioTranslateLimits(AreaType type,AxisType axis)499 void MoveDragController::CalcFixedAspectRatioTranslateLimits(AreaType type, AxisType axis)
500 {
501     int32_t minW = static_cast<int32_t>(limits_.minWidth_);
502     int32_t maxW = static_cast<int32_t>(limits_.maxWidth_);
503     int32_t minH = static_cast<int32_t>(limits_.minHeight_);
504     int32_t maxH = static_cast<int32_t>(limits_.maxHeight_);
505     if (isDecorEnable_) {
506         if (SessionUtils::ToLayoutWidth(minW, vpr_) < SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_) {
507             minW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_, vpr_);
508         } else {
509             minH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(minW, vpr_) / aspectRatio_, vpr_);
510         }
511         if (SessionUtils::ToLayoutWidth(maxW, vpr_) < SessionUtils::ToLayoutHeight(maxH, vpr_) * aspectRatio_) {
512             maxH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(maxW, vpr_) * aspectRatio_, vpr_);
513         } else {
514             maxW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(maxH, vpr_) / aspectRatio_, vpr_);
515         }
516     } else {
517         if (minW < minH * aspectRatio_) {
518             minW = minH * aspectRatio_;
519         } else {
520             minH = minW / aspectRatio_;
521         }
522         if (maxW < maxH * aspectRatio_) {
523             maxH = maxW * aspectRatio_;
524         } else {
525             maxW = maxH / aspectRatio_;
526         }
527     }
528 
529     if (axis == AxisType::X_AXIS) {
530         if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
531             minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
532             maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
533         } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
534             minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
535             maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
536         }
537     } else if (axis == AxisType::Y_AXIS) {
538         if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
539             minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
540             maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
541         } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
542             minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
543             maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
544         }
545     }
546 }
547 
FixTranslateByLimits(int32_t & tranX,int32_t & tranY)548 void MoveDragController::FixTranslateByLimits(int32_t& tranX, int32_t& tranY)
549 {
550     if (tranX < minTranX_) {
551         tranX = minTranX_;
552     } else if (tranX > maxTranX_) {
553         tranX = maxTranX_;
554     }
555     if (tranY < minTranY_) {
556         tranY = minTranY_;
557     } else if (tranY > maxTranY_) {
558         tranY = maxTranY_;
559     }
560 }
561 
InitMainAxis(AreaType type,int32_t tranX,int32_t tranY)562 bool MoveDragController::InitMainAxis(AreaType type, int32_t tranX, int32_t tranY)
563 {
564     if (type == AreaType::LEFT || type == AreaType::RIGHT) {
565         mainMoveAxis_ = AxisType::X_AXIS;
566     } else if (type == AreaType::TOP || type == AreaType::BOTTOM) {
567         mainMoveAxis_ = AxisType::Y_AXIS;
568     } else if (tranX == 0 && tranY == 0) {
569         return false;
570     } else {
571         mainMoveAxis_ = (std::abs(tranX) > std::abs(tranY)) ? AxisType::X_AXIS : AxisType::Y_AXIS;
572     }
573     CalcFixedAspectRatioTranslateLimits(type, mainMoveAxis_);
574     return true;
575 }
576 
ConvertXYByAspectRatio(int32_t & tx,int32_t & ty,float aspectRatio)577 void MoveDragController::ConvertXYByAspectRatio(int32_t& tx, int32_t& ty, float aspectRatio)
578 {
579     if (mainMoveAxis_ == AxisType::X_AXIS) {
580         ty = tx / aspectRatio;
581     } else if (mainMoveAxis_ == AxisType::Y_AXIS) {
582         tx = ty * aspectRatio;
583     }
584     return;
585 }
586 
InitDecorValue(const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)587 void MoveDragController::InitDecorValue(const sptr<WindowSessionProperty> property,
588     const SystemSessionConfig& sysConfig)
589 {
590     auto windowType = property->GetWindowType();
591     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
592     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
593     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
594     isDecorEnable_ = (isMainWindow ||
595             ((isSubWindow || isDialogWindow) && property->IsDecorEnable())) &&
596         sysConfig.isSystemDecorEnable_ &&
597         WindowHelper::IsWindowModeSupported(sysConfig.decorModeSupportInfo_, property->GetWindowMode());
598 }
599 
ProcessSessionRectChange(const SizeChangeReason & reason)600 void MoveDragController::ProcessSessionRectChange(const SizeChangeReason& reason)
601 {
602     if (moveDragCallback_) {
603         moveDragCallback_(reason);
604     }
605 }
606 
GetVirtualPixelRatio() const607 float MoveDragController::GetVirtualPixelRatio() const
608 {
609     float vpr = 1.5;
610     auto displayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
611     if (displayInfo != nullptr) {
612         vpr = displayInfo->GetVirtualPixelRatio();
613     }
614     WLOGFD("vpr: %{public}f", vpr);
615     return vpr;
616 }
617 
UpdateDragType(int32_t startPointPosX,int32_t startPointPosY)618 void MoveDragController::UpdateDragType(int32_t startPointPosX, int32_t startPointPosY)
619 {
620     if (startPointPosX > rectExceptCorner_.posX_ &&
621         (startPointPosX < rectExceptCorner_.posX_ +
622         static_cast<int32_t>(rectExceptCorner_.width_))) {
623         dragType_ = DragType::DRAG_BOTTOM_OR_TOP;
624     } else if (startPointPosY > rectExceptCorner_.posY_ &&
625         (startPointPosY < rectExceptCorner_.posY_ +
626         static_cast<int32_t>(rectExceptCorner_.height_))) {
627         dragType_ = DragType::DRAG_LEFT_OR_RIGHT;
628     } else if ((startPointPosX <= rectExceptCorner_.posX_ && startPointPosY <= rectExceptCorner_.posY_) ||
629         (startPointPosX >= rectExceptCorner_.posX_ + static_cast<int32_t>(rectExceptCorner_.width_) &&
630          startPointPosY >= rectExceptCorner_.posY_ + static_cast<int32_t>(rectExceptCorner_.height_))) {
631         dragType_ = DragType::DRAG_LEFT_TOP_CORNER;
632     } else {
633         dragType_ = DragType::DRAG_RIGHT_TOP_CORNER;
634     }
635 }
636 
IsPointInDragHotZone(int32_t startPointPosX,int32_t startPointPosY,int32_t sourceType,const WSRect & winRect)637 bool MoveDragController::IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY,
638     int32_t sourceType, const WSRect& winRect)
639 {
640     // calculate rect with hotzone
641     Rect rectWithHotzone;
642     rectWithHotzone.posX_ = winRect.posX_ - static_cast<int32_t>(HOTZONE_POINTER);
643     rectWithHotzone.posY_ = winRect.posY_ - static_cast<int32_t>(HOTZONE_POINTER);
644     rectWithHotzone.width_ = winRect.width_ + HOTZONE_POINTER * 2u; // double hotZone
645     rectWithHotzone.height_ = winRect.height_ + HOTZONE_POINTER * 2u; // double hotZone
646 
647     if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
648         !WindowHelper::IsPointInTargetRectWithBound(startPointPosX, startPointPosY, rectWithHotzone)) {
649         return false;
650     } else if ((!WindowHelper::IsPointInTargetRect(startPointPosX,
651         startPointPosY, rectExceptFrame_)) ||
652         (!WindowHelper::IsPointInWindowExceptCorner(startPointPosX,
653         startPointPosY, rectExceptCorner_))) {
654         return true;
655     }
656     return false;
657 }
658 
CalculateStartRectExceptHotZone(float vpr,const WSRect & winRect)659 void MoveDragController::CalculateStartRectExceptHotZone(float vpr, const WSRect& winRect)
660 {
661     rectExceptFrame_.posX_ = winRect.posX_ +
662         static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
663     rectExceptFrame_.posY_ = winRect.posY_ +
664         static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
665     rectExceptFrame_.width_ = winRect.width_ -
666         static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
667     rectExceptFrame_.height_ = winRect.height_ -
668         static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
669 
670     rectExceptCorner_.posX_ = winRect.posX_ +
671         static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
672     rectExceptCorner_.posY_ = winRect.posY_ +
673         static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
674     rectExceptCorner_.width_ = winRect.width_ -
675         static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
676     rectExceptCorner_.height_ = winRect.height_ -
677         static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
678 }
679 
UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)680 WSError MoveDragController::UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
681 {
682     int32_t pointerId = pointerEvent->GetPointerId();
683     int32_t startPointerId = moveTempProperty_.pointerId_;
684     int32_t pointerType = pointerEvent->GetSourceType();
685     int32_t startPointerType = moveDragProperty_.pointerType_;
686     MMI::PointerEvent::PointerItem pointerItem;
687     int32_t sourceType = pointerEvent->GetSourceType();
688     if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
689         (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
690         pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT)) {
691         WLOGFW("invalid pointerEvent");
692         return WSError::WS_ERROR_NULLPTR;
693     }
694 
695     int32_t pointerDisplayX = pointerItem.GetDisplayX();
696     int32_t pointerDisplayY = pointerItem.GetDisplayY();
697     switch (pointerEvent->GetPointerAction()) {
698         case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
699         case MMI::PointerEvent::POINTER_ACTION_DOWN:
700             moveTempProperty_.pointerId_ = pointerId;
701             moveTempProperty_.pointerType_ = pointerType;
702             moveTempProperty_.lastDownPointerPosX_ = pointerDisplayX;
703             moveTempProperty_.lastDownPointerPosY_ = pointerDisplayY;
704             moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
705             moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
706             moveTempProperty_.lastDownPointerWindowX_ = pointerItem.GetWindowX();
707             moveTempProperty_.lastDownPointerWindowY_ = pointerItem.GetWindowY();
708             break;
709         case MMI::PointerEvent::POINTER_ACTION_MOVE:
710             if ((startPointerId != -1 && startPointerId != pointerId) ||
711                 (startPointerType != -1 && pointerType != startPointerType)) {
712                 WLOGFI("block unnecessary pointer event inside the window");
713                 return WSError::WS_DO_NOTHING;
714             }
715             moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
716             moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
717             break;
718         case MMI::PointerEvent::POINTER_ACTION_UP:
719         case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
720         case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
721             moveTempProperty_ = { -1, -1, -1, -1, -1, -1, -1, -1 };
722             break;
723         }
724         default:
725             break;
726     }
727     return WSError::WS_OK;
728 }
729 
CalcFirstMoveTargetRect(const WSRect & windowRect,bool isFullToFloating)730 void MoveDragController::CalcFirstMoveTargetRect(const WSRect& windowRect, bool isFullToFloating)
731 {
732     if (!GetStartMoveFlag() || moveTempProperty_.isEmpty()) {
733         return;
734     }
735 
736     WSRect originalRect = {
737         moveTempProperty_.lastDownPointerPosX_ - moveTempProperty_.lastDownPointerWindowX_,
738         moveTempProperty_.lastDownPointerPosY_ - moveTempProperty_.lastDownPointerWindowY_,
739         windowRect.width_,
740         windowRect.height_
741     };
742     if (isFullToFloating) {
743         originalRect.posX_ = windowRect.posX_;
744         originalRect.posY_ = windowRect.posY_;
745     }
746     SetOriginalValue(moveTempProperty_.pointerId_, moveTempProperty_.pointerType_,
747         moveTempProperty_.lastDownPointerPosX_, moveTempProperty_.lastDownPointerPosY_, originalRect);
748 
749     int32_t offsetX = moveTempProperty_.lastMovePointerPosX_ - moveTempProperty_.lastDownPointerPosX_;
750     int32_t offsetY = moveTempProperty_.lastMovePointerPosY_ - moveTempProperty_.lastDownPointerPosY_;
751     WSRect targetRect = {
752         originalRect.posX_ + offsetX,
753         originalRect.posY_ + offsetY,
754         originalRect.width_,
755         originalRect.height_
756     };
757     WLOGFD("first move rect: [%{public}d, %{public}d, %{public}u, %{public}u]", targetRect.posX_, targetRect.posY_,
758         targetRect.width_, targetRect.height_);
759     moveDragProperty_.targetRect_ = targetRect;
760     ProcessSessionRectChange(SizeChangeReason::MOVE);
761 }
762 
CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const sptr<WindowSessionProperty> property)763 bool MoveDragController::CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
764     const sptr<WindowSessionProperty> property)
765 {
766     if (pointerEvent == nullptr || property == nullptr) {
767         WLOGE("ConsumeDragEvent stop because of nullptr");
768         return false;
769     }
770     if (GetStartMoveFlag()) {
771         WLOGFD("the window is being moved");
772         return false;
773     }
774     if (!GetStartDragFlag() && pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_DOWN &&
775         pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
776         return false;
777     }
778     int32_t pointerId = pointerEvent->GetPointerId();
779     int32_t startPointerId = moveDragProperty_.pointerId_;
780     if (GetStartDragFlag() && startPointerId != -1 && startPointerId != pointerId) {
781         WLOGFI("block unnecessary pointer event inside the window");
782         return false;
783     }
784     return true;
785 }
786 
UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)787 void MoveDragController::UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
788 {
789     int32_t pointerId = pointerEvent->GetPointerId();
790     MMI::PointerEvent::PointerItem pointerItem;
791     if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
792         WLOGFW("invalid pointerEvent");
793         return;
794     }
795     int32_t pointerDisplayX = pointerItem.GetDisplayX();
796     int32_t pointerDisplayY = pointerItem.GetDisplayY();
797     uint32_t windowDragHotAreaType = SceneSession::GetWindowDragHotAreaType(WINDOW_HOT_AREA_TYPE_UNDEFINED,
798         pointerDisplayX, pointerDisplayY);
799     if (windowDragHotAreaType_ != windowDragHotAreaType) {
800         WLOGFI("the pointerEvent is window drag hot area, old type is: %{public}d, new type is: %{public}d",
801             windowDragHotAreaType_, windowDragHotAreaType);
802     }
803     windowDragHotAreaType_ = windowDragHotAreaType;
804 }
805 
GetOriginalPointerPosX()806 int32_t MoveDragController::GetOriginalPointerPosX()
807 {
808     return moveDragProperty_.originalPointerPosX_;
809 }
810 
GetOriginalPointerPosY()811 int32_t MoveDragController::GetOriginalPointerPosY()
812 {
813     return moveDragProperty_.originalPointerPosY_;
814 }
815 
SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc & func)816 void MoveDragController::SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc& func)
817 {
818     windowDragHotAreaFunc_ = func;
819 }
820 
OnLostFocus()821 void MoveDragController::OnLostFocus()
822 {
823     if (isStartMove_ || isStartDrag_) {
824         WLOGFI("window id %{public}d lost focus, should stop MoveDrag isMove: %{public}d, isDrag: %{public}d",
825             persistentId_, isStartMove_, isStartDrag_);
826         isStartMove_ = false;
827         isStartDrag_ = false;
828         NotifyWindowInputPidChange(isStartDrag_);
829         if (windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED) {
830             ProcessWindowDragHotAreaFunc(true, SizeChangeReason::DRAG_END);
831         }
832         ProcessSessionRectChange(SizeChangeReason::DRAG_END);
833     }
834 }
835 
ResSchedReportData(int32_t type,bool onOffTag)836 void MoveDragController::ResSchedReportData(int32_t type, bool onOffTag)
837 {
838 #ifdef RES_SCHED_ENABLE
839     std::unordered_map<std::string, std::string> payload;
840     // 0 is start, 1 is end
841     if (onOffTag) {
842         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
843     } else {
844         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 1, payload);
845     }
846     WLOGFD("ResSchedReportData success type: %{public}d onOffTag: %{public}d", type, onOffTag);
847 #endif
848 }
849 } // namespace OHOS::Rosen
850