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