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