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