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