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