• 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             HILOG_DEBUG("MMI::PointerEvent::POINTER_ACTION_DOWN");
305             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
306                 Clear(event);
307             } else {
308                 currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
309                 SendAllUpEvents(event);
310             }
311             break;
312         case MMI::PointerEvent::POINTER_ACTION_MOVE:
313             HILOG_DEBUG("MMI::PointerEvent::POINTER_ACTION_MOVE");
314             HandleDraggingStateInnerMove(event);
315             break;
316         case MMI::PointerEvent::POINTER_ACTION_UP:
317             HILOG_DEBUG("MMI::PointerEvent::POINTER_ACTION_UP");
318             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
319                 OnTouchInteractionEnd();
320                 SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
321                 SendEventToMultimodal(event, NO_CHANGE);
322                 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
323             } else {
324                 SendEventToMultimodal(event, NO_CHANGE);
325             }
326             break;
327         default:
328             break;
329     }
330 }
331 
HandleTransmitingState(MMI::PointerEvent & event)332 void TouchGuider::HandleTransmitingState(MMI::PointerEvent& event)
333 {
334     HILOG_DEBUG();
335 
336     switch (event.GetPointerAction()) {
337         case MMI::PointerEvent::POINTER_ACTION_DOWN:
338             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
339                 Clear(event);
340             }
341             break;
342         case MMI::PointerEvent::POINTER_ACTION_UP:
343             if (event.GetPointerIds().size() == POINTER_COUNT_1) {
344                 if (longPressPointId_ >= 0) {
345                     // Adjust this event's location.
346                     MMI::PointerEvent::PointerItem pointer = {};
347                     event.GetPointerItem(event.GetPointerId(), pointer);
348                     pointer.SetDisplayX(pointer.GetDisplayX() + longPressOffsetX_);
349                     pointer.SetDisplayY(pointer.GetDisplayY() + longPressOffsetY_);
350                     event.RemovePointerItem(event.GetPointerId());
351                     event.AddPointerItem(pointer);
352                     longPressPointId_ = INIT_POINT_ID;
353                     longPressOffsetX_ = INIT_MMIPOINT;
354                     longPressOffsetY_ = INIT_MMIPOINT;
355                 }
356                 SendEventToMultimodal(event, NO_CHANGE);
357                 OnTouchInteractionEnd();
358                 SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
359                 currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
360             }
361             break;
362         default:
363             SendEventToMultimodal(event, NO_CHANGE);
364             break;
365     }
366 }
367 
Clear(MMI::PointerEvent & event)368 void TouchGuider::Clear(MMI::PointerEvent& event)
369 {
370     HILOG_DEBUG();
371 
372     if (currentState_ == static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING)) {
373         SendExitEvents();
374     } else if (currentState_ == static_cast<int32_t>(TouchGuideState::DRAGGING) ||
375                currentState_ == static_cast<int32_t>(TouchGuideState::TRANSMITTING)) {
376         SendUpForAllInjectedEvent(event);
377     }
378 
379     CancelPostEvent(EXIT_GESTURE_REC_MSG);
380     CancelPostEvent(SEND_TOUCH_INTERACTION_END_MSG);
381     CancelPostEvent(SEND_TOUCH_GUIDE_END_MSG);
382     CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
383     CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
384     ClearInjectedEventRecorder();
385     ClearReceivedEventRecorder();
386     pointerEvents_.clear();
387     currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
388     isTouchGuiding_ = false;
389     gestureRecognizer_.Clear();
390     longPressPointId_ = INIT_POINT_ID;
391     longPressOffsetX_ = INIT_MMIPOINT;
392     longPressOffsetY_ = INIT_MMIPOINT;
393     OnTouchInteractionEnd();
394 }
395 
Clear()396 void TouchGuider::Clear()
397 {
398     HILOG_DEBUG();
399 
400     std::shared_ptr<MMI::PointerEvent> event = getLastReceivedEvent();
401     if (event) {
402         Clear(*event);
403     }
404 }
405 
SendExitEvents()406 void TouchGuider::SendExitEvents()
407 {
408     HILOG_DEBUG();
409 
410     if (!HasEventPending(SEND_TOUCH_GUIDE_END_MSG)) {
411         PostAccessibilityEvent(SEND_TOUCH_GUIDE_END_MSG);
412     }
413 }
414 
HandleTouchGuidingStateInnerDown(MMI::PointerEvent & event)415 void TouchGuider::HandleTouchGuidingStateInnerDown(MMI::PointerEvent& event)
416 {
417     (void)event;
418 }
419 
HandleTouchGuidingStateInnerMove(MMI::PointerEvent & event)420 void TouchGuider::HandleTouchGuidingStateInnerMove(MMI::PointerEvent& event)
421 {
422     HILOG_DEBUG();
423 
424     switch (event.GetPointerIds().size()) {
425         case POINTER_COUNT_1:
426             HILOG_DEBUG("POINTER_COUNT_1 begin");
427             if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
428                 pointerEvents_.push_back(event);
429             } else if (isTouchGuiding_) {
430                 SendEventToMultimodal(event, HOVER_MOVE);
431             }
432             HILOG_DEBUG("POINTER_COUNT_1 end");
433             break;
434         case POINTER_COUNT_2:
435             HILOG_DEBUG("POINTER_COUNT_2 begin");
436             CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
437             CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
438             if (IsDragGestureAccept(event)) {
439                 currentState_ = static_cast<int32_t>(TouchGuideState::DRAGGING);
440                 SendEventToMultimodal(event, POINTER_DOWN);
441             } else {
442                 currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
443             }
444             HILOG_DEBUG("POINTER_COUNT_2 end");
445             break;
446         default:
447             HILOG_DEBUG("default begin");
448             if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
449                 CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
450                 CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
451             } else {
452                 SendExitEvents();
453             }
454             currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
455             HILOG_DEBUG("default end");
456             break;
457     }
458 }
459 
HandleDraggingStateInnerMove(MMI::PointerEvent & event)460 void TouchGuider::HandleDraggingStateInnerMove(MMI::PointerEvent& event)
461 {
462     HILOG_DEBUG();
463 
464     std::vector<int32_t> pIds = event.GetPointerIds();
465     int32_t pointCount = pIds.size();
466     if (pointCount == POINTER_COUNT_1) {
467         HILOG_INFO("Only two pointers can be received in the dragging state");
468     } else if (pointCount == POINTER_COUNT_2 && IsDragGestureAccept(event)) {
469         /* get densityPixels from WMS */
470         AccessibilityDisplayManager& displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
471         auto display = displayMgr.GetDefaultDisplay();
472         float densityPixels = display->GetVirtualPixelRatio();
473         int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * densityPixels);
474         MMI::PointerEvent::PointerItem pointerF = {};
475         MMI::PointerEvent::PointerItem pointerS = {};
476         event.GetPointerItem(pIds[INDEX_0], pointerF);
477         event.GetPointerItem(pIds[INDEX_1], pointerS);
478         float xPointF = pointerF.GetDisplayX();
479         float xPointS = pointerS.GetDisplayX();
480         float yPointF = pointerF.GetDisplayY();
481         float yPointS = pointerS.GetDisplayY();
482         float offsetX = abs(xPointF - xPointS);
483         float offsetY = abs(yPointF - yPointS);
484         double duration = hypot(offsetX, offsetY);
485         if (duration > miniZoomPointerDistance) {
486             // Adjust this event's location.
487             MMI::PointerEvent::PointerItem pointer = {};
488             event.GetPointerItem(event.GetPointerId(), pointer);
489             pointer.SetDisplayX(pointer.GetDisplayX() + DIVIDE_2(offsetX));
490             pointer.SetDisplayY(pointer.GetDisplayY() + DIVIDE_2(offsetY));
491             event.RemovePointerItem(event.GetPointerId());
492             event.AddPointerItem(pointer);
493         }
494         SendEventToMultimodal(event, NO_CHANGE);
495     } else {
496         currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
497         SendAllUpEvents(event);
498     }
499 }
500 
GetAngleCos(float offsetX,float offsetY,bool isGetX)501 float TouchGuider::GetAngleCos(float offsetX, float offsetY, bool isGetX)
502 {
503     HILOG_DEBUG();
504 
505     float ret = isGetX ? offsetX : offsetY;
506     double duration = hypot(offsetX, offsetY);
507     if (duration == 0) {
508         return ret;
509     }
510     ret = ret / duration;
511     return ret;
512 }
513 
IsDragGestureAccept(MMI::PointerEvent & event)514 bool TouchGuider::IsDragGestureAccept(MMI::PointerEvent& event)
515 {
516     HILOG_DEBUG();
517 
518     std::vector<int32_t> pIds = event.GetPointerIds();
519     MMI::PointerEvent::PointerItem pointerF = {};
520     MMI::PointerEvent::PointerItem pointerS = {};
521     if (!event.GetPointerItem(pIds[0], pointerF)) {
522         HILOG_ERROR("GetPointerItem(%d) failed", pIds[0]);
523     }
524     if (!event.GetPointerItem(pIds[1], pointerS)) {
525         HILOG_ERROR("GetPointerItem(%d) failed", pIds[1]);
526     }
527 
528     float xPointF = pointerF.GetDisplayX();
529     float xPointS = pointerS.GetDisplayX();
530     float yPointF = pointerF.GetDisplayY();
531     float yPointS = pointerS.GetDisplayY();
532     float xPointDownF = receivedRecorder_.pointerDownX[INDEX_0];
533     float xPointDownS = receivedRecorder_.pointerDownX[INDEX_1];
534     float yPointDownF = receivedRecorder_.pointerDownY[INDEX_0];
535     float yPointDownS = receivedRecorder_.pointerDownY[INDEX_1];
536     float firstOffsetX = xPointF - xPointDownF;
537     float firstOffsetY = yPointF - yPointDownF;
538     float secondOffsetX = xPointS - xPointDownS;
539     float secondOffsetY = yPointS - yPointDownS;
540     if ((!firstOffsetX && !firstOffsetY) || (!secondOffsetX && !secondOffsetY)) {
541         return true;
542     }
543 
544     float firstXCos = GetAngleCos(firstOffsetX, firstOffsetY, true);
545     float firstYCos = GetAngleCos(firstOffsetX, firstOffsetY, false);
546     float secondXCos = GetAngleCos(secondOffsetX, secondOffsetY, true);
547     float secondYCos = GetAngleCos(secondOffsetX, secondOffsetY, false);
548     if ((firstXCos * secondXCos + firstYCos * secondYCos) < MAX_DRAG_GESTURE_COSINE) {
549         return false;
550     }
551     return true;
552 }
553 
RecordInjectedEvent(MMI::PointerEvent & event)554 void TouchGuider::RecordInjectedEvent(MMI::PointerEvent& event)
555 {
556     HILOG_DEBUG();
557 
558     int32_t pointerId = event.GetPointerId();
559     switch (event.GetPointerAction()) {
560         case MMI::PointerEvent::POINTER_ACTION_DOWN:
561             injectedRecorder_.downPointerNum++;
562             injectedRecorder_.downPointers |= (1 << pointerId);
563             injectedRecorder_.lastDownTime = event.GetActionTime() / US_TO_MS;
564             break;
565         case MMI::PointerEvent::POINTER_ACTION_UP:
566             injectedRecorder_.downPointers &= ~(1 << pointerId);
567             if (injectedRecorder_.downPointerNum > 0) {
568                 injectedRecorder_.downPointerNum--;
569             }
570             if (!injectedRecorder_.downPointers) {
571                 injectedRecorder_.lastDownTime = 0;
572             }
573             break;
574         case MMI::PointerEvent::POINTER_ACTION_MOVE:
575             injectedRecorder_.lastHoverEvent = std::make_shared<MMI::PointerEvent>(event);
576             break;
577         default:
578             break;
579     }
580 }
581 
RecordReceivedEvent(MMI::PointerEvent & event)582 void TouchGuider::RecordReceivedEvent(MMI::PointerEvent& event)
583 {
584     HILOG_DEBUG();
585 
586     int32_t pointId = event.GetPointerId();
587     MMI::PointerEvent::PointerItem pointer;
588     if (!event.GetPointerItem(pointId, pointer)) {
589         HILOG_ERROR("GetPointerItem(%d) failed", pointId);
590     }
591     receivedRecorder_.lastEvent = std::make_shared<MMI::PointerEvent>(event);
592     switch (event.GetPointerAction()) {
593         case MMI::PointerEvent::POINTER_ACTION_DOWN:
594             receivedRecorder_.pointerDownX[pointId] = pointer.GetDisplayX();
595             receivedRecorder_.pointerDownY[pointId] = pointer.GetDisplayY();
596             break;
597         case MMI::PointerEvent::POINTER_ACTION_UP:
598             receivedRecorder_.pointerDownX[pointId] = 0;
599             receivedRecorder_.pointerDownY[pointId] = 0;
600             break;
601         default:
602             break;
603     }
604 }
605 
ClearReceivedEventRecorder()606 void TouchGuider::ClearReceivedEventRecorder()
607 {
608     HILOG_DEBUG();
609 
610     (void)memset_s(receivedRecorder_.pointerDownX,
611                    sizeof(receivedRecorder_.pointerDownX),
612                    0,
613                    sizeof(receivedRecorder_.pointerDownX));
614     (void)memset_s(receivedRecorder_.pointerDownY,
615                    sizeof(receivedRecorder_.pointerDownY),
616                    0,
617                    sizeof(receivedRecorder_.pointerDownY));
618     receivedRecorder_.lastEvent = nullptr;
619 }
620 
ClearInjectedEventRecorder()621 void TouchGuider::ClearInjectedEventRecorder()
622 {
623     HILOG_DEBUG();
624 
625     injectedRecorder_.downPointerNum = 0;
626     injectedRecorder_.downPointers = 0;
627     injectedRecorder_.lastHoverEvent = nullptr;
628 }
629 
SendAllDownEvents(MMI::PointerEvent & event)630 void TouchGuider::SendAllDownEvents(MMI::PointerEvent& event)
631 {
632     HILOG_DEBUG();
633 
634     std::vector<int32_t> pIds = event.GetPointerIds();
635     for (auto& pId : pIds) {
636         if (!(injectedRecorder_.downPointers & (1 << pId))) {
637             event.SetPointerId(pId);
638             SendEventToMultimodal(event, POINTER_DOWN);
639         }
640     }
641 }
642 
SendAllUpEvents(MMI::PointerEvent & event)643 void TouchGuider::SendAllUpEvents(MMI::PointerEvent &event)
644 {
645     HILOG_DEBUG();
646 
647     std::vector<int32_t> pIds = event.GetPointerIds();
648     for (auto& pId : pIds) {
649         event.SetPointerId(pId);
650         SendEventToMultimodal(event, POINTER_UP);
651     }
652 }
653 
SendUpForAllInjectedEvent(MMI::PointerEvent & event)654 void TouchGuider::SendUpForAllInjectedEvent(MMI::PointerEvent& event)
655 {
656     HILOG_DEBUG();
657 
658     std::vector<int32_t> pIds = event.GetPointerIds();
659     for (const auto& pId : pIds) {
660         if (!(injectedRecorder_.downPointers & (1 << pId))) {
661             continue;
662         }
663         SendEventToMultimodal(event, POINTER_UP);
664     }
665 }
666 
PostGestureRecognizeExit()667 void TouchGuider::PostGestureRecognizeExit()
668 {
669     HILOG_DEBUG();
670 
671     handler_->SendEvent(EXIT_GESTURE_REC_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
672 }
673 
PostHoverEnterAndMove(MMI::PointerEvent & event)674 void TouchGuider::PostHoverEnterAndMove(MMI::PointerEvent& event)
675 {
676     HILOG_DEBUG();
677 
678     CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
679     pointerEvents_.push_back(event);
680     handler_->SendEvent(SEND_HOVER_ENTER_MOVE_MSG, 0, DOUBLE_TAP_TIMEOUT);
681 }
682 
PostHoverExit()683 void TouchGuider::PostHoverExit()
684 {
685     HILOG_DEBUG();
686 
687     CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
688     handler_->SendEvent(SEND_HOVER_EXIT_MSG, 0, DOUBLE_TAP_TIMEOUT);
689 }
690 
PostAccessibilityEvent(uint32_t innerEventID)691 void TouchGuider::PostAccessibilityEvent(uint32_t innerEventID)
692 {
693     HILOG_DEBUG();
694 
695     handler_->SendEvent(innerEventID, 0, EXIT_GESTURE_REC_TIMEOUT);
696 }
697 
CancelPostEvent(uint32_t innerEventID)698 void TouchGuider::CancelPostEvent(uint32_t innerEventID)
699 {
700     HILOG_DEBUG();
701 
702     handler_->RemoveEvent(innerEventID);
703 }
704 
CancelPostEventIfNeed(uint32_t innerEventID)705 void TouchGuider::CancelPostEventIfNeed(uint32_t innerEventID)
706 {
707     HILOG_DEBUG();
708 
709     if (HasEventPending(innerEventID)) {
710         handler_->RemoveEvent(innerEventID);
711         if (innerEventID == SEND_HOVER_ENTER_MOVE_MSG) {
712             pointerEvents_.clear();
713         }
714     }
715 }
716 
HasEventPending(uint32_t innerEventID)717 bool TouchGuider::HasEventPending(uint32_t innerEventID)
718 {
719     HILOG_DEBUG();
720 
721     return handler_->HasInnerEvent(innerEventID);
722 }
723 
ForceSendAndRemoveEvent(uint32_t innerEventID,MMI::PointerEvent & event)724 void TouchGuider::ForceSendAndRemoveEvent(uint32_t innerEventID, MMI::PointerEvent& event)
725 {
726     (void)event;
727     HILOG_DEBUG();
728 
729     if (!HasEventPending(innerEventID)) {
730         HILOG_DEBUG("No pending event.");
731         return;
732     }
733 
734     switch (innerEventID) {
735         case SEND_HOVER_ENTER_MOVE_MSG:
736             SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
737             if (pointerEvents_.empty()) {
738                 break;
739             }
740             for (auto iter = pointerEvents_.begin(); iter != pointerEvents_.end(); ++iter) {
741                 SendEventToMultimodal(*iter, HOVER_MOVE);
742             }
743             pointerEvents_.clear();
744             break;
745         case SEND_TOUCH_INTERACTION_END_MSG:
746             SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
747             break;
748         case SEND_TOUCH_GUIDE_END_MSG:
749             SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_END);
750             break;
751         default:
752             break;
753     }
754     CancelPostEvent(innerEventID);
755 }
756 
HoverEnterAndMoveRunner()757 void TGEventHandler::HoverEnterAndMoveRunner()
758 {
759     HILOG_DEBUG();
760 
761     std::list<MMI::PointerEvent> motionEvent = tgServer_.getHoverEnterAndMoveEvent();
762     tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
763     if (!motionEvent.empty()) {
764         for (auto iter = motionEvent.begin(); iter != motionEvent.end(); ++iter) {
765             tgServer_.SendEventToMultimodal(*iter, HOVER_MOVE);
766         }
767     }
768     tgServer_.ClearHoverEnterAndMoveEvent();
769 }
770 
HoverExitRunner()771 void TGEventHandler::HoverExitRunner()
772 {
773     HILOG_DEBUG();
774 
775     std::shared_ptr<MMI::PointerEvent> pEvent = tgServer_.getLastReceivedEvent();
776     tgServer_.SendEventToMultimodal(*pEvent, HOVER_MOVE);
777     if (!HasInnerEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG)) {
778         RemoveEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG);
779         SendEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
780     }
781     if (HasInnerEvent(TouchGuider::SEND_TOUCH_INTERACTION_END_MSG)) {
782         RemoveEvent(TouchGuider::SEND_TOUCH_INTERACTION_END_MSG);
783         SendEvent(TouchGuider::SEND_TOUCH_INTERACTION_END_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
784     }
785 }
786 } // namespace Accessibility
787 } // namespace OHOS