1 /* 2 * Copyright (C) 2023 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_MULTIFINGER_MULTITAP_H 17 #define ACCESSIBILITY_MULTIFINGER_MULTITAP_H 18 19 #include <cmath> 20 #include <vector> 21 22 #include "accessibility_gesture_recognizer.h" 23 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER 24 #include "accessibility_display_manager.h" 25 #endif 26 #include "accessibility_event_info.h" 27 #include "accessible_ability_manager_service.h" 28 #include "accessibility_def.h" 29 #include "event_handler.h" 30 #include "event_runner.h" 31 #include "pointer_event.h" 32 #include "singleton.h" 33 34 namespace OHOS { 35 namespace Accessibility { 36 namespace { 37 constexpr uint32_t MAX_TAP_NUM = 3; 38 constexpr uint32_t MAX_MULTI_FINGER_TYPE = 3; 39 } // namespace 40 41 enum MoveGirectionType : int32_t { 42 SWIPE_LEFT = 0, 43 SWIPE_RIGHT = 1, 44 SWIPE_UP = 2, 45 SWIPE_DOWN = 3 46 }; 47 48 enum FingerTouchUpState : int32_t { 49 NOT_ALL_FINGER_TOUCH_UP = 0, 50 ALL_FINGER_TOUCH_UP = 1, 51 TOUCH_DOWN_AFTER_ALL_FINGER_TOUCH_UP = 2, 52 }; 53 54 enum MultiFingerGestureState : int32_t { 55 GESTURE_NOT_START = 0, 56 GESTURE_START = 1, 57 GESTURE_CANCLE = 2, 58 GESTURE_COMPLETE = 3, 59 GESTURE_WAIT = 4, 60 }; 61 62 class AccessibilityMultiTapGestureRecognizer; 63 class MultiFingerGestureHandler : public AppExecFwk::EventHandler { 64 public: 65 MultiFingerGestureHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner, 66 AccessibilityMultiTapGestureRecognizer &server); 67 virtual ~MultiFingerGestureHandler() = default; 68 /** 69 * @brief Process the event of install system bundles. 70 * @param event Indicates the event to be processed. 71 */ 72 virtual void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; 73 private: 74 /** 75 * @brief Process the multi finger gesture by Gesture type. 76 * @param gestureType Indicates the gesture type to be processed. 77 */ 78 void ProcessMultiFingerGestureTypeEvent(const GestureType gestureType); 79 80 /** 81 * @brief Process the multi finger gesture event. 82 * @param event Indicates the event to be processed. 83 * @return true if the gesture event is processed success, else false. 84 */ 85 bool ProcessMultiFingerGestureEvent(const AppExecFwk::InnerEvent::Pointer &event); 86 87 /** 88 * @brief check whether the gesture is a tap gesture. 89 * @param gestureType Indicates the gesture to be processed. 90 * @return true if the gesture is a tap gesture, else false. 91 */ 92 bool IsTapGesture(const GestureType gestureType); 93 94 AccessibilityMultiTapGestureRecognizer &server_; 95 }; 96 97 class AccessibilityMultiTapGestureRecognizer : public AppExecFwk::EventHandler { 98 public: 99 static constexpr uint32_t TWO_FINGER_SINGLE_TAP_MSG = 3; 100 static constexpr uint32_t TWO_FINGER_LONG_PRESS_MSG = 4; 101 static constexpr uint32_t TWO_FINGER_DOUBLE_TAP_MSG = 5; 102 static constexpr uint32_t TWO_FINGER_DOUBLE_TAP_AND_HOLD_MSG = 6; 103 static constexpr uint32_t TWO_FINGER_TRIPLE_TAP_MSG = 7; 104 static constexpr uint32_t TWO_FINGER_TRIPLE_TAP_AND_HOLD_MSG = 8; 105 static constexpr uint32_t THREE_FINGER_SINGLE_TAP_MSG = 9; 106 static constexpr uint32_t THREE_FINGER_LONG_PRESS_MSG = 10; 107 static constexpr uint32_t THREE_FINGER_DOUBLE_TAP_MSG = 11; 108 static constexpr uint32_t THREE_FINGER_DOUBLE_TAP_AND_HOLD_MSG = 12; 109 static constexpr uint32_t THREE_FINGER_TRIPLE_TAP_MSG = 13; 110 static constexpr uint32_t THREE_FINGER_TRIPLE_TAP_AND_HOLD_MSG = 14; 111 static constexpr uint32_t FOUR_FINGER_SINGLE_TAP_MSG = 15; 112 static constexpr uint32_t FOUR_FINGER_LONG_PRESS_MSG = 16; 113 static constexpr uint32_t FOUR_FINGER_DOUBLE_TAP_MSG = 17; 114 static constexpr uint32_t FOUR_FINGER_DOUBLE_TAP_AND_HOLD_MSG = 18; 115 static constexpr uint32_t FOUR_FINGER_TRIPLE_TAP_MSG = 19; 116 static constexpr uint32_t FOUR_FINGER_TRIPLE_TAP_AND_HOLD_MSG = 20; 117 static constexpr uint32_t WAIT_ANOTHER_FINGER_DOWN_MSG = 21; 118 static constexpr uint32_t CANCEL_WAIT_FINGER_DOWN_MSG = 22; 119 static constexpr uint32_t CANCEL_GESTURE = 23; 120 static constexpr uint32_t COMPLETE_GESTURE = 24; 121 122 static constexpr uint32_t GESTURE_TAP_MSG[MAX_TAP_NUM][MAX_MULTI_FINGER_TYPE] = { 123 { 124 TWO_FINGER_SINGLE_TAP_MSG, 125 THREE_FINGER_SINGLE_TAP_MSG, 126 FOUR_FINGER_SINGLE_TAP_MSG, 127 }, 128 { 129 TWO_FINGER_DOUBLE_TAP_MSG, 130 THREE_FINGER_DOUBLE_TAP_MSG, 131 FOUR_FINGER_DOUBLE_TAP_MSG, 132 }, 133 { 134 TWO_FINGER_TRIPLE_TAP_MSG, 135 THREE_FINGER_TRIPLE_TAP_MSG, 136 FOUR_FINGER_TRIPLE_TAP_MSG, 137 } 138 }; 139 140 static constexpr uint32_t GESTURE_HOLD_MSG[MAX_TAP_NUM][MAX_MULTI_FINGER_TYPE] = { 141 { 142 TWO_FINGER_LONG_PRESS_MSG, 143 THREE_FINGER_LONG_PRESS_MSG, 144 FOUR_FINGER_LONG_PRESS_MSG, 145 }, 146 { 147 TWO_FINGER_DOUBLE_TAP_AND_HOLD_MSG, 148 THREE_FINGER_DOUBLE_TAP_AND_HOLD_MSG, 149 FOUR_FINGER_DOUBLE_TAP_AND_HOLD_MSG, 150 }, 151 { 152 TWO_FINGER_TRIPLE_TAP_AND_HOLD_MSG, 153 THREE_FINGER_TRIPLE_TAP_AND_HOLD_MSG, 154 FOUR_FINGER_TRIPLE_TAP_AND_HOLD_MSG, 155 } 156 }; 157 158 AccessibilityMultiTapGestureRecognizer(); 159 ~AccessibilityMultiTapGestureRecognizer() = default; 160 161 /** 162 * @brief Register GestureRecognizeListener. 163 * @param listener the listener from touchguide. 164 */ 165 void RegisterListener(AccessibilityGestureRecognizeListener &listener); 166 167 /** 168 * @brief Get the GestureRecognizeListener. 169 * @return AccessibilityGestureRecognizeListener ptr. 170 */ GetRecognizeListener()171 AccessibilityGestureRecognizeListener *GetRecognizeListener() const 172 { 173 return listener_; 174 } 175 176 /** 177 * @brief Handle a touch event. If an action is completed, the appropriate callback is called. 178 * 179 * @param event the touch event to be handled. 180 * @return true if the gesture be recognized, else false. 181 */ 182 bool OnPointerEvent(MMI::PointerEvent &event); 183 184 /** 185 * @brief Cancle multi finger gesture rocognize state, buffer etc. 186 */ 187 void Clear(); 188 189 /** 190 * @brief Get the target fingers number touch down in first round. 191 * @return the finger numbers touch down in first round. 192 */ GetTargetFingers()193 int32_t GetTargetFingers() const 194 { 195 return targetFingers_; 196 } 197 198 /** 199 * @brief Get finger touch up state. 200 * @return the touch up state, indicates if fingers is still on the screen. 201 */ GetFingerTouchUpState()202 int32_t GetFingerTouchUpState() const 203 { 204 return fingerTouchUpState_; 205 } 206 207 /** 208 * @brief Set the finger touch up state when touch up or finish touch down. 209 * @param touchUpState the touchUpState to be set. 210 */ SetFingerTouchUpState(const int32_t touchUpState)211 void SetFingerTouchUpState(const int32_t touchUpState) 212 { 213 fingerTouchUpState_ = touchUpState; 214 } 215 216 /** 217 * @brief Set multi finger gesture state, when gesture recognize start, cancel, complete etc. 218 * @param gestureState the multiFingerGestureState to be set. 219 */ SetMultiFingerGestureState(const int32_t gestureState)220 void SetMultiFingerGestureState(const int32_t gestureState) 221 { 222 multiFingerGestureState_ = gestureState; 223 } 224 225 /** 226 * @brief Determine whether multi finger gesture is started. 227 * @return true if gesture recognize is started, else false. 228 */ IsMultiFingerGestureStarted()229 bool IsMultiFingerGestureStarted() const 230 { 231 return multiFingerGestureState_ == MultiFingerGestureState::GESTURE_START; 232 } 233 234 /** 235 * @brief Determine whether multi finger gesture is started or finished. 236 * @return true if gesture recognize is started or finished, else false. 237 */ IsMultiFingerRecognize()238 bool IsMultiFingerRecognize() const 239 { 240 return (multiFingerGestureState_ == MultiFingerGestureState::GESTURE_START || 241 multiFingerGestureState_ == MultiFingerGestureState::GESTURE_COMPLETE); 242 } 243 244 /** 245 * @brief Get the two finger move threshold. 246 * @return the two finger move threshold, indicates tap state to move state. 247 */ GetTouchSlop()248 float GetTouchSlop() const 249 { 250 return touchSlop_; 251 } 252 private: 253 /** 254 * @brief Cancle the pendding two finger gesture recognize event. 255 */ 256 void CancelTwoFingerEvent(); 257 258 /** 259 * @brief Cancle the pendding three finger gesture recognize event. 260 */ 261 void CancelThreeFingerEvent(); 262 263 /** 264 * @brief Cancle the pendding four finger gesture recognize event. 265 */ 266 void CancelFourFingerEvent(); 267 268 /** 269 * @brief Cancle the pendding finger gesture recognize event by finger num. 270 * @param fingerNum which type gesture pendding event to be canceled. 271 */ 272 void CancelTapAndHoldGestureEvent(const int32_t fingerNum); 273 274 /** 275 * @brief Cancle the pendding multi finger hold gesture recognize event. 276 */ 277 void CancelHoldGestureEvent(); 278 279 /** 280 * @brief Cancle All pendding inner event. 281 */ 282 void CancelAllPenddingEvent(); 283 284 /** 285 * @brief Cancel the multi gesture recognize process. 286 * @param isNoDelayFlag if gesture cancel event is immediately processed. 287 */ 288 void CancelGesture(const bool isNoDelayFlag); 289 290 /** 291 * @brief param check for two finger Double tap recognize gesture. 292 * @param fingerNum the touch event from Multimodal. 293 * @return true if the used param is ok, else false. 294 */ 295 bool ParamCheck(const int32_t fingerNum); 296 297 /** 298 * @brief Get the last touch up time of the first finger. 299 * @param fingerNum total touch down finger nums, means the lastUpPoint_ size. 300 * @return the first finger's last touch up time. 301 */ 302 int64_t GetLastFirstPointUpTime(const int32_t fingerNum); 303 304 /** 305 * @brief Get the current and pre PointerItems with fingerNum, store in curPoints and prePoints. 306 * @param curPoints to store the cur touch event pointerItems rst, size is fingerNum. 307 * @param prePoints to store the pre touch event pointerItems rst, size is fingerNum. 308 * @param event current touch event, to get the curPoints. 309 * @param prePointsEventInfo pre touch Event storage, to get the prePoints. 310 * @return true if the get rst is ok, else false. 311 */ 312 bool GetPointerItemWithFingerNum(int32_t fingerNum, std::vector<MMI::PointerEvent::PointerItem> &curPoints, 313 std::vector<MMI::PointerEvent::PointerItem> &prePoints, MMI::PointerEvent &event, 314 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> &prePointsEventInfo); 315 316 /** 317 * @brief check whether the two taps offset is less than slop threshold. 318 * @param fingerNum touch down finger nums to be processed. 319 * @param curPoints current touch down pointer infos, size is fingerNum. 320 * @param prePoints first round touch down pointer infos, size is fingfingerNumerNums. 321 * @return true if the offset of two taps is less than slop threshold, else false. 322 */ 323 bool IsDoubelTapSlopConditionMatch(const int32_t fingerNum, 324 const std::vector<MMI::PointerEvent::PointerItem> &curPoints, 325 const std::vector<MMI::PointerEvent::PointerItem> &prePoints); 326 327 /** 328 * @brief Determine whether it is a multi finger double tap gesture. 329 * @param event the touch event from Multimodal. 330 * @param fingerNum the target fingerNum to be processed. 331 * @return true if the gesture is multi finger double tap, else false. 332 */ 333 bool IsMultiFingerDoubleTap(MMI::PointerEvent &event, const int32_t fingerNum); 334 335 /** 336 * @brief save touch down point event info. 337 */ 338 void storeBaseDownPoint(); 339 340 /** 341 * @brief Get move direction by move distance. 342 * @param dx the x axis distance between base point and current point. 343 * @param dy the y axis distance between base point and current point. 344 * @return the move direction, value range is MoveGirectionType. 345 */ 346 int32_t GetSwipeDirection(const int32_t dx, const int32_t dy); 347 348 /** 349 * @brief Get the base point Item info by point Id. 350 * @param basePointerIterm to save th base pointItem info. 351 * @param pId the point Id to get the pointItem. 352 * @param pointInfo the touch down event point info storage. 353 * @return true if get base pointItem success, else false. 354 */ 355 bool GetBasePointItem(MMI::PointerEvent::PointerItem &basePointerIterm, 356 int32_t pId, std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> &pointInfo); 357 358 /** 359 * @brief Save move gesture path info. 360 * @param event the touch event to be handled. 361 * @param pId the point Id to be handled. 362 * @param pointerIterm the point Item info to be saved. 363 * @param dx the x axis distance between base point and current point. 364 * @param dy the y axis distance between base point and current point. 365 */ 366 void SaveMoveGesturePointerInfo(MMI::PointerEvent &event, 367 const int32_t pId, const MMI::PointerEvent::PointerItem &pointerIterm, const int32_t dx, const int32_t dy); 368 369 /** 370 * @brief recognize the move path is correct and match a move gesture. 371 * @param path move path pointer info storage. 372 * @return true if the move path is correct and match a move gesture, else false. 373 */ 374 bool recognizeGesturePath(const std::vector<Pointer> &path); 375 376 /** 377 * @brief Get the matched move gesture by moveDirection and fingerNum. 378 * @return the matched gesture Id. 379 */ 380 GestureType GetMoveGestureId(); 381 382 /** 383 * @brief whether the multi finger move event match a move gesture. 384 * @return true if multi finger move event match a move gesture, else false. 385 */ 386 bool IsMoveGestureRecognize(); 387 388 /** 389 * @brief Save move gesture path info when finger up. 390 * @param event the touch event to be handled. 391 */ 392 void StoreUpPointInPointerRoute(MMI::PointerEvent &event); 393 394 /** 395 * @brief Handle the first touch down event. 396 * @param event the touch event to be handled. 397 */ 398 void HanleFirstTouchDownEvent(MMI::PointerEvent &event); 399 400 /** 401 * @brief Handle the continue touch down event. 402 * @param event the touch event to be handled. 403 */ 404 void HandleContinueTouchDownEvent(MMI::PointerEvent &event); 405 406 /** 407 * @brief Handle the multi finger touch move event. 408 * @param event the touch event to be handled. 409 */ 410 void HandleMultiFingerMoveEvent(MMI::PointerEvent &event); 411 412 /** 413 * @brief Handle the touch up event, not a move gesture. 414 * @param event the touch event to be handled. 415 */ 416 void HandleMultiFingerTouchUpEvent(MMI::PointerEvent &event); 417 418 /** 419 * @brief Handle the continue touch down event, decide whether it is a multi tap event. 420 * @param event the touch event to be handled. 421 * @param fingerNum the touch down fingerNum to be handled. 422 */ 423 void HandleMultiTapEvent(MMI::PointerEvent &event, const int32_t fingerNum); 424 425 float touchSlop_ = 0.0f; 426 int32_t doubleTapOffsetThresh_ = 0; 427 int32_t targetFingers_ = -1; // touch down finger numbers before first time the finger touch up 428 uint32_t addContinueTapNum_ = 0; // total number of touch down, except the first touch down 429 int32_t multiFingerGestureState_ = 0; // recognize state, value is MultiFingerGestureState 430 int32_t fingerTouchUpState_ = FingerTouchUpState::ALL_FINGER_TOUCH_UP; 431 bool isFirstUp_ = 0; // whether the first time finger touch up 432 bool isMoveGestureRecognizing = false; // in move gesture recognize process or not 433 int32_t moveDirection = -1; 434 float mMinPixelsBetweenSamplesX_ = 0; 435 float mMinPixelsBetweenSamplesY_ = 0; 436 437 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> firstDownPoint_; // first round touch down points 438 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> currentDownPoint_; // current round touch down points 439 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> preGesturePoint_; // pre move event points 440 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> lastUpPoint_; // last time finger touch up points 441 std::map<int32_t, std::vector<Pointer>> pointerRoute_; 442 443 AccessibilityGestureRecognizeListener *listener_ = nullptr; 444 std::shared_ptr<MultiFingerGestureHandler> handler_ = nullptr; // multi finger gesture recognize event handler 445 std::shared_ptr<AppExecFwk::EventRunner> runner_ = nullptr; 446 }; 447 } // namespace Accessibility 448 } // namespace OHOS 449 #endif // ACCESSIBILITY_MULTIFINGER_MULTITAP_H