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