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 #ifndef ACCESSIBILITY_TOUCH_GUIDER_H 17 #define ACCESSIBILITY_TOUCH_GUIDER_H 18 19 #include <string> 20 #include "accessibility_element_info.h" 21 #include "accessibility_element_operator_callback_stub.h" 22 #include "accessibility_event_transmission.h" 23 #include "accessibility_gesture_recognizer.h" 24 #include "accessibility_multifinger_multitap.h" 25 #include "accessible_ability_manager_service.h" 26 27 namespace OHOS { 28 namespace Accessibility { 29 class TouchGuider; 30 31 const int32_t MAX_POINTER_COUNT = 32; 32 const int64_t EXIT_GESTURE_REC_TIMEOUT = 2000; // millisecond 33 const double MAX_DRAG_GESTURE_COSINE = 0.525321989; 34 const int32_t MINI_POINTER_DISTANCE_DIP = 200; 35 const int32_t INDEX_0 = 0; 36 const int32_t INDEX_1 = 1; 37 const int32_t INIT_POINT_ID = -1; 38 const float INIT_MMIPOINT = 0.0f; 39 #define DIVIDE_2(num) ((num) / 2) 40 #define EPSINON 0.01 41 42 /** 43 * @brief touch Guider state define 44 */ 45 enum class TouchGuideState : int32_t { 46 TOUCH_GUIDING, 47 DRAGGING, 48 TRANSMITTING, 49 GESTURE_RECOGNIZING 50 }; 51 52 /** 53 * @brief Click location define 54 */ 55 enum ClickLocation : int32_t { 56 CLICK_NONE, 57 CLICK_ACCESSIBILITY_FOCUS, 58 CLICK_LAST_TOUCH_GUIDE 59 }; 60 61 /** 62 * @brief struct to record injected pointers. 63 */ 64 struct InjectedEventRecorder { 65 int32_t downPointers; 66 int32_t downPointerNum; 67 int64_t lastDownTime; 68 std::shared_ptr<MMI::PointerEvent> lastHoverEvent; 69 }; 70 71 /** 72 * @brief struct to record received pointers. 73 */ 74 struct ReceivedEventRecorder { 75 int32_t pointerDownX[MAX_POINTER_COUNT]; 76 int32_t pointerDownY[MAX_POINTER_COUNT]; 77 int64_t pointerActionTime[MAX_POINTER_COUNT]; 78 std::shared_ptr<MMI::PointerEvent> lastEvent; 79 }; 80 81 enum ChangeAction : int32_t { 82 NO_CHANGE, 83 HOVER_MOVE, 84 POINTER_DOWN, 85 POINTER_UP, 86 POINTER_MOVE, 87 }; 88 89 class TGEventHandler : public AppExecFwk::EventHandler { 90 public: 91 TGEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner, 92 TouchGuider &tgServer); 93 virtual ~TGEventHandler() = default; 94 /** 95 * @brief Process the event of install system bundles. 96 * @param event Indicates the event to be processed. 97 */ 98 virtual void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; 99 100 private: 101 /** 102 * @brief Send HoverEnter and HoverMove to Multimodal. 103 */ 104 void HoverEnterAndMoveRunner(); 105 106 /** 107 * @brief Send HoverExit to Multimodal. 108 */ 109 void HoverExitRunner(); 110 TouchGuider &tgServer_; 111 }; 112 113 class TouchGuider : public EventTransmission { 114 public: 115 static constexpr uint32_t EXIT_GESTURE_REC_MSG = 0; 116 static constexpr uint32_t SEND_HOVER_ENTER_MOVE_MSG = 1; 117 static constexpr uint32_t SEND_HOVER_EXIT_MSG = 2; 118 static constexpr uint32_t SEND_TOUCH_INTERACTION_END_MSG = 3; 119 static constexpr uint32_t SEND_TOUCH_GUIDE_END_MSG = 4; 120 121 /** 122 * @brief A constructor used to create a touchGuide instance. 123 */ 124 TouchGuider(); 125 126 /** 127 * @brief A destructor used to delete the touchGuide instance. 128 */ ~TouchGuider()129 ~TouchGuider() {} 130 131 /** 132 * @brief TouchGuide start up. 133 */ 134 void StartUp(); 135 136 /** 137 * @brief Handle pointer events from previous event stream node. 138 * 139 * @param event the pointer event to be handled. 140 * @return true: the event has been processed and does not need to be passed to the next node; 141 * false: the event is not processed. 142 */ 143 bool OnPointerEvent(MMI::PointerEvent &event) override; 144 145 /** 146 * @brief Destroy event state. 147 */ 148 void DestroyEvents() override; 149 150 /** 151 * @brief Send pointer down event to multimodal input. 152 * @param event event the touch event from Multimodal, set the down point to the event and send. 153 * @param action point action send to multimode. 154 */ 155 void SendPointerDownEventToMultimodal(MMI::PointerEvent event, int32_t action); 156 157 /** 158 * @brief Send event to multimodal input. 159 * @param event the event prepared to send to Multimodal 160 * @param action the action of the event 161 */ 162 void SendEventToMultimodal(MMI::PointerEvent &event, int32_t action); 163 164 /** 165 * @brief Send accessibility event to specific AccessibleAbility. 166 * @param eventType the type of the event 167 */ 168 void SendAccessibilityEventToAA(EventType eventType); 169 170 /** 171 * @brief Send gesture event to specific AccessibleAbility. 172 * @param gestureId the gesture id of the event 173 */ 174 void SendGestureEventToAA(GestureType gestureId); 175 176 /** 177 * @brief Get hover enter and move event. 178 * @return Returns pointerEvents_ list. 179 */ 180 std::list<MMI::PointerEvent> getHoverEnterAndMoveEvent(); 181 182 /** 183 * @brief Clear hover enter and move event. 184 */ 185 void ClearHoverEnterAndMoveEvent(); 186 187 /** 188 * @brief Get last received event. 189 * @return Returns last event ptr. 190 */ 191 std::shared_ptr<MMI::PointerEvent> getLastReceivedEvent(); 192 193 /* For TouchGuide */ OnTouchInteractionStart()194 inline void OnTouchInteractionStart() 195 { 196 isTouchStart_ = true; 197 } 198 OnTouchInteractionEnd()199 inline void OnTouchInteractionEnd() 200 { 201 isTouchStart_ = false; 202 } 203 204 /** 205 * @brief whether touch guide end. 206 * @return true if touch guide end, else false. 207 */ IsTouchInteractionEnd()208 inline bool IsTouchInteractionEnd() 209 { 210 return isTouchStart_ == false; 211 } 212 213 /** 214 * @brief Perform action on Accessibility Focus. 215 * @param action the action of Accessibility node. 216 * @return Returns true if the action perform successfully; returns false code otherwise. 217 */ 218 bool ExecuteActionOnAccessibilityFocused(const ActionType &action); 219 220 static int64_t lastDoubleTapTime; 221 private: 222 class TouchGuideListener : public AccessibilityGestureRecognizeListener { 223 public: 224 /** 225 * @brief A constructor used to create a TouchGuideListener instance. 226 */ TouchGuideListener(TouchGuider & server)227 explicit TouchGuideListener(TouchGuider &server) : server_(server) {}; 228 229 /** 230 * @brief Prepare to send the event corresponding to the single tap to the Multimodal. 231 * @param event the touch event from Multimodal 232 */ 233 bool OnDoubleTap(MMI::PointerEvent &event) override; 234 235 /** 236 * @brief Send GESTURE_BEGIN to AccessibleAbility. 237 */ 238 bool OnStarted() override; 239 240 /** 241 * @brief Send GESTURE_BEGIN to AccessibleAbility when multi finger gesture start. 242 * @param isTwoFingerGesture whether the gesture is triggered by two finger. 243 */ 244 void MultiFingerGestureOnStarted(bool isTwoFingerGesture) override; 245 246 /** 247 * @brief Send GESTURE_END and TOUCH_END to AccessibleAbility. 248 * @param gestureId the id of gesture 249 */ 250 bool OnCompleted(GestureType gestureId) override; 251 252 /** 253 * @brief Send GESTURE_END and TOUCH_END to AccessibleAbility when multi finger gesture complete. 254 * @param gestureId the id of gesture. 255 */ 256 void MultiFingerGestureOnCompleted(GestureType gestureId) override; 257 258 /** 259 * @brief The gesture has been cancelled. 260 * @param event the touch event from Multimodal 261 */ 262 bool OnCancelled(MMI::PointerEvent &event) override; 263 264 /** 265 * @brief The gesture has been cancelled. 266 * @param isNoDelayFlag whether the gesture recognize process is immediately canceled. 267 */ 268 void MultiFingerGestureOnCancelled(const bool isNoDelayFlag) override; 269 private: 270 TouchGuider &server_; 271 }; 272 273 class ElementOperatorCallbackImpl : public AccessibilityElementOperatorCallbackStub { 274 public: 275 ElementOperatorCallbackImpl() = default; 276 ~ElementOperatorCallbackImpl() = default; 277 278 virtual void SetSearchElementInfoByAccessibilityIdResult(const std::vector<AccessibilityElementInfo> &infos, 279 const int32_t requestId) override; 280 virtual void SetSearchElementInfoByTextResult(const std::vector<AccessibilityElementInfo> &infos, 281 const int32_t requestId) override; 282 virtual void SetFindFocusedElementInfoResult(const AccessibilityElementInfo &info, 283 const int32_t requestId) override; 284 virtual void SetFocusMoveSearchResult(const AccessibilityElementInfo &info, const int32_t requestId) override; 285 virtual void SetExecuteActionResult(const bool succeeded, const int32_t requestId) override; 286 287 private: 288 std::promise<void> promise_; 289 bool executeActionResult_ = false; 290 AccessibilityElementInfo accessibilityInfoResult_ = {}; 291 std::vector<AccessibilityElementInfo> elementInfosResult_; 292 293 friend class TouchGuider; 294 }; 295 296 /** 297 * @brief Determine whether to clear the touchguide. 298 */ 299 void Clear(); 300 301 /** 302 * @brief clear the touchguide. 303 * @param event the last event from Multimodal 304 */ 305 void Clear(MMI::PointerEvent &event); 306 307 /** 308 * @brief Handle touch events on touchExploring state. 309 * @param event the touch event from Multimodal 310 */ 311 void HandleTouchGuidingState(MMI::PointerEvent &event); 312 313 /** 314 * @brief Handle touch events on dragging state. 315 * @param event the touch event from Multimodal 316 */ 317 void HandleDraggingState(MMI::PointerEvent &event); 318 319 /** 320 * @brief Handle touch events on transmitting state. 321 * @param event the touch event from Multimodal 322 */ 323 void HandleTransmitingState(MMI::PointerEvent &event); 324 325 /** 326 * @brief Determine whether it is a drag gesture. 327 * @param event the touch event from Multimodal 328 * @return whether the dragGesture is accepted. 329 */ 330 bool IsDragGestureAccept(MMI::PointerEvent &event); 331 332 /** 333 * @brief Get the offset of current points and touch down points. 334 * @param event the current touch event from Multimodal. 335 * @param firstPointOffset the first finger offset result, xAxis offset and yAxis offset. 336 * @param firstPointOffset the second finger offset result, xAxis offset and yAxis offset. 337 */ 338 void GetPointOffset(MMI::PointerEvent &event, std::vector<float> &firstPointOffset, 339 std::vector<float> &secondPointOffset) const; 340 341 /** 342 * @brief Determine whether it is a move gesture. 343 * @param event the touch event from Multimodal. 344 * @return whether this is a scolling. 345 */ 346 bool IsRealMoveState(MMI::PointerEvent &event) const; 347 348 /** 349 * @brief Get Angle Cos value. 350 * @param offsetX the X value 351 * @param offsetY the Y value 352 * @param isGetX whether is the Angle corresponding to the X axis 353 * @return Angle Cos value. 354 */ 355 float GetAngleCos(float offsetX, float offsetY, bool isGetX); 356 357 /** 358 * @brief Get the info of injected event. 359 * @param event the event prepared to send to Multimodal 360 */ 361 void RecordInjectedEvent(MMI::PointerEvent &event); 362 363 /** 364 * @brief Get the info of Received event. 365 * @param event event the touch event from Multimodal 366 */ 367 void RecordReceivedEvent(MMI::PointerEvent &event); 368 369 /** 370 * @brief Clear received recorder info. 371 */ 372 void ClearReceivedEventRecorder(); 373 374 /** 375 * @brief Clear Injected recorder info. 376 */ 377 void ClearInjectedEventRecorder(); 378 379 /** 380 * @brief Send exit event to multimodal. 381 */ 382 void SendExitEvents(); 383 384 /** 385 * @brief Send all down events to multimodal. 386 * @param event the event prepared to send to Multimodal 387 */ 388 void SendAllDownEvents(MMI::PointerEvent &event); 389 390 /** 391 * @brief Send all up events to multimodal. 392 * @param event the event prepared to send to Multimodal 393 */ 394 void SendAllUpEvents(MMI::PointerEvent &event); 395 396 /** 397 * @brief Send all up events to multimodal. 398 * @param event the event prepared to send to Multimodal 399 */ 400 void SendUpForAllInjectedEvent(MMI::PointerEvent &event); 401 402 /** 403 * @brief Send exit message. 404 */ 405 void PostGestureRecognizeExit(); 406 407 /** 408 * @brief Send enter and move message. 409 * @param event event the touch event from Multimodal 410 */ 411 void PostHoverEnterAndMove(MMI::PointerEvent &event); 412 413 /** 414 * @brief Send exit message. 415 */ 416 void PostHoverExit(); 417 418 /** 419 * @brief Send accessibility event message. 420 * @param innerEventID the id of inner event 421 */ 422 void PostAccessibilityEvent(uint32_t innerEventID); 423 424 /** 425 * @brief Cancel message. 426 * @param innerEventID the id of inner event 427 */ 428 void CancelPostEvent(uint32_t innerEventID); 429 430 /** 431 * @brief Cancel message if it has been sent. 432 * @param innerEventID the id of inner event 433 */ 434 void CancelPostEventIfNeed(uint32_t innerEventID); 435 436 /** 437 * @brief Check whether it has been sending. 438 * @param innerEventID the id of inner event 439 */ 440 bool HasEventPending(uint32_t innerEventID); 441 442 /** 443 * @brief Force send and remove event. 444 * @param innerEventID the id of inner event 445 * @param event event the touch event from Multimodal 446 */ 447 void ForceSendAndRemoveEvent(uint32_t innerEventID, MMI::PointerEvent &event); 448 449 /** 450 * @brief Handle down events on touchExploring state. 451 * @param event event the touch event from Multimodal 452 */ 453 void HandleTouchGuidingStateInnerDown(MMI::PointerEvent &event); 454 455 /** 456 * @brief Handle move events on touchExploring state. 457 * @param event event the touch event from Multimodal 458 */ 459 void HandleTouchGuidingStateInnerMove(MMI::PointerEvent &event); 460 461 /** 462 * @brief Handle move events on dragging state. 463 * @param event event the touch event from Multimodal 464 */ 465 void HandleDraggingStateInnerMove(MMI::PointerEvent &event); 466 467 /** 468 * @brief Ignore repeat execute action. 469 */ 470 bool IgnoreRepeatExecuteAction(); 471 472 int32_t currentState_ = -1; 473 int32_t longPressPointId_ = INIT_POINT_ID; 474 float longPressOffsetX_ = INIT_MMIPOINT; 475 float longPressOffsetY_ = INIT_MMIPOINT; 476 bool isTouchStart_ = false; 477 bool isTouchGuiding_ = false; 478 ReceivedEventRecorder receivedRecorder_ = {}; 479 InjectedEventRecorder injectedRecorder_ = {}; 480 std::list<MMI::PointerEvent> pointerEvents_ {}; 481 AccessibilityGestureRecognizer gestureRecognizer_; 482 AccessibilityMultiTapGestureRecognizer multiFingerGestureRecognizer_; 483 std::unique_ptr<TouchGuideListener> touchGuideListener_ = nullptr; 484 std::shared_ptr<TGEventHandler> handler_ = nullptr; 485 std::shared_ptr<AppExecFwk::EventRunner> runner_ = nullptr; 486 }; 487 } // namespace Accessibility 488 } // namespace OHOS 489 #endif // ACCESSIBILITY_TOUCH_GUIDER_H