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