• 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 "hilog_wrapper.h"
19 #include "securec.h"
20 
21 namespace OHOS {
22 namespace Accessibility {
23 namespace {
24     constexpr int32_t POINTER_COUNT_1 = 1;
25     constexpr int32_t POINTER_COUNT_2 = 2;
26 } // namespace
27 
TGEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,TouchGuider & tgServer)28 TGEventHandler::TGEventHandler(const std::shared_ptr<AppExecFwk::EventRunner>& runner, TouchGuider& tgServer)
29     : AppExecFwk::EventHandler(runner), tgServer_(tgServer)
30 {
31 }
32 
TouchGuider()33 TouchGuider::TouchGuider()
34 {
35     HILOG_DEBUG();
36     currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
37 }
38 
StartUp()39 void TouchGuider::StartUp()
40 {
41     HILOG_DEBUG();
42     touchGuideListener_ = std::make_unique<TouchGuideListener>(*this);
43     gestureRecognizer_.RegisterListener(*touchGuideListener_.get());
44     runner_ = Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner();
45     if (!runner_) {
46         HILOG_ERROR("get runner failed");
47         return;
48     }
49 
50     handler_ = std::make_shared<TGEventHandler>(runner_, *this);
51     if (!handler_) {
52         HILOG_ERROR("create event handler failed");
53         return;
54     }
55 }
56 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)57 void TGEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer& event)
58 {
59     HILOG_DEBUG();
60     switch (event->GetInnerEventId()) {
61         case TouchGuider::EXIT_GESTURE_REC_MSG:
62             tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
63             break;
64         case TouchGuider::SEND_HOVER_ENTER_MOVE_MSG:
65             HoverEnterAndMoveRunner();
66             break;
67         case TouchGuider::SEND_HOVER_EXIT_MSG:
68             HoverExitRunner();
69             break;
70         case TouchGuider::SEND_TOUCH_INTERACTION_END_MSG:
71             tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
72             break;
73         case TouchGuider::SEND_TOUCH_GUIDE_END_MSG:
74             tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_END);
75             break;
76         default:
77             break;
78     }
79 }
80 
OnPointerEvent(MMI::PointerEvent & event)81 bool TouchGuider::OnPointerEvent(MMI::PointerEvent& event)
82 {
83     HILOG_DEBUG();
84     if (event.GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
85         EventTransmission::OnPointerEvent(event);
86         return false;
87     }
88     if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
89         Clear(event);
90         return true;
91     }
92     RecordReceivedEvent(event);
93     if (gestureRecognizer_.OnPointerEvent(event)) {
94         return true;
95     }
96     switch (static_cast<TouchGuideState>(currentState_)) {
97         case TouchGuideState::TOUCH_GUIDING:
98             HandleTouchGuidingState(event);
99             break;
100         case TouchGuideState::DRAGGING:
101             HandleDraggingState(event);
102             break;
103         case TouchGuideState::TRANSMITTING:
104             HandleTransmitingState(event);
105             break;
106         default:
107             break;
108     }
109     return true;
110 }
111 
DestroyEvents()112 void TouchGuider::DestroyEvents()
113 {
114     HILOG_DEBUG();
115 
116     Clear();
117     EventTransmission::DestroyEvents();
118 }
119 
SendAccessibilityEventToAA(EventType eventType)120 void TouchGuider::SendAccessibilityEventToAA(EventType eventType)
121 {
122     HILOG_DEBUG("eventType is 0x%{public}x.", eventType);
123 
124     AccessibilityEventInfo eventInfo {};
125     eventInfo.SetEventType(eventType);
126     int32_t windowsId = Singleton<AccessibilityWindowManager>::GetInstance().activeWindowId_;
127     eventInfo.SetWindowId(windowsId);
128     Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(eventInfo);
129     if (eventType == EventType::TYPE_TOUCH_GUIDE_BEGIN) {
130         isTouchGuiding_ = true;
131     } else if (eventType == EventType::TYPE_TOUCH_GUIDE_END) {
132         isTouchGuiding_ = false;
133     }
134 }
135 
SendEventToMultimodal(MMI::PointerEvent & event,int32_t action)136 void TouchGuider::SendEventToMultimodal(MMI::PointerEvent& event, int32_t action)
137 {
138     HILOG_DEBUG("action is %{public}d.", action);
139     HILOG_DEBUG("SourceType is %{public}d.", event.GetSourceType());
140 
141     switch (action) {
142         case HOVER_MOVE:
143             if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
144                 event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_MOVE);
145                 event.SetSourceType(MMI::PointerEvent::SOURCE_TYPE_MOUSE);
146             }
147             break;
148         case POINTER_DOWN:
149             if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
150                 event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_DOWN);
151             }
152             break;
153         case POINTER_UP:
154             if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
155                 event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_UP);
156             }
157             break;
158         default:
159             break;
160     }
161     EventTransmission::OnPointerEvent(event);
162     RecordInjectedEvent(event);
163 }
164 
getHoverEnterAndMoveEvent()165 std::list<MMI::PointerEvent> TouchGuider::getHoverEnterAndMoveEvent()
166 {
167     HILOG_DEBUG();
168 
169     return pointerEvents_;
170 }
171 
ClearHoverEnterAndMoveEvent()172 void TouchGuider::ClearHoverEnterAndMoveEvent()
173 {
174     HILOG_DEBUG();
175 
176     pointerEvents_.clear();
177     gestureRecognizer_.Clear();
178 }
179 
getLastReceivedEvent()180 std::shared_ptr<MMI::PointerEvent> TouchGuider::getLastReceivedEvent()
181 {
182     HILOG_DEBUG();
183 
184     return receivedRecorder_.lastEvent;
185 }
186 
OnDoubleTap(MMI::PointerEvent & event)187 bool TouchGuider::TouchGuideListener::OnDoubleTap(MMI::PointerEvent& event)
188 {
189     HILOG_DEBUG();
190 
191     MMI::PointerEvent::PointerItem clickPoint = {};
192     if (server_.currentState_ != static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING)) {
193         return false;
194     }
195     server_.OnTouchInteractionEnd();
196     server_.CancelPostEventIfNeed(server_.SEND_HOVER_ENTER_MOVE_MSG);
197     server_.CancelPostEventIfNeed(server_.SEND_HOVER_EXIT_MSG);
198     server_.ForceSendAndRemoveEvent(server_.SEND_TOUCH_GUIDE_END_MSG, event);
199     server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
200 
201     return server_.ExecuteActionOnAccessibilityFocused(ActionType::ACCESSIBILITY_ACTION_CLICK);
202 }
203 
OnStarted()204 bool TouchGuider::TouchGuideListener::OnStarted()
205 {
206     HILOG_DEBUG();
207 
208     server_.currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
209     server_.CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
210     server_.CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
211     server_.PostGestureRecognizeExit();
212     server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_BEGIN);
213     return false;
214 }
215 
OnCompleted(GestureType gestureId)216 bool TouchGuider::TouchGuideListener::OnCompleted(GestureType gestureId)
217 {
218     HILOG_DEBUG("OnCompleted, gestureId is %{public}d", gestureId);
219 
220     if (server_.currentState_ != static_cast<int32_t>(TouchGuideState::TRANSMITTING)) {
221         HILOG_DEBUG("OnCompleted, state is not transmitting.");
222         return false;
223     }
224     server_.OnTouchInteractionEnd();
225     server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
226     server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
227     server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
228     server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
229 
230     AccessibilityEventInfo eventInfo {};
231     eventInfo.SetEventType(EventType::TYPE_GESTURE_EVENT);
232     eventInfo.SetGestureType(gestureId);
233     Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(eventInfo);
234     return true;
235 }
236 
OnCancelled(MMI::PointerEvent & event)237 bool TouchGuider::TouchGuideListener::OnCancelled(MMI::PointerEvent& event)
238 {
239     HILOG_DEBUG();
240 
241     switch (static_cast<TouchGuideState>(server_.currentState_)) {
242         case TouchGuideState::TRANSMITTING:
243             server_.OnTouchInteractionEnd();
244             server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
245             if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP &&
246                 event.GetPointerIds().size() == POINTER_COUNT_1) {
247                 server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
248             }
249             server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
250             server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
251             break;
252         case TouchGuideState::TOUCH_GUIDING:
253             server_.pointerEvents_.push_back(event);
254             server_.ForceSendAndRemoveEvent(SEND_HOVER_ENTER_MOVE_MSG, event);
255             server_.CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
256             server_.SendEventToMultimodal(event, HOVER_MOVE);
257             break;
258         default:
259             return false;
260     }
261     return true;
262 }
263 
HandleTouchGuidingState(MMI::PointerEvent & event)264 void TouchGuider::HandleTouchGuidingState(MMI::PointerEvent& event)
265 {
266     HILOG_DEBUG();
267 
268     switch (event.GetPointerAction()) {
269         case MMI::PointerEvent::POINTER_ACTION_DOWN:
270             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
271                 HandleTouchGuidingStateInnerDown(event);
272             } else {
273                 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
274                 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
275             }
276             break;
277         case MMI::PointerEvent::POINTER_ACTION_MOVE:
278             HandleTouchGuidingStateInnerMove(event);
279             break;
280         case MMI::PointerEvent::POINTER_ACTION_UP:
281             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
282                 OnTouchInteractionEnd();
283                 if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
284                     PostHoverExit();
285                 } else {
286                     SendExitEvents();
287                 }
288                 if (!HasEventPending(SEND_TOUCH_INTERACTION_END_MSG)) {
289                     PostAccessibilityEvent(SEND_TOUCH_INTERACTION_END_MSG);
290                 }
291             }
292             break;
293         default:
294             break;
295     }
296 }
297 
HandleDraggingState(MMI::PointerEvent & event)298 void TouchGuider::HandleDraggingState(MMI::PointerEvent& event)
299 {
300     HILOG_DEBUG();
301 
302     switch (event.GetPointerAction()) {
303         case MMI::PointerEvent::POINTER_ACTION_DOWN:
304             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
305                 Clear(event);
306             } else {
307                 currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
308                 SendEventToMultimodal(event, POINTER_UP);
309                 SendAllDownEvents(event);
310             }
311             break;
312         case MMI::PointerEvent::POINTER_ACTION_MOVE:
313             HandleDraggingStateInnerMove(event);
314             break;
315         case MMI::PointerEvent::POINTER_ACTION_UP:
316             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
317                 OnTouchInteractionEnd();
318                 SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
319                 SendEventToMultimodal(event, NO_CHANGE);
320                 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
321             } else {
322                 SendEventToMultimodal(event, NO_CHANGE);
323             }
324             break;
325         default:
326             break;
327     }
328 }
329 
HandleTransmitingState(MMI::PointerEvent & event)330 void TouchGuider::HandleTransmitingState(MMI::PointerEvent& event)
331 {
332     HILOG_DEBUG();
333 
334     switch (event.GetPointerAction()) {
335         case MMI::PointerEvent::POINTER_ACTION_DOWN:
336             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
337                 Clear(event);
338             }
339             break;
340         case MMI::PointerEvent::POINTER_ACTION_UP:
341             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
342                 if (longPressPointId_ >= 0) {
343                     // Adjust this event's location.
344                     MMI::PointerEvent::PointerItem pointer = {};
345                     event.GetPointerItem(event.GetPointerId(), pointer);
346                     pointer.SetDisplayX(pointer.GetDisplayX() + longPressOffsetX_);
347                     pointer.SetDisplayY(pointer.GetDisplayY() + longPressOffsetY_);
348                     event.RemovePointerItem(event.GetPointerId());
349                     event.AddPointerItem(pointer);
350                     longPressPointId_ = INIT_POINT_ID;
351                     longPressOffsetX_ = INIT_MMIPOINT;
352                     longPressOffsetY_ = INIT_MMIPOINT;
353                 }
354                 SendEventToMultimodal(event, NO_CHANGE);
355                 OnTouchInteractionEnd();
356                 SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
357                 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
358             }
359             break;
360         default:
361             SendEventToMultimodal(event, NO_CHANGE);
362             break;
363     }
364 }
365 
Clear(MMI::PointerEvent & event)366 void TouchGuider::Clear(MMI::PointerEvent& event)
367 {
368     HILOG_DEBUG();
369 
370     if (currentState_ == static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING)) {
371         SendExitEvents();
372     } else if (currentState_ == static_cast<int32_t>(TouchGuideState::DRAGGING) ||
373                currentState_ == static_cast<int32_t>(TouchGuideState::TRANSMITTING)) {
374         SendUpForAllInjectedEvent(event);
375     }
376 
377     CancelPostEvent(EXIT_GESTURE_REC_MSG);
378     CancelPostEvent(SEND_TOUCH_INTERACTION_END_MSG);
379     CancelPostEvent(SEND_TOUCH_GUIDE_END_MSG);
380     CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
381     CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
382     ClearInjectedEventRecorder();
383     ClearReceivedEventRecorder();
384     pointerEvents_.clear();
385     currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
386     isTouchGuiding_ = false;
387     gestureRecognizer_.Clear();
388     longPressPointId_ = INIT_POINT_ID;
389     longPressOffsetX_ = INIT_MMIPOINT;
390     longPressOffsetY_ = INIT_MMIPOINT;
391     OnTouchInteractionEnd();
392 }
393 
Clear()394 void TouchGuider::Clear()
395 {
396     HILOG_DEBUG();
397 
398     std::shared_ptr<MMI::PointerEvent> event = getLastReceivedEvent();
399     if (event) {
400         Clear(*event);
401     }
402 }
403 
SendExitEvents()404 void TouchGuider::SendExitEvents()
405 {
406     HILOG_DEBUG();
407 
408     if (!HasEventPending(SEND_TOUCH_GUIDE_END_MSG)) {
409         PostAccessibilityEvent(SEND_TOUCH_GUIDE_END_MSG);
410     }
411 }
412 
HandleTouchGuidingStateInnerDown(MMI::PointerEvent & event)413 void TouchGuider::HandleTouchGuidingStateInnerDown(MMI::PointerEvent& event)
414 {
415     (void)event;
416 }
417 
HandleTouchGuidingStateInnerMove(MMI::PointerEvent & event)418 void TouchGuider::HandleTouchGuidingStateInnerMove(MMI::PointerEvent& event)
419 {
420     HILOG_DEBUG();
421 
422     switch (event.GetPointerIds().size()) {
423         case POINTER_COUNT_1:
424             if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
425                 pointerEvents_.push_back(event);
426             } else if (isTouchGuiding_) {
427                 SendEventToMultimodal(event, HOVER_MOVE);
428             }
429             break;
430         case POINTER_COUNT_2:
431             CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
432             CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
433             if (IsDragGestureAccept(event)) {
434                 currentState_ = static_cast<int32_t>(TouchGuideState::DRAGGING);
435                 SendEventToMultimodal(event, POINTER_DOWN);
436             } else {
437                 currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
438                 SendAllDownEvents(event);
439             }
440             break;
441         default:
442             if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
443                 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
444                 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
445             } else {
446                 SendExitEvents();
447             }
448             currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
449             SendAllDownEvents(event);
450             break;
451     }
452 }
453 
HandleDraggingStateInnerMove(MMI::PointerEvent & event)454 void TouchGuider::HandleDraggingStateInnerMove(MMI::PointerEvent& event)
455 {
456     HILOG_DEBUG();
457 
458     std::vector<int32_t> pIds = event.GetPointerIds();
459     int32_t pointCount = pIds.size();
460     if (pointCount == POINTER_COUNT_1) {
461         HILOG_INFO("Only two pointers can be received in the dragging state");
462     } else if (pointCount == POINTER_COUNT_2 && IsDragGestureAccept(event)) {
463         /* get densityPixels from WMS */
464         AccessibilityDisplayManager& displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
465         auto display = displayMgr.GetDefaultDisplay();
466         float densityPixels = display->GetVirtualPixelRatio();
467         int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * densityPixels);
468         MMI::PointerEvent::PointerItem pointerF = {};
469         MMI::PointerEvent::PointerItem pointerS = {};
470         event.GetPointerItem(pIds[INDEX_0], pointerF);
471         event.GetPointerItem(pIds[INDEX_1], pointerS);
472         float xPointF = pointerF.GetDisplayX();
473         float xPointS = pointerS.GetDisplayX();
474         float yPointF = pointerF.GetDisplayY();
475         float yPointS = pointerS.GetDisplayY();
476         float offsetX = abs(xPointF - xPointS);
477         float offsetY = abs(yPointF - yPointS);
478         double duration = hypot(offsetX, offsetY);
479         if (duration > miniZoomPointerDistance) {
480             // Adjust this event's location.
481             MMI::PointerEvent::PointerItem pointer = {};
482             event.GetPointerItem(event.GetPointerId(), pointer);
483             pointer.SetDisplayX(pointer.GetDisplayX() + DIVIDE_2(offsetX));
484             pointer.SetDisplayY(pointer.GetDisplayY() + DIVIDE_2(offsetY));
485             event.RemovePointerItem(event.GetPointerId());
486             event.AddPointerItem(pointer);
487         }
488         SendEventToMultimodal(event, NO_CHANGE);
489     } else {
490         currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
491         SendEventToMultimodal(event, POINTER_UP);
492         SendAllDownEvents(event);
493     }
494 }
495 
GetAngleCos(float offsetX,float offsetY,bool isGetX)496 float TouchGuider::GetAngleCos(float offsetX, float offsetY, bool isGetX)
497 {
498     HILOG_DEBUG();
499 
500     float ret = isGetX ? offsetX : offsetY;
501     double duration = hypot(offsetX, offsetY);
502     if (duration == 0) {
503         return ret;
504     }
505     ret = ret / duration;
506     return ret;
507 }
508 
IsDragGestureAccept(MMI::PointerEvent & event)509 bool TouchGuider::IsDragGestureAccept(MMI::PointerEvent& event)
510 {
511     HILOG_DEBUG();
512 
513     std::vector<int32_t> pIds = event.GetPointerIds();
514     MMI::PointerEvent::PointerItem pointerF = {};
515     MMI::PointerEvent::PointerItem pointerS = {};
516     if (!event.GetPointerItem(pIds[0], pointerF)) {
517         HILOG_ERROR("GetPointerItem(%d) failed", pIds[0]);
518     }
519     if (!event.GetPointerItem(pIds[1], pointerS)) {
520         HILOG_ERROR("GetPointerItem(%d) failed", pIds[1]);
521     }
522 
523     float xPointF = pointerF.GetDisplayX();
524     float xPointS = pointerS.GetDisplayX();
525     float yPointF = pointerF.GetDisplayY();
526     float yPointS = pointerS.GetDisplayY();
527     float xPointDownF = receivedRecorder_.pointerDownX[INDEX_0];
528     float xPointDownS = receivedRecorder_.pointerDownX[INDEX_1];
529     float yPointDownF = receivedRecorder_.pointerDownY[INDEX_0];
530     float yPointDownS = receivedRecorder_.pointerDownY[INDEX_1];
531     float firstOffsetX = xPointF - xPointDownF;
532     float firstOffsetY = yPointF - yPointDownF;
533     float secondOffsetX = xPointS - xPointDownS;
534     float secondOffsetY = yPointS - yPointDownS;
535     if ((!firstOffsetX && !firstOffsetY) || (!secondOffsetX && !secondOffsetY)) {
536         return true;
537     }
538 
539     float firstXCos = GetAngleCos(firstOffsetX, firstOffsetY, true);
540     float firstYCos = GetAngleCos(firstOffsetX, firstOffsetY, false);
541     float secondXCos = GetAngleCos(secondOffsetX, secondOffsetY, true);
542     float secondYCos = GetAngleCos(secondOffsetX, secondOffsetY, false);
543     if ((firstXCos * secondXCos + firstYCos * secondYCos) < MAX_DRAG_GESTURE_COSINE) {
544         return false;
545     }
546     return true;
547 }
548 
RecordInjectedEvent(MMI::PointerEvent & event)549 void TouchGuider::RecordInjectedEvent(MMI::PointerEvent& event)
550 {
551     HILOG_DEBUG();
552 
553     int32_t pointerId = event.GetPointerId();
554     switch (event.GetPointerAction()) {
555         case MMI::PointerEvent::POINTER_ACTION_DOWN:
556             injectedRecorder_.downPointerNum++;
557             injectedRecorder_.downPointers |= (1 << pointerId);
558             injectedRecorder_.lastDownTime = event.GetActionTime() / US_TO_MS;
559             break;
560         case MMI::PointerEvent::POINTER_ACTION_UP:
561             injectedRecorder_.downPointers &= ~(1 << pointerId);
562             if (injectedRecorder_.downPointerNum > 0) {
563                 injectedRecorder_.downPointerNum--;
564             }
565             if (!injectedRecorder_.downPointers) {
566                 injectedRecorder_.lastDownTime = 0;
567             }
568             break;
569         case MMI::PointerEvent::POINTER_ACTION_MOVE:
570             injectedRecorder_.lastHoverEvent = std::make_shared<MMI::PointerEvent>(event);
571             break;
572         default:
573             break;
574     }
575 }
576 
RecordReceivedEvent(MMI::PointerEvent & event)577 void TouchGuider::RecordReceivedEvent(MMI::PointerEvent& event)
578 {
579     HILOG_DEBUG();
580 
581     int32_t pointId = event.GetPointerId();
582     MMI::PointerEvent::PointerItem pointer;
583     if (!event.GetPointerItem(pointId, pointer)) {
584         HILOG_ERROR("GetPointerItem(%d) failed", pointId);
585     }
586     receivedRecorder_.lastEvent = std::make_shared<MMI::PointerEvent>(event);
587     switch (event.GetPointerAction()) {
588         case MMI::PointerEvent::POINTER_ACTION_DOWN:
589             receivedRecorder_.pointerDownX[pointId] = pointer.GetDisplayX();
590             receivedRecorder_.pointerDownY[pointId] = pointer.GetDisplayY();
591             break;
592         case MMI::PointerEvent::POINTER_ACTION_UP:
593             receivedRecorder_.pointerDownX[pointId] = 0;
594             receivedRecorder_.pointerDownY[pointId] = 0;
595             break;
596         default:
597             break;
598     }
599 }
600 
ClearReceivedEventRecorder()601 void TouchGuider::ClearReceivedEventRecorder()
602 {
603     HILOG_DEBUG();
604 
605     (void)memset_s(receivedRecorder_.pointerDownX,
606                    sizeof(receivedRecorder_.pointerDownX),
607                    0,
608                    sizeof(receivedRecorder_.pointerDownX));
609     (void)memset_s(receivedRecorder_.pointerDownY,
610                    sizeof(receivedRecorder_.pointerDownY),
611                    0,
612                    sizeof(receivedRecorder_.pointerDownY));
613     receivedRecorder_.lastEvent = nullptr;
614 }
615 
ClearInjectedEventRecorder()616 void TouchGuider::ClearInjectedEventRecorder()
617 {
618     HILOG_DEBUG();
619 
620     injectedRecorder_.downPointerNum = 0;
621     injectedRecorder_.downPointers = 0;
622     injectedRecorder_.lastHoverEvent = nullptr;
623 }
624 
SendAllDownEvents(MMI::PointerEvent & event)625 void TouchGuider::SendAllDownEvents(MMI::PointerEvent& event)
626 {
627     HILOG_DEBUG();
628 
629     std::vector<int32_t> pIds = event.GetPointerIds();
630     for (auto& pId : pIds) {
631         if (!(injectedRecorder_.downPointers & (1 << pId))) {
632             event.SetPointerId(pId);
633             SendEventToMultimodal(event, POINTER_DOWN);
634         }
635     }
636 }
637 
SendUpForAllInjectedEvent(MMI::PointerEvent & event)638 void TouchGuider::SendUpForAllInjectedEvent(MMI::PointerEvent& event)
639 {
640     HILOG_DEBUG();
641 
642     std::vector<int32_t> pIds = event.GetPointerIds();
643     for (const auto& pId : pIds) {
644         if (!(injectedRecorder_.downPointers & (1 << pId))) {
645             continue;
646         }
647         SendEventToMultimodal(event, POINTER_UP);
648     }
649 }
650 
PostGestureRecognizeExit()651 void TouchGuider::PostGestureRecognizeExit()
652 {
653     HILOG_DEBUG();
654 
655     handler_->SendEvent(EXIT_GESTURE_REC_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
656 }
657 
PostHoverEnterAndMove(MMI::PointerEvent & event)658 void TouchGuider::PostHoverEnterAndMove(MMI::PointerEvent& event)
659 {
660     HILOG_DEBUG();
661 
662     CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
663     pointerEvents_.push_back(event);
664     handler_->SendEvent(SEND_HOVER_ENTER_MOVE_MSG, 0, DOUBLE_TAP_TIMEOUT);
665 }
666 
PostHoverExit()667 void TouchGuider::PostHoverExit()
668 {
669     HILOG_DEBUG();
670 
671     CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
672     handler_->SendEvent(SEND_HOVER_EXIT_MSG, 0, DOUBLE_TAP_TIMEOUT);
673 }
674 
PostAccessibilityEvent(uint32_t innerEventID)675 void TouchGuider::PostAccessibilityEvent(uint32_t innerEventID)
676 {
677     HILOG_DEBUG();
678 
679     handler_->SendEvent(innerEventID, 0, EXIT_GESTURE_REC_TIMEOUT);
680 }
681 
CancelPostEvent(uint32_t innerEventID)682 void TouchGuider::CancelPostEvent(uint32_t innerEventID)
683 {
684     HILOG_DEBUG();
685 
686     handler_->RemoveEvent(innerEventID);
687 }
688 
CancelPostEventIfNeed(uint32_t innerEventID)689 void TouchGuider::CancelPostEventIfNeed(uint32_t innerEventID)
690 {
691     HILOG_DEBUG();
692 
693     if (HasEventPending(innerEventID)) {
694         handler_->RemoveEvent(innerEventID);
695         if (innerEventID == SEND_HOVER_ENTER_MOVE_MSG) {
696             pointerEvents_.clear();
697         }
698     }
699 }
700 
HasEventPending(uint32_t innerEventID)701 bool TouchGuider::HasEventPending(uint32_t innerEventID)
702 {
703     HILOG_DEBUG();
704 
705     return handler_->HasInnerEvent(innerEventID);
706 }
707 
ForceSendAndRemoveEvent(uint32_t innerEventID,MMI::PointerEvent & event)708 void TouchGuider::ForceSendAndRemoveEvent(uint32_t innerEventID, MMI::PointerEvent& event)
709 {
710     (void)event;
711     HILOG_DEBUG();
712 
713     if (!HasEventPending(innerEventID)) {
714         HILOG_DEBUG("No pending event.");
715         return;
716     }
717 
718     switch (innerEventID) {
719         case SEND_HOVER_ENTER_MOVE_MSG:
720             SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
721             if (pointerEvents_.empty()) {
722                 break;
723             }
724             for (auto iter = pointerEvents_.begin(); iter != pointerEvents_.end(); ++iter) {
725                 SendEventToMultimodal(*iter, HOVER_MOVE);
726             }
727             pointerEvents_.clear();
728             break;
729         case SEND_TOUCH_INTERACTION_END_MSG:
730             SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
731             break;
732         case SEND_TOUCH_GUIDE_END_MSG:
733             SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_END);
734             break;
735         default:
736             break;
737     }
738     CancelPostEvent(innerEventID);
739 }
740 
HoverEnterAndMoveRunner()741 void TGEventHandler::HoverEnterAndMoveRunner()
742 {
743     HILOG_DEBUG();
744 
745     std::list<MMI::PointerEvent> motionEvent = tgServer_.getHoverEnterAndMoveEvent();
746     tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
747     if (!motionEvent.empty()) {
748         for (auto iter = motionEvent.begin(); iter != motionEvent.end(); ++iter) {
749             tgServer_.SendEventToMultimodal(*iter, HOVER_MOVE);
750         }
751     }
752     tgServer_.ClearHoverEnterAndMoveEvent();
753 }
754 
HoverExitRunner()755 void TGEventHandler::HoverExitRunner()
756 {
757     HILOG_DEBUG();
758 
759     std::shared_ptr<MMI::PointerEvent> pEvent = tgServer_.getLastReceivedEvent();
760     tgServer_.SendEventToMultimodal(*pEvent, HOVER_MOVE);
761     if (!HasInnerEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG)) {
762         RemoveEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG);
763         SendEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
764     }
765     if (HasInnerEvent(TouchGuider::SEND_TOUCH_INTERACTION_END_MSG)) {
766         RemoveEvent(TouchGuider::SEND_TOUCH_INTERACTION_END_MSG);
767         SendEvent(TouchGuider::SEND_TOUCH_INTERACTION_END_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
768     }
769 }
770 } // namespace Accessibility
771 } // namespace OHOS