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 */ 181 void OnPointerEvent(MMI::PointerEvent &event); 182 183 /** 184 * @brief Cancle multi finger gesture rocognize state, buffer etc. 185 */ 186 void Clear(); 187 188 /** 189 * @brief Get the target fingers number touch down in first round. 190 * @return the finger numbers touch down in first round. 191 */ GetTargetFingers()192 int32_t GetTargetFingers() const 193 { 194 return targetFingers_; 195 } 196 197 /** 198 * @brief Get finger touch up state. 199 * @return the touch up state, indicates if fingers is still on the screen. 200 */ GetFingerTouchUpState()201 int32_t GetFingerTouchUpState() const 202 { 203 return fingerTouchUpState_; 204 } 205 206 /** 207 * @brief Set the finger touch up state when touch up or finish touch down. 208 * @param touchUpState the touchUpState to be set. 209 */ SetFingerTouchUpState(const int32_t touchUpState)210 void SetFingerTouchUpState(const int32_t touchUpState) 211 { 212 fingerTouchUpState_ = touchUpState; 213 } 214 215 /** 216 * @brief Set multi finger gesture state, when gesture recognize start, cancel, complete etc. 217 * @param gestureState the multiFingerGestureState to be set. 218 */ SetMultiFingerGestureState(const int32_t gestureState)219 void SetMultiFingerGestureState(const int32_t gestureState) 220 { 221 multiFingerGestureState_ = gestureState; 222 } 223 224 /** 225 * @brief Determine whether multi finger gesture is started. 226 * @return true if gesture recognize is started, else false. 227 */ IsMultiFingerGestureStarted()228 bool IsMultiFingerGestureStarted() const 229 { 230 return multiFingerGestureState_ == MultiFingerGestureState::GESTURE_START; 231 } 232 233 /** 234 * @brief Determine whether multi finger gesture is started or finished. 235 * @return true if gesture recognize is started or finished, else false. 236 */ IsMultiFingerRecognize()237 bool IsMultiFingerRecognize() const 238 { 239 return (multiFingerGestureState_ == MultiFingerGestureState::GESTURE_START || 240 multiFingerGestureState_ == MultiFingerGestureState::GESTURE_COMPLETE); 241 } 242 243 /** 244 * @brief Get the two finger move threshold. 245 * @return the two finger move threshold, indicates tap state to move state. 246 */ GetTouchSlop()247 float GetTouchSlop() const 248 { 249 return touchSlop_; 250 } 251 private: 252 /** 253 * @brief Cancle the pendding two finger gesture recognize event. 254 */ 255 void CancelTwoFingerEvent(); 256 257 /** 258 * @brief Cancle the pendding three finger gesture recognize event. 259 */ 260 void CancelThreeFingerEvent(); 261 262 /** 263 * @brief Cancle the pendding four finger gesture recognize event. 264 */ 265 void CancelFourFingerEvent(); 266 267 /** 268 * @brief Cancle the pendding finger gesture recognize event by finger num. 269 * @param fingerNum which type gesture pendding event to be canceled. 270 */ 271 void CancelTapAndHoldGestureEvent(const int32_t fingerNum); 272 273 /** 274 * @brief Cancle the pendding multi finger hold gesture recognize event. 275 */ 276 void CancelHoldGestureEvent(); 277 278 /** 279 * @brief Cancle All pendding inner event. 280 */ 281 void CancelAllPenddingEvent(); 282 283 /** 284 * @brief Cancel the multi gesture recognize process. 285 * @param isNoDelayFlag if gesture cancel event is immediately processed. 286 */ 287 void CancelGesture(const bool isNoDelayFlag); 288 289 /** 290 * @brief param check for two finger Double tap recognize gesture. 291 * @param fingerNum the touch event from Multimodal. 292 * @return true if the used param is ok, else false. 293 */ 294 bool ParamCheck(const int32_t fingerNum); 295 296 /** 297 * @brief Get the last touch up time of the first finger. 298 * @param fingerNum total touch down finger nums, means the lastUpPoint_ size. 299 * @return the first finger's last touch up time. 300 */ 301 int64_t GetLastFirstPointUpTime(const int32_t fingerNum); 302 303 /** 304 * @brief Get the current and pre PointerItems with fingerNum, store in curPoints and prePoints. 305 * @param curPoints to store the cur touch event pointerItems rst, size is fingerNum. 306 * @param prePoints to store the pre touch event pointerItems rst, size is fingerNum. 307 * @param event current touch event, to get the curPoints. 308 * @param prePointsEventInfo pre touch Event storage, to get the prePoints. 309 * @return true if the get rst is ok, else false. 310 */ 311 bool GetPointerItemWithFingerNum(int32_t fingerNum, std::vector<MMI::PointerEvent::PointerItem> &curPoints, 312 std::vector<MMI::PointerEvent::PointerItem> &prePoints, MMI::PointerEvent &event, 313 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> &prePointsEventInfo); 314 315 /** 316 * @brief check whether the two taps offset is less than slop threshold. 317 * @param fingerNum touch down finger nums to be processed. 318 * @param curPoints current touch down pointer infos, size is fingerNum. 319 * @param prePoints first round touch down pointer infos, size is fingfingerNumerNums. 320 * @return true if the offset of two taps is less than slop threshold, else false. 321 */ 322 bool IsDoubelTapSlopConditionMatch(const int32_t fingerNum, 323 const std::vector<MMI::PointerEvent::PointerItem> &curPoints, 324 const std::vector<MMI::PointerEvent::PointerItem> &prePoints); 325 326 /** 327 * @brief Determine whether it is a multi finger double tap gesture. 328 * @param event the touch event from Multimodal. 329 * @param fingerNum the target fingerNum to be processed. 330 * @return true if the gesture is multi finger double tap, else false. 331 */ 332 bool IsMultiFingerDoubleTap(MMI::PointerEvent &event, const int32_t fingerNum); 333 334 /** 335 * @brief save touch down point event info. 336 */ 337 void storeBaseDownPoint(); 338 339 /** 340 * @brief Get move direction by move distance. 341 * @param dx the x axis distance between base point and current point. 342 * @param dy the y axis distance between base point and current point. 343 * @return the move direction, value range is MoveGirectionType. 344 */ 345 int32_t GetSwipeDirection(const int32_t dx, const int32_t dy); 346 347 /** 348 * @brief Get the base point Item info by point Id. 349 * @param basePointerIterm to save th base pointItem info. 350 * @param pId the point Id to get the pointItem. 351 * @param pointInfo the touch down event point info storage. 352 * @return true if get base pointItem success, else false. 353 */ 354 bool GetBasePointItem(MMI::PointerEvent::PointerItem &basePointerIterm, 355 int32_t pId, std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> &pointInfo); 356 357 /** 358 * @brief Save move gesture path info. 359 * @param event the touch event to be handled. 360 * @param pId the point Id to be handled. 361 * @param pointerIterm the point Item info to be saved. 362 * @param dx the x axis distance between base point and current point. 363 * @param dy the y axis distance between base point and current point. 364 */ 365 void SaveMoveGesturePointerInfo(MMI::PointerEvent &event, 366 const int32_t pId, const MMI::PointerEvent::PointerItem &pointerIterm, const int32_t dx, const int32_t dy); 367 368 /** 369 * @brief recognize the move path is correct and match a move gesture. 370 * @param path move path pointer info storage. 371 * @return true if the move path is correct and match a move gesture, else false. 372 */ 373 bool recognizeGesturePath(const std::vector<Pointer> &path); 374 375 /** 376 * @brief Get the matched move gesture by moveDirection and fingerNum. 377 * @return the matched gesture Id. 378 */ 379 GestureType GetMoveGestureId(); 380 381 /** 382 * @brief whether the multi finger move event match a move gesture. 383 * @return true if multi finger move event match a move gesture, else false. 384 */ 385 bool IsMoveGestureRecognize(); 386 387 /** 388 * @brief Save move gesture path info when finger up. 389 * @param event the touch event to be handled. 390 */ 391 void StoreUpPointInPointerRoute(MMI::PointerEvent &event); 392 393 /** 394 * @brief Handle the first touch down event. 395 * @param event the touch event to be handled. 396 */ 397 void HanleFirstTouchDownEvent(MMI::PointerEvent &event); 398 399 /** 400 * @brief Handle the continue touch down event. 401 * @param event the touch event to be handled. 402 */ 403 void HandleContinueTouchDownEvent(MMI::PointerEvent &event); 404 405 /** 406 * @brief Handle the multi finger touch move event. 407 * @param event the touch event to be handled. 408 */ 409 void HandleMultiFingerMoveEvent(MMI::PointerEvent &event); 410 411 /** 412 * @brief Handle the touch up event, not a move gesture. 413 * @param event the touch event to be handled. 414 */ 415 void HandleMultiFingerTouchUpEvent(MMI::PointerEvent &event); 416 417 /** 418 * @brief Handle the continue touch down event, decide whether it is a multi tap event. 419 * @param event the touch event to be handled. 420 * @param fingerNum the touch down fingerNum to be handled. 421 */ 422 void HandleMultiTapEvent(MMI::PointerEvent &event, const int32_t fingerNum); 423 424 float touchSlop_ = 0.0f; 425 int32_t doubleTapOffsetThresh_ = 0; 426 int32_t targetFingers_ = -1; // touch down finger numbers before first time the finger touch up 427 uint32_t addContinueTapNum_ = 0; // total number of touch down, except the first touch down 428 int32_t multiFingerGestureState_ = 0; // recognize state, value is MultiFingerGestureState 429 int32_t fingerTouchUpState_ = FingerTouchUpState::ALL_FINGER_TOUCH_UP; 430 bool isFirstUp_ = 0; // whether the first time finger touch up 431 bool isMoveGestureRecognizing = false; // in move gesture recognize process or not 432 int32_t moveDirection = -1; 433 float mMinPixelsBetweenSamplesX_ = 0; 434 float mMinPixelsBetweenSamplesY_ = 0; 435 436 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> firstDownPoint_; // first round touch down points 437 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> currentDownPoint_; // current round touch down points 438 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> preGesturePoint_; // pre move event points 439 std::map<int32_t, std::shared_ptr<MMI::PointerEvent>> lastUpPoint_; // last time finger touch up points 440 std::map<int32_t, std::vector<Pointer>> pointerRoute_; 441 442 AccessibilityGestureRecognizeListener *listener_ = nullptr; 443 std::shared_ptr<MultiFingerGestureHandler> handler_ = nullptr; // multi finger gesture recognize event handler 444 std::shared_ptr<AppExecFwk::EventRunner> runner_ = nullptr; 445 }; 446 } // namespace Accessibility 447 } // namespace OHOS 448 #endif // ACCESSIBILITY_MULTIFINGER_MULTITAP_H