• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "accessibility_touch_exploration.h"
17 #include "accessibility_window_manager.h"
18 #include "accessibility_event_info.h"
19 #include "hilog_wrapper.h"
20 #include "securec.h"
21 #include "utils.h"
22 
23 namespace OHOS {
24 namespace Accessibility {
25 
InitTwoFingerGestureFuncMap()26 void TouchExploration::InitTwoFingerGestureFuncMap()
27 {
28     handleEventFuncMap_.insert({
29         {TouchExplorationState::TWO_FINGERS_DOWN, {
30             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleTwoFingersDownStateDown)},
31             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleTwoFingersDownStateUp)},
32             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleTwoFingersDownStateMove)},
33             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
34         },
35         {TouchExplorationState::TWO_FINGERS_DRAG, {
36             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleTwoFingersDragStateDown)},
37             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleTwoFingersDragStateUp)},
38             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleTwoFingersDragStateMove)},
39             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
40         },
41         {TouchExplorationState::TWO_FINGERS_TAP, {
42             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleTwoFingersTapStateDown)},
43             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleMultiFingersTapStateUp)},
44             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleTwoFingersTapStateMove)},
45             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
46         },
47         {TouchExplorationState::TWO_FINGERS_CONTINUE_DOWN, {
48             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleMultiFingersContinueDownStateDown)},
49             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleTwoFingersContinueDownStateUp)},
50             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleTwoFingersContinueDownStateMove)},
51             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
52         },
53         {TouchExplorationState::TWO_FINGERS_UNKNOWN, {
54             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleTwoFingersUnknownStateDown)},
55             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleTwoFingersUnknownStateUp)},
56             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleTwoFingersUnknownStateMove)},
57             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
58         }
59     });
60 }
61 
InitThreeFingerGestureFuncMap()62 void TouchExploration::InitThreeFingerGestureFuncMap()
63 {
64     handleEventFuncMap_.insert({
65         {TouchExplorationState::THREE_FINGERS_DOWN, {
66             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleThreeFingersDownStateDown)},
67             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleThreeFingersDownStateUp)},
68             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleThreeFingersDownStateMove)},
69             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
70         },
71         {TouchExplorationState::THREE_FINGERS_SWIPE, {
72             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleThreeFingersSwipeStateDown)},
73             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleThreeFingersSwipeStateUp)},
74             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleThreeFingersSwipeStateMove)},
75             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
76         },
77         {TouchExplorationState::THREE_FINGERS_TAP, {
78             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleThreeFingersTapStateDown)},
79             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleMultiFingersTapStateUp)},
80             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleThreeFingersTapStateMove)},
81             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
82         },
83         {TouchExplorationState::THREE_FINGERS_CONTINUE_DOWN, {
84             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleMultiFingersContinueDownStateDown)},
85             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleThreeFingersContinueDownStateUp)},
86             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleThreeFingersContinueDownStateMove)},
87             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
88         }
89     });
90 }
91 
InitFourFingerGestureFuncMap()92 void TouchExploration::InitFourFingerGestureFuncMap()
93 {
94     handleEventFuncMap_.insert({
95         {TouchExplorationState::THREE_FINGERS_CONTINUE_DOWN, {
96             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleMultiFingersContinueDownStateDown)},
97             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleThreeFingersContinueDownStateUp)},
98             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleThreeFingersContinueDownStateMove)},
99             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
100         },
101         {TouchExplorationState::FOUR_FINGERS_DOWN, {
102             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleFourFingersDownStateDown)},
103             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleFourFingersDownStateUp)},
104             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleFourFingersDownStateMove)},
105             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
106         },
107         {TouchExplorationState::FOUR_FINGERS_SWIPE, {
108             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleFourFingersSwipeStateDown)},
109             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleFourFingersSwipeStateUp)},
110             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleFourFingersSwipeStateMove)},
111             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
112         },
113         {TouchExplorationState::FOUR_FINGERS_TAP, {
114             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleFourFingersTapStateDown)},
115             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleMultiFingersTapStateUp)},
116             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleFourFingersTapStateMove)},
117             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
118         },
119         {TouchExplorationState::FOUR_FINGERS_CONTINUE_DOWN, {
120             {MMI::PointerEvent::POINTER_ACTION_DOWN, BIND(HandleMultiFingersContinueDownStateDown)},
121             {MMI::PointerEvent::POINTER_ACTION_UP, BIND(HandleFourFingersContinueDownStateUp)},
122             {MMI::PointerEvent::POINTER_ACTION_MOVE, BIND(HandleFourFingersContinueDownStateMove)},
123             {MMI::PointerEvent::POINTER_ACTION_CANCEL, BIND(HandleCancelEvent)}}
124         }
125     });
126 }
127 
GetMultiFingerMsgToGestureMap()128 std::map<TouchExplorationMsg, GestureType> TouchExploration::GetMultiFingerMsgToGestureMap()
129 {
130     static std::map<TouchExplorationMsg, GestureType> MULTI_GESTURE_TYPE = {
131         {TouchExplorationMsg::TWO_FINGER_SINGLE_TAP_MSG, GestureType::GESTURE_TWO_FINGER_SINGLE_TAP},
132         {TouchExplorationMsg::TWO_FINGER_LONG_PRESS_MSG, GestureType::GESTURE_INVALID},
133         {TouchExplorationMsg::TWO_FINGER_DOUBLE_TAP_MSG, GestureType::GESTURE_TWO_FINGER_DOUBLE_TAP},
134         {TouchExplorationMsg::TWO_FINGER_DOUBLE_TAP_AND_HOLD_MSG, GestureType::GESTURE_TWO_FINGER_DOUBLE_TAP_AND_HOLD},
135         {TouchExplorationMsg::TWO_FINGER_TRIPLE_TAP_MSG, GestureType::GESTURE_TWO_FINGER_TRIPLE_TAP},
136         {TouchExplorationMsg::TWO_FINGER_TRIPLE_TAP_AND_HOLD_MSG, GestureType::GESTURE_TWO_FINGER_TRIPLE_TAP_AND_HOLD},
137         {TouchExplorationMsg::THREE_FINGER_SINGLE_TAP_MSG, GestureType::GESTURE_THREE_FINGER_SINGLE_TAP},
138         {TouchExplorationMsg::THREE_FINGER_LONG_PRESS_MSG, GestureType::GESTURE_INVALID},
139         {TouchExplorationMsg::THREE_FINGER_DOUBLE_TAP_MSG, GestureType::GESTURE_THREE_FINGER_DOUBLE_TAP},
140         {TouchExplorationMsg::THREE_FINGER_DOUBLE_TAP_AND_HOLD_MSG,
141             GestureType::GESTURE_THREE_FINGER_DOUBLE_TAP_AND_HOLD},
142         {TouchExplorationMsg::THREE_FINGER_TRIPLE_TAP_MSG, GestureType::GESTURE_THREE_FINGER_TRIPLE_TAP},
143         {TouchExplorationMsg::THREE_FINGER_TRIPLE_TAP_AND_HOLD_MSG,
144             GestureType::GESTURE_THREE_FINGER_TRIPLE_TAP_AND_HOLD},
145         {TouchExplorationMsg::FOUR_FINGER_SINGLE_TAP_MSG, GestureType::GESTURE_FOUR_FINGER_SINGLE_TAP},
146         {TouchExplorationMsg::FOUR_FINGER_LONG_PRESS_MSG, GestureType::GESTURE_INVALID},
147         {TouchExplorationMsg::FOUR_FINGER_DOUBLE_TAP_MSG, GestureType::GESTURE_FOUR_FINGER_DOUBLE_TAP},
148         {TouchExplorationMsg::FOUR_FINGER_DOUBLE_TAP_AND_HOLD_MSG,
149             GestureType::GESTURE_FOUR_FINGER_DOUBLE_TAP_AND_HOLD},
150         {TouchExplorationMsg::FOUR_FINGER_TRIPLE_TAP_MSG, GestureType::GESTURE_FOUR_FINGER_TRIPLE_TAP},
151         {TouchExplorationMsg::FOUR_FINGER_TRIPLE_TAP_AND_HOLD_MSG, GestureType::GESTURE_FOUR_FINGER_TRIPLE_TAP_AND_HOLD}
152     };
153     return MULTI_GESTURE_TYPE;
154 }
155 
ProcessMultiFingerGesture(TouchExplorationMsg msg)156 void TouchExploration::ProcessMultiFingerGesture(TouchExplorationMsg msg)
157 {
158     std::map<TouchExplorationMsg, GestureType> multiGestureMap = GetMultiFingerMsgToGestureMap();
159     if (multiGestureMap.find(msg) == multiGestureMap.end()) {
160         return;
161     }
162 
163     static std::map<GestureType, TouchExplorationState> MULTI_FINGER_TAP_GESTURE_TO_STATE = {
164         {GestureType::GESTURE_TWO_FINGER_SINGLE_TAP, TouchExplorationState::TWO_FINGERS_TAP},
165         {GestureType::GESTURE_TWO_FINGER_DOUBLE_TAP, TouchExplorationState::TWO_FINGERS_TAP},
166         {GestureType::GESTURE_TWO_FINGER_TRIPLE_TAP, TouchExplorationState::TWO_FINGERS_TAP},
167         {GestureType::GESTURE_THREE_FINGER_SINGLE_TAP, TouchExplorationState::THREE_FINGERS_TAP},
168         {GestureType::GESTURE_THREE_FINGER_DOUBLE_TAP, TouchExplorationState::THREE_FINGERS_TAP},
169         {GestureType::GESTURE_THREE_FINGER_TRIPLE_TAP, TouchExplorationState::THREE_FINGERS_TAP},
170         {GestureType::GESTURE_FOUR_FINGER_SINGLE_TAP, TouchExplorationState::FOUR_FINGERS_TAP},
171         {GestureType::GESTURE_FOUR_FINGER_DOUBLE_TAP, TouchExplorationState::FOUR_FINGERS_TAP},
172         {GestureType::GESTURE_FOUR_FINGER_TRIPLE_TAP, TouchExplorationState::FOUR_FINGERS_TAP}
173     };
174     GestureType gestureType = multiGestureMap.at(msg);
175     if (MULTI_FINGER_TAP_GESTURE_TO_STATE.find(gestureType) != MULTI_FINGER_TAP_GESTURE_TO_STATE.end()) {
176         // multi-finger multi-tap gesture
177         if (GetCurrentState() == MULTI_FINGER_TAP_GESTURE_TO_STATE.at(gestureType)) {
178             SendGestureEventToAA(gestureType);
179             Clear();
180             SetCurrentState(TouchExplorationState::TOUCH_INIT);
181         }
182     } else if (gestureType == GestureType::GESTURE_INVALID) {
183         if (GetCurrentState() == TouchExplorationState::TWO_FINGERS_DOWN) {
184             SetCurrentState(TouchExplorationState::TWO_FINGERS_UNKNOWN);
185             return;
186         }
187         Clear();
188         SetCurrentState(TouchExplorationState::INVALID);
189     } else {
190         // multi-finger multi-tap-and-hold gesture
191         SendGestureEventToAA(gestureType);
192         Clear();
193         SetCurrentState(TouchExplorationState::INVALID);
194     }
195 }
196 
HandleTwoFingersDownStateDown(MMI::PointerEvent & event)197 void TouchExploration::HandleTwoFingersDownStateDown(MMI::PointerEvent &event)
198 {
199     receivedPointerEvents_.push_back(event);
200     CancelPostEvent(TouchExplorationMsg::TWO_FINGER_SINGLE_TAP_MSG);
201     CancelPostEvent(TouchExplorationMsg::TWO_FINGER_LONG_PRESS_MSG);
202 
203     if (event.GetPointerIds().size() != static_cast<uint32_t>(PointerCount::POINTER_COUNT_3)) {
204         CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
205         Clear();
206         SetCurrentState(TouchExplorationState::INVALID);
207         return;
208     }
209 
210     if (!handler_->HasInnerEvent(static_cast<uint32_t>(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG))) {
211         Clear();
212         SetCurrentState(TouchExplorationState::INVALID);
213         return;
214     }
215 
216     CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
217     handler_->SendEvent(static_cast<uint32_t>(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG), 0,
218         static_cast<int32_t>(TimeoutDuration::MULTI_FINGER_TAP_INTERVAL_TIMEOUT));
219     handler_->SendEvent(static_cast<uint32_t>(TouchExplorationMsg::THREE_FINGER_SINGLE_TAP_MSG), 0,
220         static_cast<int32_t>(TimeoutDuration::DOUBLE_TAP_TIMEOUT));
221     handler_->SendEvent(static_cast<uint32_t>(TouchExplorationMsg::THREE_FINGER_LONG_PRESS_MSG), 0,
222         static_cast<int32_t>(TimeoutDuration::DOUBLE_TAP_TIMEOUT));
223     SetCurrentState(TouchExplorationState::THREE_FINGERS_DOWN);
224 }
225 
HandleTwoFingersDownStateUp(MMI::PointerEvent & event)226 void TouchExploration::HandleTwoFingersDownStateUp(MMI::PointerEvent &event)
227 {
228     receivedPointerEvents_.push_back(event);
229     CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
230     CancelPostEvent(TouchExplorationMsg::TWO_FINGER_LONG_PRESS_MSG);
231 
232     uint32_t pointerSize = event.GetPointerIds().size();
233     if (pointerSize == static_cast<uint32_t>(PointerCount::POINTER_COUNT_1)) {
234         SetCurrentState(TouchExplorationState::TWO_FINGERS_TAP);
235     } else if (pointerSize > static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) {
236         Clear();
237         CancelPostEvent(TouchExplorationMsg::TWO_FINGER_SINGLE_TAP_MSG);
238         SetCurrentState(TouchExplorationState::INVALID);
239     }
240 }
241 
GetBasePointItem(MMI::PointerEvent::PointerItem & basePointerItem,int32_t pId)242 bool TouchExploration::GetBasePointItem(MMI::PointerEvent::PointerItem &basePointerItem, int32_t pId)
243 {
244     HILOG_DEBUG();
245     for (auto rIter = receivedPointerEvents_.rbegin(); rIter != receivedPointerEvents_.rend(); ++rIter) {
246         if ((rIter->GetPointerId() == pId) && (rIter->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN)) {
247             rIter->GetPointerItem(pId, basePointerItem);
248             return true;
249         }
250     }
251     return false;
252 }
253 
GetPointOffset(MMI::PointerEvent & event,std::vector<float> & firstPointOffset,std::vector<float> & secondPointOffset)254 void TouchExploration::GetPointOffset(MMI::PointerEvent &event, std::vector<float> &firstPointOffset,
255     std::vector<float> &secondPointOffset)
256 {
257     HILOG_DEBUG();
258     std::vector<int32_t> pIds = event.GetPointerIds();
259     if (pIds.size() != static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) {
260         return;
261     }
262 
263     MMI::PointerEvent::PointerItem pointerF {};
264     MMI::PointerEvent::PointerItem pointerS {};
265     event.GetPointerItem(pIds[0], pointerF);
266     event.GetPointerItem(pIds[1], pointerS);
267 
268     MMI::PointerEvent::PointerItem basePointerF {};
269     MMI::PointerEvent::PointerItem basePointerS {};
270     if (GetBasePointItem(basePointerF, pIds[0]) && GetBasePointItem(basePointerS, pIds[1])) {
271         firstPointOffset.push_back(pointerF.GetDisplayX() - basePointerF.GetDisplayX());
272         firstPointOffset.push_back(pointerF.GetDisplayY() - basePointerF.GetDisplayY());
273         secondPointOffset.push_back(pointerS.GetDisplayX() - basePointerS.GetDisplayX());
274         secondPointOffset.push_back(pointerS.GetDisplayY() - basePointerS.GetDisplayY());
275     }
276 }
277 
GetAngleCos(float offsetX,float offsetY,bool isGetX)278 float TouchExploration::GetAngleCos(float offsetX, float offsetY, bool isGetX)
279 {
280     HILOG_DEBUG();
281     float ret = isGetX ? offsetX : offsetY;
282     double duration = hypot(offsetX, offsetY);
283     if (duration < - EPSINON || duration > EPSINON) {
284         ret = ret / duration;
285     }
286     return ret;
287 }
288 
IsDragGestureAccept(MMI::PointerEvent & event)289 bool TouchExploration::IsDragGestureAccept(MMI::PointerEvent &event)
290 {
291     HILOG_DEBUG();
292     std::vector<float> firstPointOffset;
293     std::vector<float> secondPointOffset;
294     GetPointOffset(event, firstPointOffset, secondPointOffset);
295     if (firstPointOffset.size() != SCREEN_AXIS_NUM || secondPointOffset.size() != SCREEN_AXIS_NUM) {
296         return false;
297     }
298 
299     float firstOffsetX = firstPointOffset[0];
300     float firstOffsetY = firstPointOffset[1];
301     float secondOffsetX = secondPointOffset[0];
302     float secondOffsetY = secondPointOffset[1];
303     if ((!firstOffsetX && !firstOffsetY) ||
304         (!secondOffsetX && !secondOffsetY)) {
305         return true;
306     }
307 
308     float firstXCos = GetAngleCos(firstOffsetX, firstOffsetY, true);
309     float firstYCos = GetAngleCos(firstOffsetX, firstOffsetY, false);
310     float secondXCos = GetAngleCos(secondOffsetX, secondOffsetY, true);
311     float secondYCos = GetAngleCos(secondOffsetX, secondOffsetY, false);
312     return (firstXCos * secondXCos + firstYCos * secondYCos) >= MAX_DRAG_GESTURE_COSINE;
313 }
314 
SendDragDownEventToMultimodal(MMI::PointerEvent event)315 void TouchExploration::SendDragDownEventToMultimodal(MMI::PointerEvent event)
316 {
317     HILOG_DEBUG();
318     std::vector<int32_t> pIds = event.GetPointerIds();
319     int32_t xPointDown = 0;
320     int32_t yPointDown = 0;
321     int64_t actionTime = 0;
322     MMI::PointerEvent::PointerItem basePointerItem {};
323 
324     for (auto &baseEvent : receivedPointerEvents_) {
325         if ((baseEvent.GetPointerId() == event.GetPointerId()) &&
326             (baseEvent.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN)) {
327             baseEvent.GetPointerItem(event.GetPointerId(), basePointerItem);
328             xPointDown = basePointerItem.GetDisplayX();
329             yPointDown = basePointerItem.GetDisplayY();
330             actionTime = baseEvent.GetActionTime();
331             break;
332         }
333     }
334 
335     MMI::PointerEvent::PointerItem pointer {};
336     event.GetPointerItem(draggingPid_, pointer);
337     pointer.SetDisplayX(xPointDown);
338     pointer.SetDisplayY(yPointDown);
339     event.RemovePointerItem(draggingPid_);
340     event.AddPointerItem(pointer);
341     event.SetActionTime(actionTime);
342     int32_t removePid = draggingPid_ == pIds[0] ? pIds[1] : pIds[0];
343     event.RemovePointerItem(removePid);
344     SendEventToMultimodal(event, ChangeAction::POINTER_DOWN);
345     draggingDownEvent_ = std::make_shared<MMI::PointerEvent>(event);
346 }
347 
IsRealMove(MMI::PointerEvent & event)348 bool TouchExploration::IsRealMove(MMI::PointerEvent &event)
349 {
350     std::vector<float> firstPointOffset;
351     std::vector<float> secondPointOffset;
352     GetPointOffset(event, firstPointOffset, secondPointOffset);
353     if (firstPointOffset.size() != SCREEN_AXIS_NUM || secondPointOffset.size() != SCREEN_AXIS_NUM) {
354         return false;
355     }
356 
357     return (hypot(firstPointOffset[0], firstPointOffset[1]) >= TOUCH_SLOP &&
358         hypot(secondPointOffset[0], secondPointOffset[1]) >= TOUCH_SLOP);
359 }
360 
HandleTwoFingersDownStateMove(MMI::PointerEvent & event)361 void TouchExploration::HandleTwoFingersDownStateMove(MMI::PointerEvent &event)
362 {
363     receivedPointerEvents_.push_back(event);
364 
365     MMI::PointerEvent::PointerItem pointerItem;
366     event.GetPointerItem(event.GetPointerId(), pointerItem);
367 
368     MMI::PointerEvent::PointerItem basePointerItem;
369     if (!GetBasePointItem(basePointerItem, event.GetPointerId())) {
370         HILOG_ERROR("get base point item failed, pid = %{public}d.", event.GetPointerId());
371         return;
372     }
373 
374     int32_t offsetX = pointerItem.GetDisplayX() - basePointerItem.GetDisplayX();
375     int32_t offsetY = pointerItem.GetDisplayY() - basePointerItem.GetDisplayY();
376     if (hypot(offsetX, offsetY) > TOUCH_SLOP * static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) {
377         HILOG_DEBUG("cancel two-finger tap gesture because finger move");
378         CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
379         CancelPostEvent(TouchExplorationMsg::TWO_FINGER_SINGLE_TAP_MSG);
380         CancelPostEvent(TouchExplorationMsg::TWO_FINGER_LONG_PRESS_MSG);
381         if (event.GetPointerIds().size() != static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) {
382             Clear();
383             SendScreenWakeUpEvent(event);
384             SetCurrentState(TouchExplorationState::INVALID);
385             return;
386         }
387         if (!IsRealMove(event)) {
388             HILOG_DEBUG("not a move");
389             return;
390         }
391         if (IsDragGestureAccept(event)) {
392             draggingPid_ = event.GetPointerId();
393             SendDragDownEventToMultimodal(event);
394             SendEventToMultimodal(event, ChangeAction::NO_CHANGE);
395             SetCurrentState(TouchExplorationState::TWO_FINGERS_DRAG);
396         } else {
397             for (auto &receivedEvent : receivedPointerEvents_) {
398                 SendEventToMultimodal(receivedEvent, ChangeAction::NO_CHANGE);
399             }
400             Clear();
401             SetCurrentState(TouchExplorationState::PASSING_THROUGH);
402         }
403     }
404 }
405 
SendUpForDragDownEvent()406 void TouchExploration::SendUpForDragDownEvent()
407 {
408     HILOG_DEBUG();
409     if (receivedPointerEvents_.empty()) {
410         HILOG_ERROR("received pointer event is null!");
411         return;
412     }
413 
414     MMI::PointerEvent lastMoveEvent = receivedPointerEvents_.back();
415     MMI::PointerEvent::PointerItem movePointerItem;
416     lastMoveEvent.GetPointerItem(lastMoveEvent.GetPointerId(), movePointerItem);
417     int32_t x = movePointerItem.GetDisplayX();
418     int32_t y = movePointerItem.GetDisplayY();
419 
420     if (draggingDownEvent_ == nullptr) {
421         HILOG_ERROR("dragging down event is null!");
422         return;
423     }
424     MMI::PointerEvent::PointerItem pointerItem {};
425     draggingDownEvent_->SetActionTime(Utils::GetSystemTime() * US_TO_MS);
426     draggingDownEvent_->GetPointerItem(draggingDownEvent_->GetPointerId(), pointerItem);
427     pointerItem.SetPressed(false);
428     pointerItem.SetDisplayX(x);
429     pointerItem.SetDisplayY(y);
430     draggingDownEvent_->RemovePointerItem(draggingDownEvent_->GetPointerId());
431     draggingDownEvent_->AddPointerItem(pointerItem);
432     SendEventToMultimodal(*draggingDownEvent_, ChangeAction::POINTER_UP);
433 }
434 
HandleTwoFingersDragStateDown(MMI::PointerEvent & event)435 void TouchExploration::HandleTwoFingersDragStateDown(MMI::PointerEvent &event)
436 {
437     if (event.GetPointerIds().size() != static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) {
438         SendUpForDragDownEvent();
439         Clear();
440         SetCurrentState(TouchExplorationState::INVALID);
441     }
442 }
443 
HandleTwoFingersDragStateUp(MMI::PointerEvent & event)444 void TouchExploration::HandleTwoFingersDragStateUp(MMI::PointerEvent &event)
445 {
446     if (event.GetPointerIds().size() == static_cast<uint32_t>(PointerCount::POINTER_COUNT_1)) {
447         SendUpForDragDownEvent();
448         Clear();
449         SetCurrentState(TouchExplorationState::TOUCH_INIT);
450     }
451 }
452 
HandleTwoFingersDragStateMove(MMI::PointerEvent & event)453 void TouchExploration::HandleTwoFingersDragStateMove(MMI::PointerEvent &event)
454 {
455     std::vector<int32_t> pIds = event.GetPointerIds();
456     if (pIds.size() != static_cast<uint32_t>(PointerCount::POINTER_COUNT_2) || event.GetPointerId() != draggingPid_) {
457         return;
458     }
459 
460     receivedPointerEvents_.push_back(event);
461 
462 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
463     // Get densityPixels from WMS
464     AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
465     auto display = displayMgr.GetDefaultDisplay();
466     float densityPixels = display->GetVirtualPixelRatio();
467     int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * densityPixels);
468 #else
469     HILOG_DEBUG("not support display manager");
470     int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * 1);
471 #endif
472 
473     MMI::PointerEvent::PointerItem pointerF {};
474     MMI::PointerEvent::PointerItem pointerS {};
475     event.GetPointerItem(pIds[0], pointerF);
476     event.GetPointerItem(pIds[1], pointerS);
477     float xPointF = pointerF.GetDisplayX();
478     float xPointS = pointerS.GetDisplayX();
479     float yPointF = pointerF.GetDisplayY();
480     float yPointS = pointerS.GetDisplayY();
481     float offsetX = abs(xPointF - xPointS);
482     float offsetY = abs(yPointF - yPointS);
483     double duration = hypot(offsetX, offsetY);
484     if (duration > miniZoomPointerDistance) {
485         // Adjust this event's location.
486         MMI::PointerEvent::PointerItem pointer {};
487         event.GetPointerItem(event.GetPointerId(), pointer);
488         pointer.SetDisplayX(pointer.GetDisplayX() + offsetX / DIVIDE_NUM);
489         pointer.SetDisplayY(pointer.GetDisplayY() + offsetY / DIVIDE_NUM);
490         event.RemovePointerItem(event.GetPointerId());
491         event.AddPointerItem(pointer);
492     }
493     int32_t removePid = draggingPid_ == pIds[0]? pIds[1] : pIds[0];
494     event.RemovePointerItem(removePid);
495     SendEventToMultimodal(event, ChangeAction::NO_CHANGE);
496 }
497 
GetPointerItemWithFingerNum(uint32_t fingerNum,std::vector<MMI::PointerEvent::PointerItem> & curPoints,std::vector<MMI::PointerEvent::PointerItem> & prePoints,MMI::PointerEvent & event)498 bool TouchExploration::GetPointerItemWithFingerNum(uint32_t fingerNum,
499     std::vector<MMI::PointerEvent::PointerItem> &curPoints,
500     std::vector<MMI::PointerEvent::PointerItem> &prePoints, MMI::PointerEvent &event)
501 {
502     HILOG_DEBUG();
503     if (fingerNum > static_cast<uint32_t>(INT32_MAX)) {
504         HILOG_ERROR("fingerNum is invalid!");
505         return false;
506     }
507 
508     bool findPrePointer = false;
509     std::vector<int32_t> pIds = event.GetPointerIds();
510     for (int32_t i = 0; i < static_cast<int32_t>(fingerNum); i++) {
511         findPrePointer = false;
512         event.GetPointerItem(pIds[i], curPoints[i]);
513         for (auto &preEvent : receivedPointerEvents_) {
514             if ((preEvent.GetPointerId() == i) &&
515                 (preEvent.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN)) {
516                 findPrePointer = true;
517                 preEvent.GetPointerItem(i, prePoints[i]);
518                 break;
519             }
520         }
521         if (!findPrePointer) {
522             HILOG_ERROR("get prePointerItem(%{public}d) failed", i);
523             return false;
524         }
525     }
526     return true;
527 }
528 
IsMultiFingerMultiTap(MMI::PointerEvent & event,const uint32_t fingerNum)529 bool TouchExploration::IsMultiFingerMultiTap(MMI::PointerEvent &event, const uint32_t fingerNum)
530 {
531     HILOG_DEBUG();
532     std::vector<MMI::PointerEvent::PointerItem> curPoints(fingerNum);
533     std::vector<MMI::PointerEvent::PointerItem> prePoints(fingerNum);
534     if (!GetPointerItemWithFingerNum(fingerNum, curPoints, prePoints, event)) {
535         return false;
536     }
537 
538     std::vector<int32_t> excludePid(fingerNum, -1);
539     for (auto curPoint : curPoints) {
540         float moveDelta = FLT_MAX;
541         int32_t nearestPid = -1;
542         int32_t curX = curPoint.GetDisplayX();
543         int32_t curY = curPoint.GetDisplayY();
544         for (auto prePoint : prePoints) {
545             int32_t pId = prePoint.GetPointerId();
546             if (std::find(excludePid.begin(), excludePid.end(), pId) != excludePid.end()) {
547                 continue;
548             }
549             int32_t preX = prePoint.GetDisplayX();
550             int32_t preY = prePoint.GetDisplayY();
551             int32_t offsetX = curX - preX;
552             int32_t offsetY = curY - preY;
553             if (offsetX == 0 && offsetY == 0) {
554                 nearestPid = pId;
555                 moveDelta = 0;
556                 break;
557             }
558 
559             float delta = hypot(offsetX, offsetY);
560             if (delta < moveDelta) {
561                 moveDelta = delta;
562                 nearestPid = pId;
563             }
564         }
565         if (moveDelta < multiTapOffsetThresh_ * fingerNum) {
566             excludePid.push_back(nearestPid);
567         } else {
568             return false;
569         }
570     }
571 
572     return true;
573 }
574 
IsMultiFingerMultiTapGesture(MMI::PointerEvent & event,const uint32_t fingerNum)575 bool TouchExploration::IsMultiFingerMultiTapGesture(MMI::PointerEvent &event, const uint32_t fingerNum)
576 {
577     HILOG_DEBUG();
578 
579     if (fingerNum < static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) {
580         Clear();
581         SetCurrentState(TouchExplorationState::INVALID);
582         return false;
583     }
584 
585     if (IsMultiFingerMultiTap(event, fingerNum)) {
586         multiTapNum_ = multiTapNum_ + 1;
587         HILOG_DEBUG("%{public}d finger %{public}d tap is recognized", static_cast<int32_t>(fingerNum),
588             multiTapNum_ + 1);
589     } else {
590         Clear();
591         SetCurrentState(TouchExplorationState::INVALID);
592         return false;
593     }
594 
595     uint32_t fingerNumIndex = fingerNum - 2;
596     handler_->SendEvent(static_cast<uint32_t>(GESTURE_TAP_MSG[multiTapNum_][fingerNumIndex]), 0,
597         static_cast<int32_t>(TimeoutDuration::DOUBLE_TAP_TIMEOUT));
598     handler_->SendEvent(static_cast<uint32_t>(GESTURE_HOLD_MSG[multiTapNum_][fingerNumIndex]), 0,
599         static_cast<int32_t>(TimeoutDuration::DOUBLE_TAP_TIMEOUT));
600     return true;
601 }
602 
HandleMultiFingersTapStateDown(MMI::PointerEvent & event,uint32_t fingerNum)603 void TouchExploration::HandleMultiFingersTapStateDown(MMI::PointerEvent &event, uint32_t fingerNum)
604 {
605     receivedPointerEvents_.push_back(event);
606     CancelMultiFingerTapEvent();
607     CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
608 
609     if (multiTapNum_ == TAP_COUNT_MAXIMUM - 1) {
610         Clear();
611         SetCurrentState(TouchExplorationState::INVALID);
612         return;
613     }
614 
615     uint32_t pointerSize = event.GetPointerIds().size();
616     if (pointerSize < fingerNum) {
617         handler_->SendEvent(static_cast<uint32_t>(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG), 0,
618             static_cast<int32_t>(TimeoutDuration::MULTI_FINGER_TAP_INTERVAL_TIMEOUT));
619     } else if (pointerSize == fingerNum) {
620         if (IsMultiFingerMultiTapGesture(event, fingerNum)) {
621             if (fingerNum == static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) {
622                 SetCurrentState(TouchExplorationState::TWO_FINGERS_CONTINUE_DOWN);
623             } else if (fingerNum == static_cast<uint32_t>(PointerCount::POINTER_COUNT_3)) {
624                 SetCurrentState(TouchExplorationState::THREE_FINGERS_CONTINUE_DOWN);
625             } else {
626                 SetCurrentState(TouchExplorationState::FOUR_FINGERS_CONTINUE_DOWN);
627             }
628         }
629     } else {
630         Clear();
631         SetCurrentState(TouchExplorationState::INVALID);
632     }
633 }
634 
HandleTwoFingersTapStateDown(MMI::PointerEvent & event)635 void TouchExploration::HandleTwoFingersTapStateDown(MMI::PointerEvent &event)
636 {
637     HandleMultiFingersTapStateDown(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_2));
638 }
639 
HandleMultiFingersTapStateUp(MMI::PointerEvent & event)640 void TouchExploration::HandleMultiFingersTapStateUp(MMI::PointerEvent &event)
641 {
642     Clear();
643     CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
644 
645     uint32_t pointerSize = event.GetPointerIds().size();
646     if (pointerSize == static_cast<uint32_t>(PointerCount::POINTER_COUNT_1)) {
647         SetCurrentState(TouchExplorationState::TOUCH_INIT);
648     } else {
649         SetCurrentState(TouchExplorationState::INVALID);
650     }
651 }
652 
HandleMultiFingersTapStateMove(MMI::PointerEvent & event,uint32_t fingerNum)653 void TouchExploration::HandleMultiFingersTapStateMove(MMI::PointerEvent &event, uint32_t fingerNum)
654 {
655     if (event.GetPointerIds().size() >= fingerNum) {
656         Clear();
657         SetCurrentState(TouchExplorationState::INVALID);
658         return;
659     }
660 
661     receivedPointerEvents_.push_back(event);
662 
663     MMI::PointerEvent::PointerItem pointerItem;
664     event.GetPointerItem(event.GetPointerId(), pointerItem);
665 
666     MMI::PointerEvent::PointerItem basePointerItem;
667     if (!GetBasePointItem(basePointerItem, event.GetPointerId())) {
668         HILOG_ERROR("get base point item failed, pid = %{public}d.", event.GetPointerId());
669         return;
670     }
671 
672     int32_t offsetX = pointerItem.GetDisplayX() - basePointerItem.GetDisplayX();
673     int32_t offsetY = pointerItem.GetDisplayY() - basePointerItem.GetDisplayY();
674     if (hypot(offsetX, offsetY) > TOUCH_SLOP * (fingerNum - 1)) {
675         CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
676         Clear();
677         SetCurrentState(TouchExplorationState::INVALID);
678     }
679 
680     SendScreenWakeUpEvent(event);
681 }
682 
HandleTwoFingersTapStateMove(MMI::PointerEvent & event)683 void TouchExploration::HandleTwoFingersTapStateMove(MMI::PointerEvent &event)
684 {
685     HandleMultiFingersTapStateMove(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_2));
686 }
687 
HandleMultiFingersContinueDownStateDown(MMI::PointerEvent & event)688 void TouchExploration::HandleMultiFingersContinueDownStateDown(MMI::PointerEvent &event)
689 {
690     CancelMultiFingerTapEvent();
691     CancelMultiFingerTapAndHoldEvent();
692     Clear();
693     SetCurrentState(TouchExplorationState::INVALID);
694 }
695 
HandleMultiFingersContinueDownStateUp(MMI::PointerEvent & event,uint32_t fingerNum)696 void TouchExploration::HandleMultiFingersContinueDownStateUp(MMI::PointerEvent &event, uint32_t fingerNum)
697 {
698     receivedPointerEvents_.push_back(event);
699     CancelMultiFingerTapAndHoldEvent();
700 
701     uint32_t pointerSize = event.GetPointerIds().size();
702     if (pointerSize == static_cast<uint32_t>(PointerCount::POINTER_COUNT_1)) {
703         if (fingerNum == static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) {
704             SetCurrentState(TouchExplorationState::TWO_FINGERS_TAP);
705         } else if (fingerNum == static_cast<uint32_t>(PointerCount::POINTER_COUNT_3)) {
706             SetCurrentState(TouchExplorationState::THREE_FINGERS_TAP);
707         } else {
708             SetCurrentState(TouchExplorationState::FOUR_FINGERS_TAP);
709         }
710     } else if (pointerSize > fingerNum) {
711         CancelMultiFingerTapEvent();
712         Clear();
713         SetCurrentState(TouchExplorationState::INVALID);
714     }
715 }
716 
HandleTwoFingersContinueDownStateUp(MMI::PointerEvent & event)717 void TouchExploration::HandleTwoFingersContinueDownStateUp(MMI::PointerEvent &event)
718 {
719     HandleMultiFingersContinueDownStateUp(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_2));
720 }
721 
HandleMultiFingersContinueDownStateMove(MMI::PointerEvent & event,uint32_t fingerNum)722 void TouchExploration::HandleMultiFingersContinueDownStateMove(MMI::PointerEvent &event, uint32_t fingerNum)
723 {
724     receivedPointerEvents_.push_back(event);
725 
726     MMI::PointerEvent::PointerItem pointerItem;
727     event.GetPointerItem(event.GetPointerId(), pointerItem);
728 
729     MMI::PointerEvent::PointerItem basePointerItem;
730     if (!GetBasePointItem(basePointerItem, event.GetPointerId())) {
731         HILOG_ERROR("get base point item failed, pid = %{public}d.", event.GetPointerId());
732         return;
733     }
734 
735     int32_t offsetX = pointerItem.GetDisplayX() - basePointerItem.GetDisplayX();
736     int32_t offsetY = pointerItem.GetDisplayY() - basePointerItem.GetDisplayY();
737     if (hypot(offsetX, offsetY) > TOUCH_SLOP * fingerNum) {
738         Clear();
739         CancelMultiFingerTapEvent();
740         CancelMultiFingerTapAndHoldEvent();
741         SetCurrentState(TouchExplorationState::INVALID);
742     }
743 
744     SendScreenWakeUpEvent(event);
745 }
746 
HandleTwoFingersContinueDownStateMove(MMI::PointerEvent & event)747 void TouchExploration::HandleTwoFingersContinueDownStateMove(MMI::PointerEvent &event)
748 {
749     HandleMultiFingersContinueDownStateMove(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_2));
750 }
751 
HandleTwoFingersUnknownStateDown(MMI::PointerEvent & event)752 void TouchExploration::HandleTwoFingersUnknownStateDown(MMI::PointerEvent &event)
753 {
754     if (event.GetPointerIds().size() == static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) {
755         receivedPointerEvents_.push_back(event);
756         return;
757     }
758 
759     Clear();
760     SetCurrentState(TouchExplorationState::INVALID);
761 }
762 
HandleTwoFingersUnknownStateUp(MMI::PointerEvent & event)763 void TouchExploration::HandleTwoFingersUnknownStateUp(MMI::PointerEvent &event)
764 {
765     receivedPointerEvents_.push_back(event);
766     if (event.GetPointerIds().size() == static_cast<uint32_t>(PointerCount::POINTER_COUNT_1)) {
767         Clear();
768         SetCurrentState(TouchExplorationState::TOUCH_INIT);
769     }
770 }
771 
HandleTwoFingersUnknownStateMove(MMI::PointerEvent & event)772 void TouchExploration::HandleTwoFingersUnknownStateMove(MMI::PointerEvent &event)
773 {
774     if ((event.GetPointerIds().size() != static_cast<uint32_t>(PointerCount::POINTER_COUNT_2)) ||
775         (event.GetPointerId() != draggingPid_)) {
776         return;
777     }
778 
779     receivedPointerEvents_.push_back(event);
780 
781     std::vector<int32_t> pIds = event.GetPointerIds();
782     if (IsDragGestureAccept(event)) {
783         int32_t removePid = draggingPid_ == pIds[0] ? pIds[1] : pIds[0];
784         event.RemovePointerItem(removePid);
785         SendEventToMultimodal(event, ChangeAction::POINTER_DOWN);
786         draggingDownEvent_ = std::make_shared<MMI::PointerEvent>(event);
787         SetCurrentState(TouchExplorationState::TWO_FINGERS_DRAG);
788         return;
789     }
790 }
791 
HandleThreeFingersDownStateDown(MMI::PointerEvent & event)792 void TouchExploration::HandleThreeFingersDownStateDown(MMI::PointerEvent &event)
793 {
794     receivedPointerEvents_.push_back(event);
795     CancelPostEvent(TouchExplorationMsg::THREE_FINGER_SINGLE_TAP_MSG);
796     CancelPostEvent(TouchExplorationMsg::THREE_FINGER_LONG_PRESS_MSG);
797 
798     if (event.GetPointerIds().size() != static_cast<uint32_t>(PointerCount::POINTER_COUNT_4)) {
799         CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
800         Clear();
801         SetCurrentState(TouchExplorationState::INVALID);
802         return;
803     }
804 
805     if (!handler_->HasInnerEvent(static_cast<uint32_t>(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG))) {
806         Clear();
807         SetCurrentState(TouchExplorationState::INVALID);
808         return;
809     }
810 
811     CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
812     handler_->SendEvent(static_cast<uint32_t>(TouchExplorationMsg::FOUR_FINGER_SINGLE_TAP_MSG), 0,
813         static_cast<int32_t>(TimeoutDuration::DOUBLE_TAP_TIMEOUT));
814     handler_->SendEvent(static_cast<uint32_t>(TouchExplorationMsg::FOUR_FINGER_LONG_PRESS_MSG), 0,
815         static_cast<int32_t>(TimeoutDuration::DOUBLE_TAP_TIMEOUT));
816     SetCurrentState(TouchExplorationState::FOUR_FINGERS_DOWN);
817 }
818 
HandleThreeFingersDownStateUp(MMI::PointerEvent & event)819 void TouchExploration::HandleThreeFingersDownStateUp(MMI::PointerEvent &event)
820 {
821     receivedPointerEvents_.push_back(event);
822     CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
823     CancelPostEvent(TouchExplorationMsg::THREE_FINGER_LONG_PRESS_MSG);
824 
825     uint32_t pointerSize = event.GetPointerIds().size();
826     if (pointerSize == static_cast<uint32_t>(PointerCount::POINTER_COUNT_1)) {
827         SetCurrentState(TouchExplorationState::THREE_FINGERS_TAP);
828     } else if (pointerSize > static_cast<uint32_t>(PointerCount::POINTER_COUNT_3)) {
829         CancelPostEvent(TouchExplorationMsg::THREE_FINGER_SINGLE_TAP_MSG);
830         Clear();
831         SetCurrentState(TouchExplorationState::INVALID);
832     }
833 }
834 
StoreMultiFingerSwipeBaseDownPoint()835 void TouchExploration::StoreMultiFingerSwipeBaseDownPoint()
836 {
837     HILOG_DEBUG();
838     for (auto& event : receivedPointerEvents_) {
839         if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
840             Pointer mp;
841             MMI::PointerEvent::PointerItem pointerItem;
842             std::vector<Pointer> mpVec;
843             int32_t pId = event.GetPointerId();
844             event.GetPointerItem(pId, pointerItem);
845             mp.px_ = static_cast<float>(pointerItem.GetDisplayX());
846             mp.py_ = static_cast<float>(pointerItem.GetDisplayY());
847             mpVec.push_back(mp);
848             multiFingerSwipeRoute_.insert(std::make_pair(pId, mpVec));
849             multiFingerSwipePrePoint_[event.GetPointerId()] = std::make_shared<MMI::PointerEvent>(event);
850         }
851     }
852 }
853 
HandleThreeFingersDownStateMove(MMI::PointerEvent & event)854 void TouchExploration::HandleThreeFingersDownStateMove(MMI::PointerEvent &event)
855 {
856     receivedPointerEvents_.push_back(event);
857 
858     MMI::PointerEvent::PointerItem pointerItem;
859     event.GetPointerItem(event.GetPointerId(), pointerItem);
860 
861     MMI::PointerEvent::PointerItem basePointerItem;
862     if (!GetBasePointItem(basePointerItem, event.GetPointerId())) {
863         HILOG_ERROR("get base point item failed, pid = %{public}d.", event.GetPointerId());
864         return;
865     }
866 
867     int32_t offsetX = pointerItem.GetDisplayX() - basePointerItem.GetDisplayX();
868     int32_t offsetY = pointerItem.GetDisplayY() - basePointerItem.GetDisplayY();
869     if (hypot(offsetX, offsetY) > TOUCH_SLOP * static_cast<uint32_t>(PointerCount::POINTER_COUNT_3)) {
870         CancelPostEvent(TouchExplorationMsg::WAIT_ANOTHER_FINGER_DOWN_MSG);
871         CancelPostEvent(TouchExplorationMsg::THREE_FINGER_SINGLE_TAP_MSG);
872         CancelPostEvent(TouchExplorationMsg::THREE_FINGER_LONG_PRESS_MSG);
873         if (event.GetPointerIds().size() != static_cast<uint32_t>(PointerCount::POINTER_COUNT_3)) {
874             Clear();
875             SendScreenWakeUpEvent(event);
876             SetCurrentState(TouchExplorationState::INVALID);
877             return;
878         }
879         StoreMultiFingerSwipeBaseDownPoint();
880         multiFingerSwipeDirection_ = GetSwipeDirection(offsetX, offsetY);
881         SetCurrentState(TouchExplorationState::THREE_FINGERS_SWIPE);
882     }
883 
884     SendScreenWakeUpEvent(event);
885 }
886 
HandleThreeFingersSwipeStateDown(MMI::PointerEvent & event)887 void TouchExploration::HandleThreeFingersSwipeStateDown(MMI::PointerEvent &event)
888 {
889     Clear();
890     SetCurrentState(TouchExplorationState::INVALID);
891 }
892 
GetMultiFingerSwipeBasePointerItem(MMI::PointerEvent::PointerItem & basePointerItem,int32_t pId)893 bool TouchExploration::GetMultiFingerSwipeBasePointerItem(MMI::PointerEvent::PointerItem &basePointerItem, int32_t pId)
894 {
895     HILOG_DEBUG();
896     if (multiFingerSwipePrePoint_.count(pId) == 0 || !multiFingerSwipePrePoint_[pId]) {
897         HILOG_ERROR("get base pointEvent(%{public}d) failed", pId);
898         return false;
899     }
900     multiFingerSwipePrePoint_[pId]->GetPointerItem(pId, basePointerItem);
901     return true;
902 }
903 
SaveMultiFingerSwipeGesturePointerInfo(MMI::PointerEvent & event)904 bool TouchExploration::SaveMultiFingerSwipeGesturePointerInfo(MMI::PointerEvent &event)
905 {
906     HILOG_DEBUG();
907     MMI::PointerEvent::PointerItem pointerItem;
908     int32_t pId = event.GetPointerId();
909     event.GetPointerItem(pId, pointerItem);
910 
911     MMI::PointerEvent::PointerItem basePointerItem;
912     if (!GetMultiFingerSwipeBasePointerItem(basePointerItem, pId)) {
913         HILOG_WARN("get base point item failed, pid = %{public}d.", pId);
914         return true;
915     }
916 
917     int32_t offsetX = pointerItem.GetDisplayX() - basePointerItem.GetDisplayX();
918     int32_t offsetY = pointerItem.GetDisplayY() - basePointerItem.GetDisplayY();
919     if (abs(offsetX) > mMinPixelsBetweenSamplesX_ || abs(offsetY) > mMinPixelsBetweenSamplesY_) {
920         if (multiFingerSwipeDirection_ != GetSwipeDirection(offsetX, offsetY)) {
921             Clear();
922             if ((event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP) &&
923                 (event.GetPointerIds().size() == static_cast<uint32_t>(PointerCount::POINTER_COUNT_1))) {
924                 SetCurrentState(TouchExplorationState::TOUCH_INIT);
925             } else {
926                 SetCurrentState(TouchExplorationState::INVALID);
927             }
928             return false;
929         }
930 
931         Pointer mp;
932         mp.px_ = static_cast<float>(pointerItem.GetDisplayX());
933         mp.py_ = static_cast<float>(pointerItem.GetDisplayY());
934         multiFingerSwipeRoute_[pId].push_back(mp);
935         multiFingerSwipePrePoint_[pId] = std::make_shared<MMI::PointerEvent>(event);
936     }
937 
938     return true;
939 }
940 
RecognizeMultiFingerSwipePath(const std::vector<Pointer> & path)941 bool TouchExploration::RecognizeMultiFingerSwipePath(const std::vector<Pointer> &path)
942 {
943     HILOG_DEBUG();
944     if (path.size() < MIN_MULTI_FINGER_SWIPE_POINTER_NUM) {
945         return false;
946     }
947 
948     int pathSize = static_cast<int>(path.size() - 1);
949     for (int routerIndex = 0; routerIndex < pathSize; routerIndex++) {
950         int32_t dx = static_cast<int32_t>(path[routerIndex + 1].px_ - path[routerIndex].px_);
951         int32_t dy = static_cast<int32_t>(path[routerIndex + 1].py_ - path[routerIndex].py_);
952         if (GetSwipeDirection(dx, dy) != multiFingerSwipeDirection_) {
953             return false;
954         }
955     }
956     return true;
957 }
958 
GetMultiFingerSwipeGestureId(uint32_t fingerNum)959 GestureType TouchExploration::GetMultiFingerSwipeGestureId(uint32_t fingerNum)
960 {
961     HILOG_DEBUG();
962     if (fingerNum == static_cast<uint32_t>(PointerCount::POINTER_COUNT_3)) {
963         switch (multiFingerSwipeDirection_) {
964             case SWIPE_LEFT:
965                 return GestureType::GESTURE_THREE_FINGER_SWIPE_LEFT;
966             case SWIPE_RIGHT:
967                 return GestureType::GESTURE_THREE_FINGER_SWIPE_RIGHT;
968             case SWIPE_UP:
969                 return GestureType::GESTURE_THREE_FINGER_SWIPE_UP;
970             case SWIPE_DOWN:
971                 return GestureType::GESTURE_THREE_FINGER_SWIPE_DOWN;
972             default:
973                 return GestureType::GESTURE_INVALID;
974         }
975     } else if (fingerNum == static_cast<uint32_t>(PointerCount::POINTER_COUNT_4)) {
976         switch (multiFingerSwipeDirection_) {
977             case SWIPE_LEFT:
978                 return GestureType::GESTURE_FOUR_FINGER_SWIPE_LEFT;
979             case SWIPE_RIGHT:
980                 return GestureType::GESTURE_FOUR_FINGER_SWIPE_RIGHT;
981             case SWIPE_UP:
982                 return GestureType::GESTURE_FOUR_FINGER_SWIPE_UP;
983             case SWIPE_DOWN:
984                 return GestureType::GESTURE_FOUR_FINGER_SWIPE_DOWN;
985             default:
986                 return GestureType::GESTURE_INVALID;
987         }
988     }
989     return GestureType::GESTURE_INVALID;
990 }
991 
HandleMultiFingersSwipeStateUp(MMI::PointerEvent & event,uint32_t fingerNum)992 void TouchExploration::HandleMultiFingersSwipeStateUp(MMI::PointerEvent &event, uint32_t fingerNum)
993 {
994     receivedPointerEvents_.push_back(event);
995 
996     if (!SaveMultiFingerSwipeGesturePointerInfo(event)) {
997         return;
998     }
999 
1000     if (event.GetPointerIds().size() == static_cast<uint32_t>(PointerCount::POINTER_COUNT_1)) {
1001         if (fingerNum > static_cast<uint32_t>(INT32_MAX)) {
1002             SetCurrentState(TouchExplorationState::TOUCH_INIT);
1003             return;
1004         }
1005         for (int32_t pIndex = 0; pIndex < static_cast<int32_t>(fingerNum); pIndex++) {
1006             if (multiFingerSwipeRoute_.count(pIndex) == 0 ||
1007                 multiFingerSwipeRoute_[pIndex].size() < MIN_MULTI_FINGER_SWIPE_POINTER_NUM) {
1008                 Clear();
1009                 SetCurrentState(TouchExplorationState::TOUCH_INIT);
1010                 return;
1011             }
1012             if (!RecognizeMultiFingerSwipePath(multiFingerSwipeRoute_[pIndex])) {
1013                 Clear();
1014                 SetCurrentState(TouchExplorationState::TOUCH_INIT);
1015                 return;
1016             }
1017         }
1018 
1019         GestureType gestureId = GetMultiFingerSwipeGestureId(fingerNum);
1020         SendGestureEventToAA(gestureId);
1021         Clear();
1022         SetCurrentState(TouchExplorationState::TOUCH_INIT);
1023     }
1024 }
1025 
HandleThreeFingersSwipeStateUp(MMI::PointerEvent & event)1026 void TouchExploration::HandleThreeFingersSwipeStateUp(MMI::PointerEvent &event)
1027 {
1028     HandleMultiFingersSwipeStateUp(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_3));
1029 }
1030 
HandleThreeFingersSwipeStateMove(MMI::PointerEvent & event)1031 void TouchExploration::HandleThreeFingersSwipeStateMove(MMI::PointerEvent &event)
1032 {
1033     receivedPointerEvents_.push_back(event);
1034     SaveMultiFingerSwipeGesturePointerInfo(event);
1035     SendScreenWakeUpEvent(event);
1036 }
1037 
HandleThreeFingersTapStateDown(MMI::PointerEvent & event)1038 void TouchExploration::HandleThreeFingersTapStateDown(MMI::PointerEvent &event)
1039 {
1040     HandleMultiFingersTapStateDown(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_3));
1041 }
1042 
HandleThreeFingersTapStateMove(MMI::PointerEvent & event)1043 void TouchExploration::HandleThreeFingersTapStateMove(MMI::PointerEvent &event)
1044 {
1045     HandleMultiFingersTapStateMove(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_3));
1046 }
1047 
HandleThreeFingersContinueDownStateUp(MMI::PointerEvent & event)1048 void TouchExploration::HandleThreeFingersContinueDownStateUp(MMI::PointerEvent &event)
1049 {
1050     HandleMultiFingersContinueDownStateUp(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_3));
1051 }
1052 
HandleThreeFingersContinueDownStateMove(MMI::PointerEvent & event)1053 void TouchExploration::HandleThreeFingersContinueDownStateMove(MMI::PointerEvent &event)
1054 {
1055     HandleMultiFingersContinueDownStateMove(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_3));
1056 }
1057 
HandleFourFingersDownStateDown(MMI::PointerEvent & event)1058 void TouchExploration::HandleFourFingersDownStateDown(MMI::PointerEvent &event)
1059 {
1060     Clear();
1061     CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_SINGLE_TAP_MSG);
1062     CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_LONG_PRESS_MSG);
1063     SetCurrentState(TouchExplorationState::INVALID);
1064 }
1065 
HandleFourFingersDownStateUp(MMI::PointerEvent & event)1066 void TouchExploration::HandleFourFingersDownStateUp(MMI::PointerEvent &event)
1067 {
1068     receivedPointerEvents_.push_back(event);
1069     CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_LONG_PRESS_MSG);
1070 
1071     uint32_t pointerSize = event.GetPointerIds().size();
1072     if (pointerSize == static_cast<uint32_t>(PointerCount::POINTER_COUNT_1)) {
1073         SetCurrentState(TouchExplorationState::FOUR_FINGERS_TAP);
1074     } else if (pointerSize > static_cast<uint32_t>(PointerCount::POINTER_COUNT_4)) {
1075         Clear();
1076         CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_SINGLE_TAP_MSG);
1077         SetCurrentState(TouchExplorationState::INVALID);
1078     }
1079 }
1080 
HandleFourFingersDownStateMove(MMI::PointerEvent & event)1081 void TouchExploration::HandleFourFingersDownStateMove(MMI::PointerEvent &event)
1082 {
1083     receivedPointerEvents_.push_back(event);
1084 
1085     MMI::PointerEvent::PointerItem pointerItem;
1086     event.GetPointerItem(event.GetPointerId(), pointerItem);
1087     MMI::PointerEvent::PointerItem basePointerItem;
1088     if (!GetBasePointItem(basePointerItem, event.GetPointerId())) {
1089         HILOG_ERROR("get base point item failed, pid = %{public}d.", event.GetPointerId());
1090         return;
1091     }
1092 
1093     int32_t offsetX = pointerItem.GetDisplayX() - basePointerItem.GetDisplayX();
1094     int32_t offsetY = pointerItem.GetDisplayY() - basePointerItem.GetDisplayY();
1095     if (hypot(offsetX, offsetY) > TOUCH_SLOP * static_cast<uint32_t>(PointerCount::POINTER_COUNT_4)) {
1096         CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_SINGLE_TAP_MSG);
1097         CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_LONG_PRESS_MSG);
1098         if (event.GetPointerIds().size() != static_cast<uint32_t>(PointerCount::POINTER_COUNT_4)) {
1099             Clear();
1100             SendScreenWakeUpEvent(event);
1101             SetCurrentState(TouchExplorationState::INVALID);
1102             return;
1103         }
1104         StoreMultiFingerSwipeBaseDownPoint();
1105         multiFingerSwipeDirection_ = GetSwipeDirection(offsetX, offsetY);
1106         SetCurrentState(TouchExplorationState::FOUR_FINGERS_SWIPE);
1107     }
1108 
1109     SendScreenWakeUpEvent(event);
1110 }
1111 
HandleFourFingersSwipeStateDown(MMI::PointerEvent & event)1112 void TouchExploration::HandleFourFingersSwipeStateDown(MMI::PointerEvent &event)
1113 {
1114     Clear();
1115     SetCurrentState(TouchExplorationState::INVALID);
1116 }
1117 
HandleFourFingersSwipeStateUp(MMI::PointerEvent & event)1118 void TouchExploration::HandleFourFingersSwipeStateUp(MMI::PointerEvent &event)
1119 {
1120     HandleMultiFingersSwipeStateUp(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_4));
1121 }
1122 
HandleFourFingersSwipeStateMove(MMI::PointerEvent & event)1123 void TouchExploration::HandleFourFingersSwipeStateMove(MMI::PointerEvent &event)
1124 {
1125     receivedPointerEvents_.push_back(event);
1126     SaveMultiFingerSwipeGesturePointerInfo(event);
1127     SendScreenWakeUpEvent(event);
1128 }
1129 
HandleFourFingersTapStateDown(MMI::PointerEvent & event)1130 void TouchExploration::HandleFourFingersTapStateDown(MMI::PointerEvent &event)
1131 {
1132     HandleMultiFingersTapStateDown(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_4));
1133 }
1134 
HandleFourFingersTapStateMove(MMI::PointerEvent & event)1135 void TouchExploration::HandleFourFingersTapStateMove(MMI::PointerEvent &event)
1136 {
1137     HandleMultiFingersTapStateMove(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_4));
1138 }
1139 
HandleFourFingersContinueDownStateUp(MMI::PointerEvent & event)1140 void TouchExploration::HandleFourFingersContinueDownStateUp(MMI::PointerEvent &event)
1141 {
1142     HandleMultiFingersContinueDownStateUp(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_4));
1143 }
1144 
HandleFourFingersContinueDownStateMove(MMI::PointerEvent & event)1145 void TouchExploration::HandleFourFingersContinueDownStateMove(MMI::PointerEvent &event)
1146 {
1147     HandleMultiFingersContinueDownStateMove(event, static_cast<uint32_t>(PointerCount::POINTER_COUNT_4));
1148 }
1149 
CancelPostEvent(TouchExplorationMsg msg)1150 void TouchExploration::CancelPostEvent(TouchExplorationMsg msg)
1151 {
1152     HILOG_DEBUG("innerEventID = %{public}u", static_cast<uint32_t>(msg));
1153     if (handler_->HasInnerEvent(static_cast<uint32_t>(msg))) {
1154         handler_->RemoveEvent(static_cast<uint32_t>(msg));
1155     }
1156 }
1157 
CancelMultiFingerTapEvent()1158 void TouchExploration::CancelMultiFingerTapEvent()
1159 {
1160     CancelPostEvent(TouchExplorationMsg::TWO_FINGER_SINGLE_TAP_MSG);
1161     CancelPostEvent(TouchExplorationMsg::TWO_FINGER_DOUBLE_TAP_MSG);
1162     CancelPostEvent(TouchExplorationMsg::TWO_FINGER_TRIPLE_TAP_MSG);
1163     CancelPostEvent(TouchExplorationMsg::THREE_FINGER_SINGLE_TAP_MSG);
1164     CancelPostEvent(TouchExplorationMsg::THREE_FINGER_DOUBLE_TAP_MSG);
1165     CancelPostEvent(TouchExplorationMsg::THREE_FINGER_TRIPLE_TAP_MSG);
1166     CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_SINGLE_TAP_MSG);
1167     CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_DOUBLE_TAP_MSG);
1168     CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_TRIPLE_TAP_MSG);
1169 }
1170 
CancelMultiFingerTapAndHoldEvent()1171 void TouchExploration::CancelMultiFingerTapAndHoldEvent()
1172 {
1173     CancelPostEvent(TouchExplorationMsg::TWO_FINGER_DOUBLE_TAP_AND_HOLD_MSG);
1174     CancelPostEvent(TouchExplorationMsg::TWO_FINGER_TRIPLE_TAP_AND_HOLD_MSG);
1175     CancelPostEvent(TouchExplorationMsg::THREE_FINGER_DOUBLE_TAP_AND_HOLD_MSG);
1176     CancelPostEvent(TouchExplorationMsg::THREE_FINGER_TRIPLE_TAP_AND_HOLD_MSG);
1177     CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_DOUBLE_TAP_AND_HOLD_MSG);
1178     CancelPostEvent(TouchExplorationMsg::FOUR_FINGER_TRIPLE_TAP_AND_HOLD_MSG);
1179 }
1180 } // namespace Accessibility
1181 } // namespace OHOS