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