1 /*
2 * Copyright (C) 2022 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_guider.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 namespace {
26 constexpr int32_t POINTER_COUNT_1 = 1;
27 constexpr int32_t POINTER_COUNT_2 = 2;
28 constexpr int32_t SCREEN_AXIS_NUM = 2;
29 constexpr int32_t REMOVE_POINTER_ID_1 = 1;
30 constexpr int64_t IGNORE_REPEAT_EXECUTE_INTERVAL = 300;
31 } // namespace
32
TGEventHandler( const std::shared_ptr<AppExecFwk::EventRunner> &runner, TouchGuider &tgServer)33 TGEventHandler::TGEventHandler(
34 const std::shared_ptr<AppExecFwk::EventRunner> &runner, TouchGuider &tgServer)
35 : AppExecFwk::EventHandler(runner), tgServer_(tgServer)
36 {
37 }
38
39 int64_t TouchGuider::lastDoubleTapTime = 0;
40
TouchGuider()41 TouchGuider::TouchGuider()
42 {
43 HILOG_DEBUG();
44 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
45 }
46
StartUp()47 void TouchGuider::StartUp()
48 {
49 HILOG_DEBUG();
50 touchGuideListener_ = std::make_unique<TouchGuideListener>(*this);
51 gestureRecognizer_.RegisterListener(*touchGuideListener_.get());
52 multiFingerGestureRecognizer_.RegisterListener(*touchGuideListener_.get());
53
54 runner_ = Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner();
55 if (!runner_) {
56 HILOG_ERROR("get runner failed");
57 return;
58 }
59
60 handler_ = std::make_shared<TGEventHandler>(runner_, *this);
61 if (!handler_) {
62 HILOG_ERROR("create event handler failed");
63 return;
64 }
65 }
66
ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)67 void TGEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
68 {
69 HILOG_DEBUG();
70 switch (event->GetInnerEventId()) {
71 case TouchGuider::EXIT_GESTURE_REC_MSG:
72 tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
73 break;
74 case TouchGuider::SEND_HOVER_ENTER_MOVE_MSG:
75 HoverEnterAndMoveRunner();
76 break;
77 case TouchGuider::SEND_HOVER_EXIT_MSG:
78 HoverExitRunner();
79 break;
80 case TouchGuider::SEND_TOUCH_GUIDE_END_MSG:
81 tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_END);
82 break;
83 default:
84 break;
85 }
86 }
87
SendTouchEventToAA(MMI::PointerEvent &event)88 void TouchGuider::SendTouchEventToAA(MMI::PointerEvent &event)
89 {
90 HILOG_DEBUG();
91
92 if (event.GetPointerIds().size() != POINTER_COUNT_1) {
93 return;
94 }
95
96 MMI::PointerEvent::PointerItem pointerIterm = {};
97 if (!event.GetPointerItem(event.GetPointerId(), pointerIterm)) {
98 HILOG_WARN("GetPointerItem(%{public}d) failed", event.GetPointerId());
99 }
100
101 if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
102 SendAccessibilityEventToAA(EventType::TYPE_TOUCH_BEGIN);
103 } else if (!pointerIterm.IsPressed()) {
104 SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
105 }
106 }
107
OnPointerEvent(MMI::PointerEvent &event)108 bool TouchGuider::OnPointerEvent(MMI::PointerEvent &event)
109 {
110 HILOG_DEBUG();
111 if (event.GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
112 EventTransmission::OnPointerEvent(event);
113 return false;
114 }
115
116 if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN ||
117 event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP) {
118 HILOG_INFO("PointerAction:%{public}d, PointerId:%{public}d.", event.GetPointerAction(),
119 event.GetPointerId());
120 }
121 SendTouchEventToAA(event);
122
123 if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
124 if ((static_cast<TouchGuideState>(currentState_) == TouchGuideState::DRAGGING) &&
125 event.GetPointerId() == currentPid_) {
126 EventTransmission::OnPointerEvent(event);
127 } else if (static_cast<TouchGuideState>(currentState_) != TouchGuideState::DRAGGING) {
128 Clear(event);
129 }
130 event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_HOVER_CANCEL);
131 EventTransmission::OnPointerEvent(event);
132 return true;
133 }
134 RecordReceivedEvent(event);
135
136 bool gestureRecognizedFlag = false;
137 if (!multiFingerGestureRecognizer_.IsMultiFingerGestureStarted() &&
138 gestureRecognizer_.OnPointerEvent(event)) {
139 gestureRecognizedFlag = true;
140 }
141 if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
142 HILOG_DEBUG("recognize doubleTap and longpress");
143 if (doubleTapLongPressDownEvent_ != nullptr) {
144 SendEventToMultimodal(*doubleTapLongPressDownEvent_, NO_CHANGE);
145 doubleTapLongPressDownEvent_ = nullptr;
146 }
147 SendEventToMultimodal(event, NO_CHANGE);
148 gestureRecognizedFlag = true;
149 }
150
151 multiFingerGestureRecognizer_.OnPointerEvent(event);
152
153 if (!gestureRecognizedFlag) {
154 HandlePointerEvent(event);
155 }
156 return true;
157 }
158
HandlePointerEvent(MMI::PointerEvent &event)159 void TouchGuider::HandlePointerEvent(MMI::PointerEvent &event)
160 {
161 switch (static_cast<TouchGuideState>(currentState_)) {
162 case TouchGuideState::TOUCH_GUIDING:
163 if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN &&
164 event.GetPointerIds().size() == POINTER_COUNT_1) {
165 cachedPointerEvents_.clear();
166 }
167 cachedPointerEvents_.push_back(event);
168 HandleTouchGuidingState(event);
169 break;
170 case TouchGuideState::DRAGGING:
171 HandleDraggingState(event);
172 break;
173 case TouchGuideState::TRANSMITTING:
174 HandleTransmitingState(event);
175 break;
176 case TouchGuideState::PASSING_THROUGH:
177 HandlePassingThroughState(event);
178 break;
179 default:
180 break;
181 }
182 }
183
DestroyEvents()184 void TouchGuider::DestroyEvents()
185 {
186 HILOG_DEBUG();
187
188 Clear();
189 EventTransmission::DestroyEvents();
190 }
191
SendAccessibilityEventToAA(EventType eventType)192 void TouchGuider::SendAccessibilityEventToAA(EventType eventType)
193 {
194 HILOG_DEBUG("eventType is 0x%{public}x.", eventType);
195
196 AccessibilityEventInfo eventInfo {};
197 eventInfo.SetEventType(eventType);
198 int32_t windowsId = Singleton<AccessibilityWindowManager>::GetInstance().GetActiveWindowId();
199 eventInfo.SetWindowId(windowsId);
200 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(eventInfo);
201 if (eventType == EventType::TYPE_TOUCH_GUIDE_BEGIN) {
202 isTouchGuiding_ = true;
203 } else if (eventType == EventType::TYPE_TOUCH_GUIDE_END) {
204 isTouchGuiding_ = false;
205 }
206 }
207
SendGestureEventToAA(GestureType gestureId)208 void TouchGuider::SendGestureEventToAA(GestureType gestureId)
209 {
210 HILOG_DEBUG("gestureId is %{public}d.", gestureId);
211
212 AccessibilityEventInfo eventInfo {};
213 int32_t windowsId = Singleton<AccessibilityWindowManager>::GetInstance().GetActiveWindowId();
214 eventInfo.SetWindowId(windowsId);
215 eventInfo.SetEventType(EventType::TYPE_GESTURE_EVENT);
216 eventInfo.SetGestureType(gestureId);
217 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(eventInfo);
218 }
219
OffsetEvent(MMI::PointerEvent &event)220 void TouchGuider::OffsetEvent(MMI::PointerEvent &event)
221 {
222 HILOG_DEBUG("OffsetEvent");
223 MMI::PointerEvent::PointerItem pointer = {};
224 event.GetPointerItem(event.GetPointerId(), pointer);
225
226 // add offset
227 int32_t newDisplayX = pointer.GetDisplayX() + static_cast<int>(longPressOffsetX_);
228 int32_t newDisplayY = pointer.GetDisplayY() + static_cast<int>(longPressOffsetY_);
229
230 HILOG_DEBUG("newDisplayX: %{public}d, newDisplayY: %{public}d", newDisplayX, newDisplayY);
231 pointer.SetDisplayX(newDisplayX);
232 pointer.SetDisplayY(newDisplayY);
233 event.RemovePointerItem(event.GetPointerId());
234 event.AddPointerItem(pointer);
235 }
236
SendEventToMultimodal(MMI::PointerEvent &event, int32_t action)237 void TouchGuider::SendEventToMultimodal(MMI::PointerEvent &event, int32_t action)
238 {
239 HILOG_DEBUG("action:%{public}d, SourceType:%{public}d.", action, event.GetSourceType());
240
241 if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
242 bool focusedElementExistFlag = true;
243 if (!focusedElementExist_) {
244 HILOG_DEBUG("send long press event to multimodal, but no focused element.");
245 focusedElementExistFlag = false;
246 }
247 OffsetEvent(event);
248 if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP &&
249 event.GetPointerIds().size() == POINTER_COUNT_1) {
250 HILOG_INFO("doubleTap and longpress end");
251 Clear(event);
252 }
253 if (!focusedElementExistFlag) {
254 return;
255 }
256 }
257
258 switch (action) {
259 case HOVER_MOVE:
260 if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
261 event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_HOVER_MOVE);
262 }
263 break;
264 case POINTER_DOWN:
265 if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
266 event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_DOWN);
267 }
268 break;
269 case POINTER_UP:
270 if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
271 event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_UP);
272 }
273 break;
274 case HOVER_ENTER:
275 if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
276 event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_HOVER_ENTER);
277 }
278 break;
279 case HOVER_EXIT:
280 if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
281 event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_HOVER_EXIT);
282 }
283 break;
284 default:
285 break;
286 }
287 EventTransmission::OnPointerEvent(event);
288 RecordInjectedEvent(event);
289 }
290
getHoverEnterAndMoveEvent()291 std::list<MMI::PointerEvent> TouchGuider::getHoverEnterAndMoveEvent()
292 {
293 HILOG_DEBUG();
294
295 return pointerEvents_;
296 }
297
ClearHoverEnterAndMoveEvent()298 void TouchGuider::ClearHoverEnterAndMoveEvent()
299 {
300 HILOG_DEBUG();
301
302 pointerEvents_.clear();
303 gestureRecognizer_.Clear();
304 }
305
getLastReceivedEvent()306 std::shared_ptr<MMI::PointerEvent> TouchGuider::getLastReceivedEvent()
307 {
308 HILOG_DEBUG();
309
310 return receivedRecorder_.lastEvent;
311 }
312
OnDoubleTap(MMI::PointerEvent &event)313 bool TouchGuider::TouchGuideListener::OnDoubleTap(MMI::PointerEvent &event)
314 {
315 HILOG_INFO();
316
317 if (server_.currentState_ != static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING)) {
318 return false;
319 }
320 server_.OnTouchInteractionEnd();
321 server_.CancelPostEventIfNeed(server_.SEND_HOVER_ENTER_MOVE_MSG);
322 server_.CancelPostEventIfNeed(server_.SEND_HOVER_EXIT_MSG);
323 server_.ForceSendAndRemoveEvent(server_.SEND_TOUCH_GUIDE_END_MSG, event);
324
325 return server_.ExecuteActionOnAccessibilityFocused(ActionType::ACCESSIBILITY_ACTION_CLICK);
326 }
327
OnStarted()328 bool TouchGuider::TouchGuideListener::OnStarted()
329 {
330 HILOG_DEBUG();
331
332 server_.currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
333 server_.CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
334 server_.CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
335 server_.PostGestureRecognizeExit();
336 server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_BEGIN);
337 return true;
338 }
339
MultiFingerGestureOnStarted(bool isTwoFingerGesture)340 void TouchGuider::TouchGuideListener::MultiFingerGestureOnStarted(bool isTwoFingerGesture)
341 {
342 HILOG_DEBUG();
343
344 if (!isTwoFingerGesture) {
345 server_.currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
346 return;
347 }
348
349 server_.CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
350 server_.CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
351 server_.PostGestureRecognizeExit();
352 server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_BEGIN);
353 }
354
OnCompleted(GestureType gestureId)355 bool TouchGuider::TouchGuideListener::OnCompleted(GestureType gestureId)
356 {
357 HILOG_INFO("gestureId is %{public}d", gestureId);
358
359 if (server_.currentState_ != static_cast<int32_t>(TouchGuideState::TRANSMITTING)) {
360 HILOG_DEBUG("OnCompleted, state is not transmitting.");
361 return false;
362 }
363 server_.OnTouchInteractionEnd();
364 server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
365 server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
366 server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
367
368 // Send customize gesture type to aa
369 server_.SendGestureEventToAA(gestureId);
370 return true;
371 }
372
MultiFingerGestureOnCompleted(GestureType gestureId)373 void TouchGuider::TouchGuideListener::MultiFingerGestureOnCompleted(GestureType gestureId)
374 {
375 HILOG_INFO("gestureId is %{public}d", gestureId);
376
377 server_.OnTouchInteractionEnd();
378 server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
379 server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
380 server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
381
382 // Send customize gesture type to aa
383 server_.SendGestureEventToAA(gestureId);
384 }
385
OnCancelled(MMI::PointerEvent &event)386 bool TouchGuider::TouchGuideListener::OnCancelled(MMI::PointerEvent &event)
387 {
388 HILOG_DEBUG();
389
390 switch (static_cast<TouchGuideState>(server_.currentState_)) {
391 case TouchGuideState::TRANSMITTING:
392 server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
393 if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP &&
394 event.GetPointerIds().size() == POINTER_COUNT_1) {
395 server_.OnTouchInteractionEnd();
396 }
397 server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
398 server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
399 break;
400 case TouchGuideState::TOUCH_GUIDING:
401 server_.pointerEvents_.push_back(event);
402 server_.ForceSendAndRemoveEvent(SEND_HOVER_ENTER_MOVE_MSG, event);
403 server_.CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
404 server_.SendEventToMultimodal(event, HOVER_MOVE);
405 break;
406 default:
407 return false;
408 }
409 return true;
410 }
411
MultiFingerGestureOnCancelled(const bool isNoDelayFlag)412 void TouchGuider::TouchGuideListener::MultiFingerGestureOnCancelled(const bool isNoDelayFlag)
413 {
414 HILOG_DEBUG();
415
416 if (static_cast<TouchGuideState>(server_.currentState_) == TouchGuideState::TRANSMITTING) {
417 server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
418 }
419 server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
420 server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
421 if (isNoDelayFlag) {
422 server_.OnTouchInteractionEnd();
423 }
424 }
425
SetFindFocusedElementInfoResult(const AccessibilityElementInfo &info, const int32_t requestId)426 void TouchGuider::ElementOperatorCallbackImpl::SetFindFocusedElementInfoResult(const AccessibilityElementInfo &info,
427 const int32_t requestId)
428 {
429 HILOG_DEBUG("Response [requestId:%{public}d]", requestId);
430 accessibilityInfoResult_ = info;
431 promise_.set_value();
432 }
433
SetSearchElementInfoByTextResult( const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)434 void TouchGuider::ElementOperatorCallbackImpl::SetSearchElementInfoByTextResult(
435 const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
436 {
437 HILOG_DEBUG("Response [requestId:%{public}d]", requestId);
438 elementInfosResult_ = infos;
439 promise_.set_value();
440 }
441
SetSearchElementInfoByAccessibilityIdResult( const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)442 void TouchGuider::ElementOperatorCallbackImpl::SetSearchElementInfoByAccessibilityIdResult(
443 const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
444 {
445 HILOG_DEBUG("Response [requestId:%{public}d]", requestId);
446 elementInfosResult_ = infos;
447 promise_.set_value();
448 }
449
SetFocusMoveSearchResult(const AccessibilityElementInfo &info, const int32_t requestId)450 void TouchGuider::ElementOperatorCallbackImpl::SetFocusMoveSearchResult(const AccessibilityElementInfo &info,
451 const int32_t requestId)
452 {
453 HILOG_DEBUG("Response [requestId:%{public}d]", requestId);
454 accessibilityInfoResult_ = info;
455 promise_.set_value();
456 }
457
SetExecuteActionResult(const bool succeeded, const int32_t requestId)458 void TouchGuider::ElementOperatorCallbackImpl::SetExecuteActionResult(const bool succeeded, const int32_t requestId)
459 {
460 HILOG_DEBUG("Response [result:%{public}d, requestId:%{public}d]", succeeded, requestId);
461 executeActionResult_ = succeeded;
462 promise_.set_value();
463 }
464
HandleTouchGuidingState(MMI::PointerEvent &event)465 void TouchGuider::HandleTouchGuidingState(MMI::PointerEvent &event)
466 {
467 HILOG_DEBUG("action: %{public}d", event.GetPointerAction());
468
469 switch (event.GetPointerAction()) {
470 case MMI::PointerEvent::POINTER_ACTION_DOWN:
471 if (event.GetPointerIds().size() == POINTER_COUNT_1) {
472 HandleTouchGuidingStateInnerDown(event);
473 } else if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
474 SendEventToMultimodal(event, NO_CHANGE);
475 } else {
476 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
477 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
478 }
479 break;
480 case MMI::PointerEvent::POINTER_ACTION_MOVE:
481 HandleTouchGuidingStateInnerMove(event);
482 break;
483 case MMI::PointerEvent::POINTER_ACTION_UP:
484 if (event.GetPointerIds().size() == POINTER_COUNT_1 && !IsTouchInteractionEnd() &&
485 !multiFingerGestureRecognizer_.IsMultiFingerRecognize()) {
486 if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
487 HILOG_DEBUG();
488 SendEventToMultimodal(event, NO_CHANGE);
489 Clear(event);
490 break;
491 }
492 OnTouchInteractionEnd();
493 if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
494 PostHoverExit();
495 } else if (isTouchGuiding_) {
496 SendExitEvents();
497 PostHoverExit();
498 }
499 }
500 break;
501 case MMI::PointerEvent::POINTER_ACTION_PULL_MOVE:
502 SendEventToMultimodal(event, NO_CHANGE);
503 break;
504 case MMI::PointerEvent::POINTER_ACTION_PULL_UP:
505 SendEventToMultimodal(event, NO_CHANGE);
506 break;
507 default:
508 break;
509 }
510 }
511
HandleDraggingState(MMI::PointerEvent &event)512 void TouchGuider::HandleDraggingState(MMI::PointerEvent &event)
513 {
514 HILOG_DEBUG();
515 std::vector<int32_t> pIds = event.GetPointerIds();
516 switch (event.GetPointerAction()) {
517 case MMI::PointerEvent::POINTER_ACTION_DOWN:
518 if (event.GetPointerIds().size() == POINTER_COUNT_1) {
519 Clear(event);
520 } else {
521 currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
522 SendAllUpEvents(event);
523 }
524 break;
525 case MMI::PointerEvent::POINTER_ACTION_MOVE:
526 if (event.GetPointerId() == currentPid_) {
527 HandleDraggingStateInnerMove(event);
528 }
529 break;
530 case MMI::PointerEvent::POINTER_ACTION_UP:
531 if (pIds.size() == POINTER_COUNT_1) {
532 if (event.GetPointerId() == currentPid_) {
533 HILOG_DEBUG("single currentPid_ move: %{public}d", event.GetPointerId());
534 OnTouchInteractionEnd();
535 SendEventToMultimodal(event, NO_CHANGE);
536 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
537 }
538 } else {
539 if (event.GetPointerId() == currentPid_ && pIds.size() == POINTER_COUNT_2) {
540 HILOG_DEBUG("double currentPid_ move: %{public}d", event.GetPointerId());
541 int32_t removePid = currentPid_ == pIds[0]? pIds[1] : pIds[0];
542 event.RemovePointerItem(removePid);
543 OnTouchInteractionEnd();
544 SendEventToMultimodal(event, NO_CHANGE);
545 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
546 }
547 }
548
549 break;
550 default:
551 break;
552 }
553 }
554
HandleTransmitingState(MMI::PointerEvent &event)555 void TouchGuider::HandleTransmitingState(MMI::PointerEvent &event)
556 {
557 HILOG_DEBUG();
558
559 switch (event.GetPointerAction()) {
560 case MMI::PointerEvent::POINTER_ACTION_DOWN:
561 if (event.GetPointerIds().size() == POINTER_COUNT_1) {
562 Clear(event);
563 }
564 break;
565 case MMI::PointerEvent::POINTER_ACTION_UP:
566 if (event.GetPointerIds().size() == POINTER_COUNT_1 && !IsTouchInteractionEnd() &&
567 !multiFingerGestureRecognizer_.IsMultiFingerRecognize()) {
568 if (longPressPointId_ >= 0) {
569 // Adjust this event's location.
570 MMI::PointerEvent::PointerItem pointer = {};
571 event.GetPointerItem(event.GetPointerId(), pointer);
572 pointer.SetDisplayX(pointer.GetDisplayX() + longPressOffsetX_);
573 pointer.SetDisplayY(pointer.GetDisplayY() + longPressOffsetY_);
574 event.RemovePointerItem(event.GetPointerId());
575 event.AddPointerItem(pointer);
576 longPressPointId_ = INIT_POINT_ID;
577 longPressOffsetX_ = INIT_MMIPOINT;
578 longPressOffsetY_ = INIT_MMIPOINT;
579 }
580 SendEventToMultimodal(event, NO_CHANGE);
581 OnTouchInteractionEnd();
582 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
583 }
584 break;
585 default:
586 MMI::PointerEvent::PointerItem pointerItem = {};
587 for (auto& pid : event.GetPointerIds()) {
588 event.GetPointerItem(pid, pointerItem);
589 pointerItem.SetPressed(false);
590 event.RemovePointerItem(pid);
591 event.AddPointerItem(pointerItem);
592 }
593 SendEventToMultimodal(event, NO_CHANGE);
594 break;
595 }
596 }
597
HandlePassingThroughState(MMI::PointerEvent &event)598 void TouchGuider::HandlePassingThroughState(MMI::PointerEvent &event)
599 {
600 HILOG_DEBUG();
601
602 if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP &&
603 event.GetPointerIds().size() == POINTER_COUNT_1) {
604 SendEventToMultimodal(event, NO_CHANGE);
605 OnTouchInteractionEnd();
606 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
607 return;
608 }
609
610 SendEventToMultimodal(event, NO_CHANGE);
611 return;
612 }
613
Clear(MMI::PointerEvent &event)614 void TouchGuider::Clear(MMI::PointerEvent &event)
615 {
616 HILOG_DEBUG();
617
618 if (currentState_ == static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING)) {
619 SendExitEvents();
620 } else if (currentState_ == static_cast<int32_t>(TouchGuideState::DRAGGING) ||
621 currentState_ == static_cast<int32_t>(TouchGuideState::TRANSMITTING)) {
622 SendUpForAllInjectedEvent(event);
623 }
624
625 CancelPostEvent(EXIT_GESTURE_REC_MSG);
626 CancelPostEvent(SEND_TOUCH_GUIDE_END_MSG);
627 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
628 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
629 ClearInjectedEventRecorder();
630 ClearReceivedEventRecorder();
631 pointerEvents_.clear();
632 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
633 isTouchGuiding_ = false;
634 gestureRecognizer_.Clear();
635 longPressPointId_ = INIT_POINT_ID;
636 longPressOffsetX_ = INIT_MMIPOINT;
637 longPressOffsetY_ = INIT_MMIPOINT;
638 leftTopX_ = INIT_POINT_DISPLAY;
639 leftTopY_ = INIT_POINT_DISPLAY;
640 rightBottomX_ = INIT_POINT_DISPLAY;
641 rightBottomY_ = INIT_POINT_DISPLAY;
642 focusedElementExist_ = false;
643 currentPid_ = -1;
644 cachedPointerEvents_.clear();
645 OnTouchInteractionEnd();
646 }
647
Clear()648 void TouchGuider::Clear()
649 {
650 HILOG_DEBUG();
651
652 std::shared_ptr<MMI::PointerEvent> event = getLastReceivedEvent();
653 if (event) {
654 Clear(*event);
655 }
656 }
657
SendExitEvents()658 void TouchGuider::SendExitEvents()
659 {
660 HILOG_DEBUG();
661
662 if (!HasEventPending(SEND_TOUCH_GUIDE_END_MSG)) {
663 PostAccessibilityEvent(SEND_TOUCH_GUIDE_END_MSG);
664 }
665 }
666
HandleTouchGuidingStateInnerDown(MMI::PointerEvent &event)667 void TouchGuider::HandleTouchGuidingStateInnerDown(MMI::PointerEvent &event)
668 {
669 HILOG_DEBUG();
670
671 OnTouchInteractionStart();
672 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
673 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
674 if (isTouchGuiding_) {
675 SendExitEvents();
676 }
677 if (!gestureRecognizer_.IsfirstTap() && !multiFingerGestureRecognizer_.IsMultiFingerGestureStarted()) {
678 ForceSendAndRemoveEvent(SEND_TOUCH_GUIDE_END_MSG, event);
679 if (!isTouchGuiding_) {
680 if (!HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
681 PostHoverEnterAndMove(event);
682 } else {
683 pointerEvents_.push_back(event);
684 }
685 }
686 } else if (gestureRecognizer_.GetIsDoubleTap() && !multiFingerGestureRecognizer_.IsMultiFingerGestureStarted()) {
687 doubleTapLongPressDownEvent_ = nullptr;
688
689 AccessibilityElementInfo focusedElementInfo = {};
690 if (!FindFocusedElement(focusedElementInfo)) {
691 HILOG_ERROR("FindFocusedElement failed.");
692 return;
693 }
694 HILOG_DEBUG("FindFocusedElement success");
695 MMI::PointerEvent::PointerItem pointerIterm = {};
696 if (!event.GetPointerItem(event.GetPointerId(), pointerIterm)) {
697 HILOG_ERROR("event.GetPointerItem failed");
698 return;
699 }
700 HILOG_DEBUG("GetPointerItem success");
701 focusedElementExist_ = true;
702
703 // set point x,y range and offset
704 leftTopX_ = focusedElementInfo.GetRectInScreen().GetLeftTopXScreenPostion();
705 leftTopY_ = focusedElementInfo.GetRectInScreen().GetLeftTopYScreenPostion();
706 rightBottomX_ = focusedElementInfo.GetRectInScreen().GetRightBottomXScreenPostion();
707 rightBottomY_ = focusedElementInfo.GetRectInScreen().GetRightBottomYScreenPostion();
708 longPressOffsetX_ = static_cast<float>(DIVIDE_2(leftTopX_ + rightBottomX_) - pointerIterm.GetDisplayX());
709 longPressOffsetY_ = static_cast<float>(DIVIDE_2(leftTopY_ + rightBottomY_) - pointerIterm.GetDisplayY());
710
711 doubleTapLongPressDownEvent_ = std::make_shared<MMI::PointerEvent>(event);
712 }
713 }
714
SendPointerDownEventToMultimodal(MMI::PointerEvent event, int32_t action)715 void TouchGuider::SendPointerDownEventToMultimodal(MMI::PointerEvent event, int32_t action)
716 {
717 currentPid_ = event.GetPointerId();
718 int32_t xPointDown = 0;
719 int32_t yPointDown = 0;
720 int64_t actionTime = 0;
721
722 if (receivedRecorder_.pointerDownX.find(currentPid_) != receivedRecorder_.pointerDownX.end()) {
723 xPointDown = receivedRecorder_.pointerDownX.find(currentPid_)->second;
724 yPointDown = receivedRecorder_.pointerDownY.find(currentPid_)->second;
725 actionTime = receivedRecorder_.pointerActionTime.find(currentPid_)->second;
726 }
727
728 HILOG_DEBUG("first down point info is: xPos: %{public}d, yPos: %{public}d, actionTime: [%{public}" PRId64 "], "
729 "currentTime: [%{public}" PRId64 "]", xPointDown, yPointDown, actionTime, event.GetActionTime());
730 MMI::PointerEvent::PointerItem pointer = {};
731 event.GetPointerItem(currentPid_, pointer);
732 pointer.SetDisplayX(xPointDown);
733 pointer.SetDisplayY(yPointDown);
734 event.RemovePointerItem(currentPid_);
735 event.AddPointerItem(pointer);
736 event.SetActionTime(actionTime);
737 int32_t removePid = currentPid_ == 0 ? REMOVE_POINTER_ID_1 : 0;
738 event.RemovePointerItem(removePid);
739 SendEventToMultimodal(event, action);
740 }
741
HandleTouchGuidingStateInnerMove(MMI::PointerEvent &event)742 void TouchGuider::HandleTouchGuidingStateInnerMove(MMI::PointerEvent &event)
743 {
744 HILOG_DEBUG();
745
746 switch (event.GetPointerIds().size()) {
747 case POINTER_COUNT_1:
748 if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
749 pointerEvents_.push_back(event);
750 } else if (isTouchGuiding_) {
751 SendEventToMultimodal(event, HOVER_MOVE);
752 } else if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
753 HILOG_DEBUG();
754 if (doubleTapLongPressDownEvent_ != nullptr) {
755 HILOG_DEBUG("doubleTapLongPressDownEvent_ is not null");
756 SendEventToMultimodal(*doubleTapLongPressDownEvent_, NO_CHANGE);
757 doubleTapLongPressDownEvent_ = nullptr;
758 }
759 SendEventToMultimodal(event, NO_CHANGE);
760 } else {
761 HILOG_DEBUG("other case");
762 }
763 break;
764 case POINTER_COUNT_2:
765 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
766 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
767 if (!IsRealMoveState(event)) {
768 HILOG_DEBUG("not a move");
769 break;
770 }
771 if (IsDragGestureAccept(event)) {
772 currentState_ = static_cast<int32_t>(TouchGuideState::DRAGGING);
773 SendPointerDownEventToMultimodal(event, POINTER_DOWN);
774 SendEventToMultimodal(event, NO_CHANGE);
775 } else {
776 for (auto iter = cachedPointerEvents_.begin(); iter != cachedPointerEvents_.end(); ++iter) {
777 EventTransmission::OnPointerEvent(*iter);
778 }
779 cachedPointerEvents_.clear();
780 currentState_ = static_cast<int32_t>(TouchGuideState::PASSING_THROUGH);
781 }
782 break;
783 default:
784 if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
785 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
786 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
787 } else {
788 SendExitEvents();
789 }
790 currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
791 break;
792 }
793 }
794
HandleDraggingStateInnerMove(MMI::PointerEvent &event)795 void TouchGuider::HandleDraggingStateInnerMove(MMI::PointerEvent &event)
796 {
797 HILOG_DEBUG();
798 std::vector<int32_t> pIds = event.GetPointerIds();
799 uint32_t pointCount = pIds.size();
800 if (pointCount == POINTER_COUNT_1) {
801 HILOG_DEBUG("Only two pointers can be received in the dragging state");
802 } else if (pointCount == POINTER_COUNT_2) {
803 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
804 // Get densityPixels from WMS
805 AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
806 auto display = displayMgr.GetDefaultDisplay();
807 float densityPixels = display->GetVirtualPixelRatio();
808 int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * densityPixels);
809 #else
810 HILOG_DEBUG("not support display manager");
811 int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * 1);
812 #endif
813 MMI::PointerEvent::PointerItem pointerF = {};
814 MMI::PointerEvent::PointerItem pointerS = {};
815 event.GetPointerItem(pIds[INDEX_0], pointerF);
816 event.GetPointerItem(pIds[INDEX_1], pointerS);
817 float xPointF = pointerF.GetDisplayX();
818 float xPointS = pointerS.GetDisplayX();
819 float yPointF = pointerF.GetDisplayY();
820 float yPointS = pointerS.GetDisplayY();
821 float offsetX = abs(xPointF - xPointS);
822 float offsetY = abs(yPointF - yPointS);
823 double duration = hypot(offsetX, offsetY);
824 if (duration > miniZoomPointerDistance) {
825 // Adjust this event's location.
826 MMI::PointerEvent::PointerItem pointer = {};
827 event.GetPointerItem(event.GetPointerId(), pointer);
828 pointer.SetDisplayX(pointer.GetDisplayX() + DIVIDE_2(offsetX));
829 pointer.SetDisplayY(pointer.GetDisplayY() + DIVIDE_2(offsetY));
830 event.RemovePointerItem(event.GetPointerId());
831 event.AddPointerItem(pointer);
832 }
833 int32_t removePid = currentPid_ == pIds[0]? pIds[1] : pIds[0];
834 HILOG_DEBUG("removePid when move: (%{public}d)", removePid);
835 event.RemovePointerItem(removePid);
836 SendEventToMultimodal(event, NO_CHANGE);
837 } else {
838 currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
839 SendAllUpEvents(event);
840 }
841 }
842
GetAngleCos(float offsetX, float offsetY, bool isGetX)843 float TouchGuider::GetAngleCos(float offsetX, float offsetY, bool isGetX)
844 {
845 HILOG_DEBUG();
846
847 float ret = isGetX ? offsetX : offsetY;
848 double duration = hypot(offsetX, offsetY);
849 if (duration < - EPSINON || duration > EPSINON) {
850 ret = ret / duration;
851 }
852 return ret;
853 }
854
GetPointOffset(MMI::PointerEvent &event, std::vector<float> &firstPointOffset, std::vector<float> &secondPointOffset) const855 void TouchGuider::GetPointOffset(MMI::PointerEvent &event, std::vector<float> &firstPointOffset,
856 std::vector<float> &secondPointOffset) const
857 {
858 HILOG_DEBUG();
859
860 std::vector<int32_t> pIds = event.GetPointerIds();
861 if (pIds.size() != POINTER_COUNT_2) {
862 return;
863 }
864
865 MMI::PointerEvent::PointerItem pointerF = {};
866 MMI::PointerEvent::PointerItem pointerS = {};
867 if (!event.GetPointerItem(pIds[0], pointerF)) {
868 HILOG_ERROR("GetPointerItem(%{public}d) failed", pIds[0]);
869 return;
870 }
871
872 if (!event.GetPointerItem(pIds[1], pointerS)) {
873 HILOG_ERROR("GetPointerItem(%{public}d) failed", pIds[1]);
874 return;
875 }
876
877 float xPointF = pointerF.GetDisplayX();
878 float xPointS = pointerS.GetDisplayX();
879 float yPointF = pointerF.GetDisplayY();
880 float yPointS = pointerS.GetDisplayY();
881 float xPointDownF = 0;
882 float xPointDownS = 0;
883 float yPointDownF = 0;
884 float yPointDownS = 0;
885 if (receivedRecorder_.pointerDownX.find(INDEX_0) != receivedRecorder_.pointerDownX.end()) {
886 xPointDownF = receivedRecorder_.pointerDownX.find(INDEX_0)->second;
887 yPointDownF = receivedRecorder_.pointerDownY.find(INDEX_0)->second;
888 }
889 if (receivedRecorder_.pointerDownX.find(INDEX_1) != receivedRecorder_.pointerDownX.end()) {
890 xPointDownS = receivedRecorder_.pointerDownX.find(INDEX_1)->second;
891 yPointDownS = receivedRecorder_.pointerDownY.find(INDEX_1)->second;
892 }
893
894 firstPointOffset.push_back(xPointF - xPointDownF); // firstOffsetX
895 firstPointOffset.push_back(yPointF - yPointDownF); // firstOffsetY
896 secondPointOffset.push_back(xPointS - xPointDownS); // secondOffsetX
897 secondPointOffset.push_back(yPointS - yPointDownS); // secondOffsetY
898 }
899
IsDragGestureAccept(MMI::PointerEvent &event)900 bool TouchGuider::IsDragGestureAccept(MMI::PointerEvent &event)
901 {
902 HILOG_DEBUG();
903
904 std::vector<float> firstPointOffset;
905 std::vector<float> secondPointOffset;
906 GetPointOffset(event, firstPointOffset, secondPointOffset);
907 if (firstPointOffset.size() != SCREEN_AXIS_NUM || secondPointOffset.size() != SCREEN_AXIS_NUM) {
908 return false;
909 }
910
911 float firstOffsetX = firstPointOffset[0];
912 float firstOffsetY = firstPointOffset[1];
913 float secondOffsetX = secondPointOffset[0];
914 float secondOffsetY = secondPointOffset[1];
915 if ((!firstOffsetX && !firstOffsetY) ||
916 (!secondOffsetX && !secondOffsetY)) {
917 return true;
918 }
919
920 float firstXCos = GetAngleCos(firstOffsetX, firstOffsetY, true);
921 float firstYCos = GetAngleCos(firstOffsetX, firstOffsetY, false);
922 float secondXCos = GetAngleCos(secondOffsetX, secondOffsetY, true);
923 float secondYCos = GetAngleCos(secondOffsetX, secondOffsetY, false);
924 if ((firstXCos * secondXCos + firstYCos * secondYCos) < MAX_DRAG_GESTURE_COSINE) {
925 return false;
926 }
927 return true;
928 }
929
IsRealMoveState(MMI::PointerEvent &event) const930 bool TouchGuider::IsRealMoveState(MMI::PointerEvent &event) const
931 {
932 HILOG_DEBUG("moveThreshold: %{public}f", multiFingerGestureRecognizer_.GetTouchSlop());
933
934 std::vector<float> firstPointOffset;
935 std::vector<float> secondPointOffset;
936 GetPointOffset(event, firstPointOffset, secondPointOffset);
937 if (firstPointOffset.size() != SCREEN_AXIS_NUM || secondPointOffset.size() != SCREEN_AXIS_NUM) {
938 return false;
939 }
940
941 HILOG_DEBUG("offset of fisrt down points and current points: %{public}f, %{public}f,%{public}f, %{public}f",
942 firstPointOffset[0], firstPointOffset[1], secondPointOffset[0], secondPointOffset[1]);
943 if (hypot(firstPointOffset[0], firstPointOffset[1]) >= multiFingerGestureRecognizer_.GetTouchSlop() &&
944 hypot(secondPointOffset[0], secondPointOffset[1]) >= multiFingerGestureRecognizer_.GetTouchSlop()) {
945 return true;
946 }
947 return false;
948 }
949
RecordInjectedEvent(MMI::PointerEvent &event)950 void TouchGuider::RecordInjectedEvent(MMI::PointerEvent &event)
951 {
952 HILOG_DEBUG();
953
954 int32_t pointerId = event.GetPointerId();
955 switch (event.GetPointerAction()) {
956 case MMI::PointerEvent::POINTER_ACTION_DOWN:
957 injectedRecorder_.downPointerNum++;
958 injectedRecorder_.downPointers.insert(pointerId);
959 injectedRecorder_.lastDownTime = event.GetActionTime() / US_TO_MS;
960 break;
961 case MMI::PointerEvent::POINTER_ACTION_UP:
962 injectedRecorder_.downPointers.erase(pointerId);
963 if (injectedRecorder_.downPointerNum > 0) {
964 injectedRecorder_.downPointerNum--;
965 }
966 if (injectedRecorder_.downPointers.empty()) {
967 injectedRecorder_.lastDownTime = 0;
968 }
969 break;
970 case MMI::PointerEvent::POINTER_ACTION_MOVE:
971 injectedRecorder_.lastHoverEvent = std::make_shared<MMI::PointerEvent>(event);
972 break;
973 default:
974 break;
975 }
976 }
977
RecordReceivedEvent(MMI::PointerEvent &event)978 void TouchGuider::RecordReceivedEvent(MMI::PointerEvent &event)
979 {
980 HILOG_DEBUG();
981
982 int32_t pointId = event.GetPointerId();
983 MMI::PointerEvent::PointerItem pointer;
984 if (!event.GetPointerItem(pointId, pointer)) {
985 HILOG_ERROR("GetPointerItem(%{public}d) failed", pointId);
986 }
987 receivedRecorder_.lastEvent = std::make_shared<MMI::PointerEvent>(event);
988 switch (event.GetPointerAction()) {
989 case MMI::PointerEvent::POINTER_ACTION_DOWN:
990 receivedRecorder_.pointerDownX[pointId] = pointer.GetDisplayX();
991 receivedRecorder_.pointerDownY[pointId] = pointer.GetDisplayY();
992 receivedRecorder_.pointerActionTime[pointId] = event.GetActionTime();
993 break;
994 case MMI::PointerEvent::POINTER_ACTION_UP:
995 receivedRecorder_.pointerDownX.erase(pointId);
996 receivedRecorder_.pointerDownY.erase(pointId);
997 receivedRecorder_.pointerActionTime.erase(pointId);
998 break;
999 default:
1000 break;
1001 }
1002 }
1003
ClearReceivedEventRecorder()1004 void TouchGuider::ClearReceivedEventRecorder()
1005 {
1006 HILOG_DEBUG();
1007
1008 receivedRecorder_.pointerDownX.clear();
1009 receivedRecorder_.pointerDownY.clear();
1010 receivedRecorder_.pointerActionTime.clear();
1011 receivedRecorder_.lastEvent = nullptr;
1012 }
1013
ClearInjectedEventRecorder()1014 void TouchGuider::ClearInjectedEventRecorder()
1015 {
1016 HILOG_DEBUG();
1017
1018 injectedRecorder_.downPointerNum = 0;
1019 injectedRecorder_.downPointers.clear();
1020 injectedRecorder_.lastHoverEvent = nullptr;
1021 }
1022
SendAllDownEvents(MMI::PointerEvent &event)1023 void TouchGuider::SendAllDownEvents(MMI::PointerEvent &event)
1024 {
1025 HILOG_DEBUG();
1026
1027 std::vector<int32_t> pIds = event.GetPointerIds();
1028 for (auto& pId : pIds) {
1029 if (injectedRecorder_.downPointers.find(pId) == injectedRecorder_.downPointers.end()) {
1030 event.SetPointerId(pId);
1031 SendEventToMultimodal(event, POINTER_DOWN);
1032 }
1033 }
1034 }
1035
SendAllUpEvents(MMI::PointerEvent &event)1036 void TouchGuider::SendAllUpEvents(MMI::PointerEvent &event)
1037 {
1038 HILOG_DEBUG();
1039
1040 std::vector<int32_t> pIds = event.GetPointerIds();
1041 for (auto& pId : pIds) {
1042 event.SetPointerId(pId);
1043 SendEventToMultimodal(event, POINTER_UP);
1044 }
1045 }
1046
SendUpForAllInjectedEvent(MMI::PointerEvent &event)1047 void TouchGuider::SendUpForAllInjectedEvent(MMI::PointerEvent &event)
1048 {
1049 HILOG_DEBUG();
1050
1051 std::vector<int32_t> pIds = event.GetPointerIds();
1052 for (const auto& pId : pIds) {
1053 if (injectedRecorder_.downPointers.find(pId) == injectedRecorder_.downPointers.end()) {
1054 continue;
1055 }
1056 SendEventToMultimodal(event, POINTER_UP);
1057 }
1058 }
1059
PostGestureRecognizeExit()1060 void TouchGuider::PostGestureRecognizeExit()
1061 {
1062 HILOG_DEBUG();
1063
1064 handler_->SendEvent(EXIT_GESTURE_REC_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
1065 }
1066
PostHoverEnterAndMove(MMI::PointerEvent &event)1067 void TouchGuider::PostHoverEnterAndMove(MMI::PointerEvent &event)
1068 {
1069 HILOG_DEBUG();
1070
1071 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
1072 pointerEvents_.push_back(event);
1073 handler_->SendEvent(SEND_HOVER_ENTER_MOVE_MSG, 0, DOUBLE_TAP_TIMEOUT / US_TO_MS);
1074 }
1075
PostHoverExit()1076 void TouchGuider::PostHoverExit()
1077 {
1078 HILOG_DEBUG();
1079
1080 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
1081 handler_->SendEvent(SEND_HOVER_EXIT_MSG, 0, DOUBLE_TAP_TIMEOUT / US_TO_MS);
1082 }
1083
PostAccessibilityEvent(uint32_t innerEventID)1084 void TouchGuider::PostAccessibilityEvent(uint32_t innerEventID)
1085 {
1086 HILOG_DEBUG();
1087
1088 handler_->SendEvent(innerEventID, 0, EXIT_GESTURE_REC_TIMEOUT);
1089 }
1090
CancelPostEvent(uint32_t innerEventID)1091 void TouchGuider::CancelPostEvent(uint32_t innerEventID)
1092 {
1093 HILOG_DEBUG();
1094
1095 handler_->RemoveEvent(innerEventID);
1096 }
1097
CancelPostEventIfNeed(uint32_t innerEventID)1098 void TouchGuider::CancelPostEventIfNeed(uint32_t innerEventID)
1099 {
1100 HILOG_DEBUG();
1101
1102 if (HasEventPending(innerEventID)) {
1103 handler_->RemoveEvent(innerEventID);
1104 if (innerEventID == SEND_HOVER_ENTER_MOVE_MSG) {
1105 pointerEvents_.clear();
1106 }
1107 }
1108 }
1109
HasEventPending(uint32_t innerEventID)1110 bool TouchGuider::HasEventPending(uint32_t innerEventID)
1111 {
1112 HILOG_DEBUG();
1113
1114 return handler_->HasInnerEvent(innerEventID);
1115 }
1116
ForceSendAndRemoveEvent(uint32_t innerEventID, MMI::PointerEvent &event)1117 void TouchGuider::ForceSendAndRemoveEvent(uint32_t innerEventID, MMI::PointerEvent &event)
1118 {
1119 HILOG_DEBUG();
1120
1121 if (!HasEventPending(innerEventID)) {
1122 HILOG_DEBUG("No pending event.");
1123 return;
1124 }
1125
1126 switch (innerEventID) {
1127 case SEND_HOVER_ENTER_MOVE_MSG:
1128 SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
1129 if (pointerEvents_.empty()) {
1130 break;
1131 }
1132 for (auto iter = pointerEvents_.begin(); iter != pointerEvents_.end(); ++iter) {
1133 if (iter->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
1134 SendEventToMultimodal(*iter, HOVER_ENTER);
1135 } else {
1136 SendEventToMultimodal(*iter, HOVER_MOVE);
1137 }
1138 }
1139 pointerEvents_.clear();
1140 break;
1141 case SEND_TOUCH_GUIDE_END_MSG:
1142 SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_END);
1143 break;
1144 default:
1145 break;
1146 }
1147 CancelPostEvent(innerEventID);
1148 }
1149
IgnoreRepeatExecuteAction()1150 bool TouchGuider::IgnoreRepeatExecuteAction()
1151 {
1152 HILOG_DEBUG();
1153 int64_t time = Utils::GetSystemTime();
1154 if (time - lastDoubleTapTime < IGNORE_REPEAT_EXECUTE_INTERVAL) {
1155 HILOG_DEBUG("time interval < 300ms");
1156 lastDoubleTapTime = time;
1157 return true;
1158 }
1159
1160 lastDoubleTapTime = time;
1161 return false;
1162 }
1163
ExecuteActionOnAccessibilityFocused(const ActionType &action)1164 bool TouchGuider::ExecuteActionOnAccessibilityFocused(const ActionType &action)
1165 {
1166 HILOG_DEBUG();
1167 if (IgnoreRepeatExecuteAction()) {
1168 return true;
1169 }
1170 return Singleton<AccessibleAbilityManagerService>::GetInstance().ExecuteActionOnAccessibilityFocused(action);
1171 }
1172
FindFocusedElement(AccessibilityElementInfo &elementInfo)1173 bool TouchGuider::FindFocusedElement(AccessibilityElementInfo &elementInfo)
1174 {
1175 HILOG_DEBUG();
1176 return Singleton<AccessibleAbilityManagerService>::GetInstance().FindFocusedElement(elementInfo);
1177 }
1178
HoverEnterAndMoveRunner()1179 void TGEventHandler::HoverEnterAndMoveRunner()
1180 {
1181 HILOG_DEBUG();
1182
1183 std::list<MMI::PointerEvent> motionEvent = tgServer_.getHoverEnterAndMoveEvent();
1184 tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
1185 if (!motionEvent.empty()) {
1186 for (auto iter = motionEvent.begin(); iter != motionEvent.end(); ++iter) {
1187 if (iter->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
1188 tgServer_.SendEventToMultimodal(*iter, HOVER_ENTER);
1189 } else {
1190 tgServer_.SendEventToMultimodal(*iter, HOVER_MOVE);
1191 }
1192 }
1193 }
1194 tgServer_.ClearHoverEnterAndMoveEvent();
1195 }
1196
HoverExitRunner()1197 void TGEventHandler::HoverExitRunner()
1198 {
1199 HILOG_DEBUG();
1200
1201 std::shared_ptr<MMI::PointerEvent> pEvent = tgServer_.getLastReceivedEvent();
1202 tgServer_.SendEventToMultimodal(*pEvent, HOVER_EXIT);
1203 if (!HasInnerEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG)) {
1204 RemoveEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG);
1205 SendEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
1206 }
1207 }
1208 } // namespace Accessibility
1209 } // namespace OHOS