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