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().activeWindowId_;
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().activeWindowId_;
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             if (IsTouchInteractionEnd()) {
482                 currentState_ = static_cast<int32_t>(TouchGuideState::PASSING_THROUGH);
483             } else {
484                 HandleTouchGuidingStateInnerMove(event);
485             }
486             break;
487         case MMI::PointerEvent::POINTER_ACTION_UP:
488             if (event.GetPointerIds().size() == POINTER_COUNT_1 && !IsTouchInteractionEnd() &&
489                 !multiFingerGestureRecognizer_.IsMultiFingerRecognize()) {
490                 if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
491                     HILOG_DEBUG();
492                     SendEventToMultimodal(event, NO_CHANGE);
493                     Clear(event);
494                     break;
495                 }
496                 OnTouchInteractionEnd();
497                 if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
498                     PostHoverExit();
499                 } else if (isTouchGuiding_) {
500                     SendExitEvents();
501                     PostHoverExit();
502                 }
503             }
504             break;
505         case MMI::PointerEvent::POINTER_ACTION_PULL_MOVE:
506             SendEventToMultimodal(event, NO_CHANGE);
507             break;
508         case MMI::PointerEvent::POINTER_ACTION_PULL_UP:
509             SendEventToMultimodal(event, NO_CHANGE);
510             break;
511         default:
512             break;
513     }
514 }
515 
HandleDraggingState(MMI::PointerEvent & event)516 void TouchGuider::HandleDraggingState(MMI::PointerEvent &event)
517 {
518     HILOG_DEBUG();
519     std::vector<int32_t> pIds = event.GetPointerIds();
520     switch (event.GetPointerAction()) {
521         case MMI::PointerEvent::POINTER_ACTION_DOWN:
522             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
523                 Clear(event);
524             } else {
525                 currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
526                 SendAllUpEvents(event);
527             }
528             break;
529         case MMI::PointerEvent::POINTER_ACTION_MOVE:
530             if (event.GetPointerId() == currentPid_) {
531                 HandleDraggingStateInnerMove(event);
532             }
533             break;
534         case MMI::PointerEvent::POINTER_ACTION_UP:
535             if (pIds.size() == POINTER_COUNT_1) {
536                 if (event.GetPointerId() == currentPid_) {
537                     HILOG_DEBUG("single currentPid_ move: %{public}d", event.GetPointerId());
538                     OnTouchInteractionEnd();
539                     SendEventToMultimodal(event, NO_CHANGE);
540                     currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
541                 }
542             } else {
543                 if (event.GetPointerId() == currentPid_ && pIds.size() == POINTER_COUNT_2) {
544                     HILOG_DEBUG("double currentPid_ move: %{public}d", event.GetPointerId());
545                     int32_t removePid = currentPid_ == pIds[0]? pIds[1] : pIds[0];
546                     event.RemovePointerItem(removePid);
547                     OnTouchInteractionEnd();
548                     SendEventToMultimodal(event, NO_CHANGE);
549                     currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
550                 }
551             }
552 
553             break;
554         default:
555             break;
556     }
557 }
558 
HandleTransmitingState(MMI::PointerEvent & event)559 void TouchGuider::HandleTransmitingState(MMI::PointerEvent &event)
560 {
561     HILOG_DEBUG();
562 
563     switch (event.GetPointerAction()) {
564         case MMI::PointerEvent::POINTER_ACTION_DOWN:
565             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
566                 Clear(event);
567             }
568             break;
569         case MMI::PointerEvent::POINTER_ACTION_UP:
570             if (event.GetPointerIds().size() == POINTER_COUNT_1 && !IsTouchInteractionEnd() &&
571                 !multiFingerGestureRecognizer_.IsMultiFingerRecognize()) {
572                 if (longPressPointId_ >= 0) {
573                     // Adjust this event's location.
574                     MMI::PointerEvent::PointerItem pointer = {};
575                     event.GetPointerItem(event.GetPointerId(), pointer);
576                     pointer.SetDisplayX(pointer.GetDisplayX() + longPressOffsetX_);
577                     pointer.SetDisplayY(pointer.GetDisplayY() + longPressOffsetY_);
578                     event.RemovePointerItem(event.GetPointerId());
579                     event.AddPointerItem(pointer);
580                     longPressPointId_ = INIT_POINT_ID;
581                     longPressOffsetX_ = INIT_MMIPOINT;
582                     longPressOffsetY_ = INIT_MMIPOINT;
583                 }
584                 SendEventToMultimodal(event, NO_CHANGE);
585                 OnTouchInteractionEnd();
586                 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
587             }
588             break;
589         default:
590             MMI::PointerEvent::PointerItem pointerItem = {};
591             for (auto& pid : event.GetPointerIds()) {
592                 event.GetPointerItem(pid, pointerItem);
593                 pointerItem.SetPressed(false);
594                 event.RemovePointerItem(pid);
595                 event.AddPointerItem(pointerItem);
596             }
597             SendEventToMultimodal(event, NO_CHANGE);
598             break;
599     }
600 }
601 
HandlePassingThroughState(MMI::PointerEvent & event)602 void TouchGuider::HandlePassingThroughState(MMI::PointerEvent &event)
603 {
604     HILOG_DEBUG();
605 
606     if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP &&
607         event.GetPointerIds().size() == POINTER_COUNT_1) {
608         SendEventToMultimodal(event, NO_CHANGE);
609         OnTouchInteractionEnd();
610         currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
611         return;
612     }
613 
614     SendEventToMultimodal(event, NO_CHANGE);
615     return;
616 }
617 
Clear(MMI::PointerEvent & event)618 void TouchGuider::Clear(MMI::PointerEvent &event)
619 {
620     HILOG_DEBUG();
621 
622     if (currentState_ == static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING)) {
623         SendExitEvents();
624     } else if (currentState_ == static_cast<int32_t>(TouchGuideState::DRAGGING) ||
625         currentState_ == static_cast<int32_t>(TouchGuideState::TRANSMITTING)) {
626         SendUpForAllInjectedEvent(event);
627     }
628 
629     CancelPostEvent(EXIT_GESTURE_REC_MSG);
630     CancelPostEvent(SEND_TOUCH_GUIDE_END_MSG);
631     CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
632     CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
633     ClearInjectedEventRecorder();
634     ClearReceivedEventRecorder();
635     pointerEvents_.clear();
636     currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
637     isTouchGuiding_ = false;
638     gestureRecognizer_.Clear();
639     longPressPointId_ = INIT_POINT_ID;
640     longPressOffsetX_ = INIT_MMIPOINT;
641     longPressOffsetY_ = INIT_MMIPOINT;
642     leftTopX_ = INIT_POINT_DISPLAY;
643     leftTopY_ = INIT_POINT_DISPLAY;
644     rightBottomX_ = INIT_POINT_DISPLAY;
645     rightBottomY_ = INIT_POINT_DISPLAY;
646     focusedElementExist_ = false;
647     currentPid_ = -1;
648     cachedPointerEvents_.clear();
649     OnTouchInteractionEnd();
650 }
651 
Clear()652 void TouchGuider::Clear()
653 {
654     HILOG_DEBUG();
655 
656     std::shared_ptr<MMI::PointerEvent> event = getLastReceivedEvent();
657     if (event) {
658         Clear(*event);
659     }
660 }
661 
SendExitEvents()662 void TouchGuider::SendExitEvents()
663 {
664     HILOG_DEBUG();
665 
666     if (!HasEventPending(SEND_TOUCH_GUIDE_END_MSG)) {
667         PostAccessibilityEvent(SEND_TOUCH_GUIDE_END_MSG);
668     }
669 }
670 
HandleTouchGuidingStateInnerDown(MMI::PointerEvent & event)671 void TouchGuider::HandleTouchGuidingStateInnerDown(MMI::PointerEvent &event)
672 {
673     HILOG_DEBUG();
674 
675     OnTouchInteractionStart();
676     CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
677     CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
678     if (isTouchGuiding_) {
679         SendExitEvents();
680     }
681     if (!gestureRecognizer_.IsfirstTap() && !multiFingerGestureRecognizer_.IsMultiFingerGestureStarted()) {
682         ForceSendAndRemoveEvent(SEND_TOUCH_GUIDE_END_MSG, event);
683         if (!isTouchGuiding_) {
684             if (!HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
685                 PostHoverEnterAndMove(event);
686             } else {
687                 pointerEvents_.push_back(event);
688             }
689         }
690     } else if (gestureRecognizer_.GetIsDoubleTap() && !multiFingerGestureRecognizer_.IsMultiFingerGestureStarted()) {
691         doubleTapLongPressDownEvent_ = nullptr;
692 
693         AccessibilityElementInfo focusedElementInfo = {};
694         if (!FindFocusedElement(focusedElementInfo)) {
695             HILOG_ERROR("FindFocusedElement failed.");
696             return;
697         }
698         HILOG_DEBUG("FindFocusedElement success");
699         MMI::PointerEvent::PointerItem pointerIterm = {};
700         if (!event.GetPointerItem(event.GetPointerId(), pointerIterm)) {
701             HILOG_ERROR("event.GetPointerItem failed");
702             return;
703         }
704         HILOG_DEBUG("GetPointerItem success");
705         focusedElementExist_ = true;
706 
707         // set point x,y range and offset
708         leftTopX_ = focusedElementInfo.GetRectInScreen().GetLeftTopXScreenPostion();
709         leftTopY_ = focusedElementInfo.GetRectInScreen().GetLeftTopYScreenPostion();
710         rightBottomX_ = focusedElementInfo.GetRectInScreen().GetRightBottomXScreenPostion();
711         rightBottomY_ = focusedElementInfo.GetRectInScreen().GetRightBottomYScreenPostion();
712         longPressOffsetX_ = static_cast<float>(DIVIDE_2(leftTopX_ + rightBottomX_) - pointerIterm.GetDisplayX());
713         longPressOffsetY_ = static_cast<float>(DIVIDE_2(leftTopY_ + rightBottomY_) - pointerIterm.GetDisplayY());
714 
715         doubleTapLongPressDownEvent_ = std::make_shared<MMI::PointerEvent>(event);
716     }
717 }
718 
SendPointerDownEventToMultimodal(MMI::PointerEvent event,int32_t action)719 void TouchGuider::SendPointerDownEventToMultimodal(MMI::PointerEvent event, int32_t action)
720 {
721     currentPid_ = event.GetPointerId();
722     int32_t xPointDown = 0;
723     int32_t yPointDown = 0;
724     int64_t actionTime = 0;
725 
726     if (receivedRecorder_.pointerDownX.find(currentPid_) != receivedRecorder_.pointerDownX.end()) {
727         xPointDown = receivedRecorder_.pointerDownX.find(currentPid_)->second;
728         yPointDown = receivedRecorder_.pointerDownY.find(currentPid_)->second;
729         actionTime = receivedRecorder_.pointerActionTime.find(currentPid_)->second;
730     }
731 
732     HILOG_DEBUG("first down point info is: xPos: %{public}d, yPos: %{public}d, actionTime: [%{public}" PRId64 "], "
733         "currentTime: [%{public}" PRId64 "]", xPointDown, yPointDown, actionTime, event.GetActionTime());
734     MMI::PointerEvent::PointerItem pointer = {};
735     event.GetPointerItem(currentPid_, pointer);
736     pointer.SetDisplayX(xPointDown);
737     pointer.SetDisplayY(yPointDown);
738     event.RemovePointerItem(currentPid_);
739     event.AddPointerItem(pointer);
740     event.SetActionTime(actionTime);
741     int32_t removePid = currentPid_ == 0 ? REMOVE_POINTER_ID_1 : 0;
742     event.RemovePointerItem(removePid);
743     SendEventToMultimodal(event, action);
744 }
745 
HandleTouchGuidingStateInnerMove(MMI::PointerEvent & event)746 void TouchGuider::HandleTouchGuidingStateInnerMove(MMI::PointerEvent &event)
747 {
748     HILOG_DEBUG();
749 
750     switch (event.GetPointerIds().size()) {
751         case POINTER_COUNT_1:
752             if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
753                 pointerEvents_.push_back(event);
754             } else if (isTouchGuiding_) {
755                 SendEventToMultimodal(event, HOVER_MOVE);
756             } else if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
757                 HILOG_DEBUG();
758                 if (doubleTapLongPressDownEvent_ != nullptr) {
759                     HILOG_DEBUG("doubleTapLongPressDownEvent_ is not null");
760                     SendEventToMultimodal(*doubleTapLongPressDownEvent_, NO_CHANGE);
761                     doubleTapLongPressDownEvent_ = nullptr;
762                 }
763                 SendEventToMultimodal(event, NO_CHANGE);
764             } else {
765                 HILOG_DEBUG("other case");
766             }
767             break;
768         case POINTER_COUNT_2:
769             CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
770             CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
771             if (!IsRealMoveState(event)) {
772                 HILOG_DEBUG("not a move");
773                 break;
774             }
775             if (IsDragGestureAccept(event)) {
776                 currentState_ = static_cast<int32_t>(TouchGuideState::DRAGGING);
777                 SendPointerDownEventToMultimodal(event, POINTER_DOWN);
778                 SendEventToMultimodal(event, NO_CHANGE);
779             } else {
780                 for (auto iter = cachedPointerEvents_.begin(); iter != cachedPointerEvents_.end(); ++iter) {
781                     EventTransmission::OnPointerEvent(*iter);
782                 }
783                 cachedPointerEvents_.clear();
784                 currentState_ = static_cast<int32_t>(TouchGuideState::PASSING_THROUGH);
785             }
786             break;
787         default:
788             if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
789                 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
790                 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
791             } else {
792                 SendExitEvents();
793             }
794             currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
795             break;
796     }
797 }
798 
HandleDraggingStateInnerMove(MMI::PointerEvent & event)799 void TouchGuider::HandleDraggingStateInnerMove(MMI::PointerEvent &event)
800 {
801     HILOG_DEBUG();
802     std::vector<int32_t> pIds = event.GetPointerIds();
803     int32_t pointCount = pIds.size();
804     if (pointCount == POINTER_COUNT_1) {
805         HILOG_DEBUG("Only two pointers can be received in the dragging state");
806     } else if (pointCount == POINTER_COUNT_2) {
807 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
808         // Get densityPixels from WMS
809         AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
810         auto display = displayMgr.GetDefaultDisplay();
811         float densityPixels = display->GetVirtualPixelRatio();
812         int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * densityPixels);
813 #else
814         HILOG_DEBUG("not support display manager");
815         int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * 1);
816 #endif
817         MMI::PointerEvent::PointerItem pointerF = {};
818         MMI::PointerEvent::PointerItem pointerS = {};
819         event.GetPointerItem(pIds[INDEX_0], pointerF);
820         event.GetPointerItem(pIds[INDEX_1], pointerS);
821         float xPointF = pointerF.GetDisplayX();
822         float xPointS = pointerS.GetDisplayX();
823         float yPointF = pointerF.GetDisplayY();
824         float yPointS = pointerS.GetDisplayY();
825         float offsetX = abs(xPointF - xPointS);
826         float offsetY = abs(yPointF - yPointS);
827         double duration = hypot(offsetX, offsetY);
828         if (duration > miniZoomPointerDistance) {
829             // Adjust this event's location.
830             MMI::PointerEvent::PointerItem pointer = {};
831             event.GetPointerItem(event.GetPointerId(), pointer);
832             pointer.SetDisplayX(pointer.GetDisplayX() + DIVIDE_2(offsetX));
833             pointer.SetDisplayY(pointer.GetDisplayY() + DIVIDE_2(offsetY));
834             event.RemovePointerItem(event.GetPointerId());
835             event.AddPointerItem(pointer);
836         }
837         int32_t removePid = currentPid_ == pIds[0]? pIds[1] : pIds[0];
838         HILOG_DEBUG("removePid when move: (%{public}d)", removePid);
839         event.RemovePointerItem(removePid);
840         SendEventToMultimodal(event, NO_CHANGE);
841     } else {
842         currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
843         SendAllUpEvents(event);
844     }
845 }
846 
GetAngleCos(float offsetX,float offsetY,bool isGetX)847 float TouchGuider::GetAngleCos(float offsetX, float offsetY, bool isGetX)
848 {
849     HILOG_DEBUG();
850 
851     float ret = isGetX ? offsetX : offsetY;
852     double duration = hypot(offsetX, offsetY);
853     if (duration < - EPSINON || duration > EPSINON) {
854         ret = ret / duration;
855     }
856     return ret;
857 }
858 
GetPointOffset(MMI::PointerEvent & event,std::vector<float> & firstPointOffset,std::vector<float> & secondPointOffset) const859 void TouchGuider::GetPointOffset(MMI::PointerEvent &event, std::vector<float> &firstPointOffset,
860     std::vector<float> &secondPointOffset) const
861 {
862     HILOG_DEBUG();
863 
864     std::vector<int32_t> pIds = event.GetPointerIds();
865     if (pIds.size() != POINTER_COUNT_2) {
866         return;
867     }
868 
869     MMI::PointerEvent::PointerItem pointerF = {};
870     MMI::PointerEvent::PointerItem pointerS = {};
871     if (!event.GetPointerItem(pIds[0], pointerF)) {
872         HILOG_ERROR("GetPointerItem(%{public}d) failed", pIds[0]);
873         return;
874     }
875 
876     if (!event.GetPointerItem(pIds[1], pointerS)) {
877         HILOG_ERROR("GetPointerItem(%{public}d) failed", pIds[1]);
878         return;
879     }
880 
881     float xPointF = pointerF.GetDisplayX();
882     float xPointS = pointerS.GetDisplayX();
883     float yPointF = pointerF.GetDisplayY();
884     float yPointS = pointerS.GetDisplayY();
885     float xPointDownF = 0;
886     float xPointDownS = 0;
887     float yPointDownF = 0;
888     float yPointDownS = 0;
889     if (receivedRecorder_.pointerDownX.find(INDEX_0) != receivedRecorder_.pointerDownX.end()) {
890         xPointDownF = receivedRecorder_.pointerDownX.find(INDEX_0)->second;
891         yPointDownF = receivedRecorder_.pointerDownY.find(INDEX_0)->second;
892     }
893     if (receivedRecorder_.pointerDownX.find(INDEX_1) != receivedRecorder_.pointerDownX.end()) {
894         xPointDownS = receivedRecorder_.pointerDownX.find(INDEX_1)->second;
895         yPointDownS = receivedRecorder_.pointerDownY.find(INDEX_1)->second;
896     }
897 
898     firstPointOffset.push_back(xPointF - xPointDownF); // firstOffsetX
899     firstPointOffset.push_back(yPointF - yPointDownF); // firstOffsetY
900     secondPointOffset.push_back(xPointS - xPointDownS); // secondOffsetX
901     secondPointOffset.push_back(yPointS - yPointDownS); // secondOffsetY
902 }
903 
IsDragGestureAccept(MMI::PointerEvent & event)904 bool TouchGuider::IsDragGestureAccept(MMI::PointerEvent &event)
905 {
906     HILOG_DEBUG();
907 
908     std::vector<float> firstPointOffset;
909     std::vector<float> secondPointOffset;
910     GetPointOffset(event, firstPointOffset, secondPointOffset);
911     if (firstPointOffset.size() != SCREEN_AXIS_NUM || secondPointOffset.size() != SCREEN_AXIS_NUM) {
912         return false;
913     }
914 
915     float firstOffsetX = firstPointOffset[0];
916     float firstOffsetY = firstPointOffset[1];
917     float secondOffsetX = secondPointOffset[0];
918     float secondOffsetY = secondPointOffset[1];
919     if ((!firstOffsetX && !firstOffsetY) ||
920         (!secondOffsetX && !secondOffsetY)) {
921         return true;
922     }
923 
924     float firstXCos = GetAngleCos(firstOffsetX, firstOffsetY, true);
925     float firstYCos = GetAngleCos(firstOffsetX, firstOffsetY, false);
926     float secondXCos = GetAngleCos(secondOffsetX, secondOffsetY, true);
927     float secondYCos = GetAngleCos(secondOffsetX, secondOffsetY, false);
928     if ((firstXCos * secondXCos + firstYCos * secondYCos) < MAX_DRAG_GESTURE_COSINE) {
929         return false;
930     }
931     return true;
932 }
933 
IsRealMoveState(MMI::PointerEvent & event) const934 bool TouchGuider::IsRealMoveState(MMI::PointerEvent &event) const
935 {
936     HILOG_DEBUG("moveThreshold: %{public}f", multiFingerGestureRecognizer_.GetTouchSlop());
937 
938     std::vector<float> firstPointOffset;
939     std::vector<float> secondPointOffset;
940     GetPointOffset(event, firstPointOffset, secondPointOffset);
941     if (firstPointOffset.size() != SCREEN_AXIS_NUM || secondPointOffset.size() != SCREEN_AXIS_NUM) {
942         return false;
943     }
944 
945     HILOG_DEBUG("offset of fisrt down points and current points: %{public}f, %{public}f,%{public}f, %{public}f",
946         firstPointOffset[0], firstPointOffset[1], secondPointOffset[0], secondPointOffset[1]);
947     if (hypot(firstPointOffset[0], firstPointOffset[1]) >= multiFingerGestureRecognizer_.GetTouchSlop() &&
948         hypot(secondPointOffset[0], secondPointOffset[1]) >= multiFingerGestureRecognizer_.GetTouchSlop()) {
949         return true;
950     }
951     return false;
952 }
953 
RecordInjectedEvent(MMI::PointerEvent & event)954 void TouchGuider::RecordInjectedEvent(MMI::PointerEvent &event)
955 {
956     HILOG_DEBUG();
957 
958     int32_t pointerId = event.GetPointerId();
959     switch (event.GetPointerAction()) {
960         case MMI::PointerEvent::POINTER_ACTION_DOWN:
961             injectedRecorder_.downPointerNum++;
962             injectedRecorder_.downPointers.insert(pointerId);
963             injectedRecorder_.lastDownTime = event.GetActionTime() / US_TO_MS;
964             break;
965         case MMI::PointerEvent::POINTER_ACTION_UP:
966             injectedRecorder_.downPointers.erase(pointerId);
967             if (injectedRecorder_.downPointerNum > 0) {
968                 injectedRecorder_.downPointerNum--;
969             }
970             if (injectedRecorder_.downPointers.empty()) {
971                 injectedRecorder_.lastDownTime = 0;
972             }
973             break;
974         case MMI::PointerEvent::POINTER_ACTION_MOVE:
975             injectedRecorder_.lastHoverEvent = std::make_shared<MMI::PointerEvent>(event);
976             break;
977         default:
978             break;
979     }
980 }
981 
RecordReceivedEvent(MMI::PointerEvent & event)982 void TouchGuider::RecordReceivedEvent(MMI::PointerEvent &event)
983 {
984     HILOG_DEBUG();
985 
986     int32_t pointId = event.GetPointerId();
987     MMI::PointerEvent::PointerItem pointer;
988     if (!event.GetPointerItem(pointId, pointer)) {
989         HILOG_ERROR("GetPointerItem(%{public}d) failed", pointId);
990     }
991     receivedRecorder_.lastEvent = std::make_shared<MMI::PointerEvent>(event);
992     switch (event.GetPointerAction()) {
993         case MMI::PointerEvent::POINTER_ACTION_DOWN:
994             receivedRecorder_.pointerDownX[pointId] = pointer.GetDisplayX();
995             receivedRecorder_.pointerDownY[pointId] = pointer.GetDisplayY();
996             receivedRecorder_.pointerActionTime[pointId] = event.GetActionTime();
997             break;
998         case MMI::PointerEvent::POINTER_ACTION_UP:
999             receivedRecorder_.pointerDownX.erase(pointId);
1000             receivedRecorder_.pointerDownY.erase(pointId);
1001             receivedRecorder_.pointerActionTime.erase(pointId);
1002             break;
1003         default:
1004             break;
1005     }
1006 }
1007 
ClearReceivedEventRecorder()1008 void TouchGuider::ClearReceivedEventRecorder()
1009 {
1010     HILOG_DEBUG();
1011 
1012     receivedRecorder_.pointerDownX.clear();
1013     receivedRecorder_.pointerDownY.clear();
1014     receivedRecorder_.pointerActionTime.clear();
1015     receivedRecorder_.lastEvent = nullptr;
1016 }
1017 
ClearInjectedEventRecorder()1018 void TouchGuider::ClearInjectedEventRecorder()
1019 {
1020     HILOG_DEBUG();
1021 
1022     injectedRecorder_.downPointerNum = 0;
1023     injectedRecorder_.downPointers.clear();
1024     injectedRecorder_.lastHoverEvent = nullptr;
1025 }
1026 
SendAllDownEvents(MMI::PointerEvent & event)1027 void TouchGuider::SendAllDownEvents(MMI::PointerEvent &event)
1028 {
1029     HILOG_DEBUG();
1030 
1031     std::vector<int32_t> pIds = event.GetPointerIds();
1032     for (auto& pId : pIds) {
1033         if (injectedRecorder_.downPointers.find(pId) == injectedRecorder_.downPointers.end()) {
1034             event.SetPointerId(pId);
1035             SendEventToMultimodal(event, POINTER_DOWN);
1036         }
1037     }
1038 }
1039 
SendAllUpEvents(MMI::PointerEvent & event)1040 void TouchGuider::SendAllUpEvents(MMI::PointerEvent &event)
1041 {
1042     HILOG_DEBUG();
1043 
1044     std::vector<int32_t> pIds = event.GetPointerIds();
1045     for (auto& pId : pIds) {
1046         event.SetPointerId(pId);
1047         SendEventToMultimodal(event, POINTER_UP);
1048     }
1049 }
1050 
SendUpForAllInjectedEvent(MMI::PointerEvent & event)1051 void TouchGuider::SendUpForAllInjectedEvent(MMI::PointerEvent &event)
1052 {
1053     HILOG_DEBUG();
1054 
1055     std::vector<int32_t> pIds = event.GetPointerIds();
1056     for (const auto& pId : pIds) {
1057         if (injectedRecorder_.downPointers.find(pId) == injectedRecorder_.downPointers.end()) {
1058             continue;
1059         }
1060         SendEventToMultimodal(event, POINTER_UP);
1061     }
1062 }
1063 
PostGestureRecognizeExit()1064 void TouchGuider::PostGestureRecognizeExit()
1065 {
1066     HILOG_DEBUG();
1067 
1068     handler_->SendEvent(EXIT_GESTURE_REC_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
1069 }
1070 
PostHoverEnterAndMove(MMI::PointerEvent & event)1071 void TouchGuider::PostHoverEnterAndMove(MMI::PointerEvent &event)
1072 {
1073     HILOG_DEBUG();
1074 
1075     CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
1076     pointerEvents_.push_back(event);
1077     handler_->SendEvent(SEND_HOVER_ENTER_MOVE_MSG, 0, DOUBLE_TAP_TIMEOUT / US_TO_MS);
1078 }
1079 
PostHoverExit()1080 void TouchGuider::PostHoverExit()
1081 {
1082     HILOG_DEBUG();
1083 
1084     CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
1085     handler_->SendEvent(SEND_HOVER_EXIT_MSG, 0, DOUBLE_TAP_TIMEOUT / US_TO_MS);
1086 }
1087 
PostAccessibilityEvent(uint32_t innerEventID)1088 void TouchGuider::PostAccessibilityEvent(uint32_t innerEventID)
1089 {
1090     HILOG_DEBUG();
1091 
1092     handler_->SendEvent(innerEventID, 0, EXIT_GESTURE_REC_TIMEOUT);
1093 }
1094 
CancelPostEvent(uint32_t innerEventID)1095 void TouchGuider::CancelPostEvent(uint32_t innerEventID)
1096 {
1097     HILOG_DEBUG();
1098 
1099     handler_->RemoveEvent(innerEventID);
1100 }
1101 
CancelPostEventIfNeed(uint32_t innerEventID)1102 void TouchGuider::CancelPostEventIfNeed(uint32_t innerEventID)
1103 {
1104     HILOG_DEBUG();
1105 
1106     if (HasEventPending(innerEventID)) {
1107         handler_->RemoveEvent(innerEventID);
1108         if (innerEventID == SEND_HOVER_ENTER_MOVE_MSG) {
1109             pointerEvents_.clear();
1110         }
1111     }
1112 }
1113 
HasEventPending(uint32_t innerEventID)1114 bool TouchGuider::HasEventPending(uint32_t innerEventID)
1115 {
1116     HILOG_DEBUG();
1117 
1118     return handler_->HasInnerEvent(innerEventID);
1119 }
1120 
ForceSendAndRemoveEvent(uint32_t innerEventID,MMI::PointerEvent & event)1121 void TouchGuider::ForceSendAndRemoveEvent(uint32_t innerEventID, MMI::PointerEvent &event)
1122 {
1123     HILOG_DEBUG();
1124 
1125     if (!HasEventPending(innerEventID)) {
1126         HILOG_DEBUG("No pending event.");
1127         return;
1128     }
1129 
1130     switch (innerEventID) {
1131         case SEND_HOVER_ENTER_MOVE_MSG:
1132             SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
1133             if (pointerEvents_.empty()) {
1134                 break;
1135             }
1136             for (auto iter = pointerEvents_.begin(); iter != pointerEvents_.end(); ++iter) {
1137                 if (iter->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
1138                     SendEventToMultimodal(*iter, HOVER_ENTER);
1139                 } else {
1140                     SendEventToMultimodal(*iter, HOVER_MOVE);
1141                 }
1142             }
1143             pointerEvents_.clear();
1144             break;
1145         case SEND_TOUCH_GUIDE_END_MSG:
1146             SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_END);
1147             break;
1148         default:
1149             break;
1150     }
1151     CancelPostEvent(innerEventID);
1152 }
1153 
IgnoreRepeatExecuteAction()1154 bool TouchGuider::IgnoreRepeatExecuteAction()
1155 {
1156     HILOG_DEBUG();
1157     int64_t time = Utils::GetSystemTime();
1158     if (time - lastDoubleTapTime < IGNORE_REPEAT_EXECUTE_INTERVAL) {
1159         HILOG_DEBUG("time interval < 300ms");
1160         lastDoubleTapTime = time;
1161         return true;
1162     }
1163 
1164     lastDoubleTapTime = time;
1165     return false;
1166 }
1167 
ExecuteActionOnAccessibilityFocused(const ActionType & action)1168 bool TouchGuider::ExecuteActionOnAccessibilityFocused(const ActionType &action)
1169 {
1170     HILOG_DEBUG();
1171     if (IgnoreRepeatExecuteAction()) {
1172         return true;
1173     }
1174     return Singleton<AccessibleAbilityManagerService>::GetInstance().ExecuteActionOnAccessibilityFocused(action);
1175 }
1176 
FindFocusedElement(AccessibilityElementInfo & elementInfo)1177 bool TouchGuider::FindFocusedElement(AccessibilityElementInfo &elementInfo)
1178 {
1179     HILOG_DEBUG();
1180     return Singleton<AccessibleAbilityManagerService>::GetInstance().FindFocusedElement(elementInfo);
1181 }
1182 
HoverEnterAndMoveRunner()1183 void TGEventHandler::HoverEnterAndMoveRunner()
1184 {
1185     HILOG_DEBUG();
1186 
1187     std::list<MMI::PointerEvent> motionEvent = tgServer_.getHoverEnterAndMoveEvent();
1188     tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
1189     if (!motionEvent.empty()) {
1190         for (auto iter = motionEvent.begin(); iter != motionEvent.end(); ++iter) {
1191             if (iter->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
1192                 tgServer_.SendEventToMultimodal(*iter, HOVER_ENTER);
1193             } else {
1194                 tgServer_.SendEventToMultimodal(*iter, HOVER_MOVE);
1195             }
1196         }
1197     }
1198     tgServer_.ClearHoverEnterAndMoveEvent();
1199 }
1200 
HoverExitRunner()1201 void TGEventHandler::HoverExitRunner()
1202 {
1203     HILOG_DEBUG();
1204 
1205     std::shared_ptr<MMI::PointerEvent> pEvent = tgServer_.getLastReceivedEvent();
1206     tgServer_.SendEventToMultimodal(*pEvent, HOVER_EXIT);
1207     if (!HasInnerEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG)) {
1208         RemoveEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG);
1209         SendEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
1210     }
1211 }
1212 } // namespace Accessibility
1213 } // namespace OHOS