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