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