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