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