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_GESTURE_RECOGNIZER_H 17 #define ACCESSIBILITY_GESTURE_RECOGNIZER_H 18 19 #include <cmath> 20 #include <vector> 21 22 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER 23 #include "accessibility_display_manager.h" 24 #endif 25 #include "accessibility_event_info.h" 26 #include "accessible_ability_manager_service.h" 27 #include "event_handler.h" 28 #include "event_runner.h" 29 #include "pointer_event.h" 30 #include "singleton.h" 31 32 namespace OHOS { 33 namespace Accessibility { 34 const int64_t GESTURE_STARTED_TIME_THRESHOLD = 300000; // microsecond 35 const int64_t GESTURE_NOT_STARTED_TIME_THRESHOLD = 200000; // microsecond 36 const float DOUBLE_TAP_SLOP = 100.0f; 37 const int64_t MIN_DOUBLE_TAP_TIME = 40000; // microsecond 38 const int64_t DOUBLE_TAP_TIMEOUT = 300000; // microsecond 39 const int64_t LONG_PRESS_TIMEOUT = 400000; // microsecond 40 const int64_t TAP_INTERVAL_TIMEOUT = 100000; // microsecond 41 const float DEGREES_THRESHOLD = 0.0f; 42 const int32_t DIRECTION_NUM = 4; 43 const int64_t US_TO_MS = 1000; 44 #define CALCULATION_DIMENSION(xdpi) ((xdpi) * 0.25f) 45 #define MIN_PIXELS(xyDpi) ((xyDpi) * 0.1f) 46 47 struct Pointer { 48 float px_; 49 float py_; 50 }; 51 52 class AccessibilityGestureRecognizer; 53 class GestureHandler : public AppExecFwk::EventHandler { 54 public: 55 GestureHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner, AccessibilityGestureRecognizer &server); 56 virtual ~GestureHandler() = default; 57 /** 58 * @brief Process the event of install system bundles. 59 * @param event Indicates the event to be processed. 60 */ 61 virtual void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; 62 private: 63 AccessibilityGestureRecognizer &server_; 64 }; 65 66 class AccessibilityGestureRecognizeListener { 67 public: 68 /** 69 * @brief A destructor used to delete the listener instance. 70 */ 71 virtual ~AccessibilityGestureRecognizeListener() = default; 72 73 /** 74 * @brief The callback function when lifted the finger on the second tap of a double tap. 75 * 76 * @param event the touch event received. 77 * @return true if the event is consumed, else false 78 */ 79 virtual bool OnDoubleTap(MMI::PointerEvent &event); 80 81 /** 82 * @brief The callback function when recognized an event stream as a gesture. 83 * @return true if the event is consumed, else false 84 */ 85 virtual bool OnStarted(); 86 87 /** 88 * @brief The callback function when recognized an event stream as a multi finger gesture. 89 * @param isTwoFingerGesture whether the gesture is triggered by two finger. 90 */ 91 virtual void MultiFingerGestureOnStarted(bool isTwoFingerGesture); 92 93 /** 94 * @brief The callback function when decided the event stream is a gesture. 95 * @param gestureId the recognized gesture ID. 96 * @return true if the event is consumed, else false 97 */ 98 virtual bool OnCompleted(GestureType gestureId); 99 100 /** 101 * @brief The callback function when decided the event stream is a multi finger gesture. 102 * @param gestureId the recognized gesture ID. 103 */ 104 virtual void MultiFingerGestureOnCompleted(GestureType gestureId); 105 106 /** 107 * @brief The callback function when decided an event stream doesn't match any known gesture. 108 * @param event the touch event received. 109 * @return true if the event is consumed, else false 110 */ 111 virtual bool OnCancelled(MMI::PointerEvent &event); 112 113 /** 114 * @brief The callback function when decided an event stream doesn't match any known multi finger gesture. 115 * @param isNoDelayFlag whether the gesture recognize process is immediately canceled. 116 */ 117 virtual void MultiFingerGestureOnCancelled(const bool isNoDelayFlag); 118 }; 119 120 class AccessibilityGestureRecognizer : public AppExecFwk::EventHandler { 121 public: 122 static constexpr uint32_t LONG_PRESS_MSG = 1; 123 static constexpr uint32_t SINGLE_TAP_MSG = 2; 124 125 /** 126 * @brief A constructor used to create a accessibilityGestureRecognizer instance. 127 */ 128 AccessibilityGestureRecognizer(); 129 130 /** 131 * @brief A destructor used to delete the accessibilityGestureRecognizer instance. 132 */ ~AccessibilityGestureRecognizer()133 ~AccessibilityGestureRecognizer() {} 134 135 /** 136 * @brief Register GestureRecognizeListener. 137 * @param listener the listener from touchguide 138 */ 139 void RegisterListener(AccessibilityGestureRecognizeListener& listener); 140 141 /** 142 * @brief Register GestureRecognizeListener. 143 * @param listener the listener from touchguide 144 */ 145 void UnregisterListener(); 146 147 /** 148 * @brief Determine whether a single tap has occurred. 149 * @return true if a single tap has occurred, else false. 150 */ IsfirstTap()151 bool IsfirstTap() 152 { 153 return isFirstTapUp_; 154 } 155 156 /** 157 * @brief Handle a touch event. If an action is completed, the appropriate callback is called. 158 * 159 * @param event the touch event to be handled. 160 * @param rawEvent The raw touch event. 161 * @return true if the gesture be recognized, else false 162 */ 163 bool OnPointerEvent(MMI::PointerEvent &event); 164 165 /** 166 * @brief Clear state. 167 */ 168 void Clear(); 169 170 /** 171 * @brief Judge whether the double click and long press gesture is recognized. 172 * @param event the touch event from touchguide 173 */ 174 void MaybeRecognizeLongPress(MMI::PointerEvent &event); 175 176 /** 177 * @brief If a single tap completed. 178 */ 179 void SingleTapDetected(); 180 181 /** 182 * @brief Set isLongpress_ flag; 183 * @param value set isLongpress_ flag 184 */ SetIsLongpress(bool value)185 void SetIsLongpress (bool value) 186 { 187 isLongpress_ = value; 188 } 189 190 /** 191 * @brief Get pCurDown_ ptr. 192 */ GetCurDown()193 std::shared_ptr<MMI::PointerEvent> GetCurDown() 194 { 195 return pCurDown_; 196 } 197 198 /** 199 * @brief Get continueDown_ flag. 200 */ GetContinueDown()201 bool GetContinueDown() 202 { 203 return continueDown_; 204 } 205 206 private: 207 /** 208 * @brief Recognize the standard gesture. 209 * @param event the touch event from touchguide 210 * @return true if the standard gesture be recognized, else false 211 */ 212 bool StandardGestureRecognizer(MMI::PointerEvent &event); 213 214 /** 215 * @brief A double tap has occurred, call OnDoubleTap callback. 216 * @param event the touch event from touchguide 217 * @return true if the DoubleTap be recognized, else false 218 */ 219 bool DoubleTapRecognized(MMI::PointerEvent &event); 220 221 /** 222 * @brief Recognize gestures based on the sequence of motions. 223 * @param event the touch event from touchguide 224 * @return true if the Direction be recognized, else false 225 */ 226 bool recognizeDirectionGesture(MMI::PointerEvent &event); 227 228 /** 229 * @brief Handle the down event from touchguide. 230 * @param event the touch event from touchguide 231 */ 232 void HandleTouchDownEvent(MMI::PointerEvent &event); 233 234 /** 235 * @brief Handle the move event from touchguide. 236 * @param event the touch event from touchguide 237 */ 238 bool HandleTouchMoveEvent(MMI::PointerEvent &event); 239 240 /** 241 * @brief Handle the up event from touchguide. 242 * @param event the touch event from touchguide 243 */ 244 bool HandleTouchUpEvent(MMI::PointerEvent &event); 245 246 /** 247 * @brief Check if it's double tap. 248 * @param event the touch event from touchguide 249 * @return true if it's double tap, else false 250 */ 251 bool isDoubleTap(MMI::PointerEvent &event); 252 253 /** 254 * @brief Cancel the gesture. 255 */ 256 void StandardGestureCanceled(); 257 258 /** 259 * @brief Get pointer path. 260 * @param route all pointer route 261 * @return the vector of PointerPath 262 */ 263 std::vector<Pointer> GetPointerPath(std::vector<Pointer> &route); 264 265 /** 266 * @brief Get swipe direction. 267 * @param firstP the start point 268 * @param secondP the endpoint 269 * @return the type of swipe direction 270 */ 271 int32_t GetSwipeDirection(Pointer firstP, Pointer secondP); 272 273 static constexpr int32_t SWIPE_UP = 0; 274 static constexpr int32_t SWIPE_DOWN = 1; 275 static constexpr int32_t SWIPE_LEFT = 2; 276 static constexpr int32_t SWIPE_RIGHT = 3; 277 278 static constexpr GestureType GESTURE_DIRECTION[DIRECTION_NUM] = { 279 GestureType::GESTURE_SWIPE_UP, 280 GestureType::GESTURE_SWIPE_DOWN, 281 GestureType::GESTURE_SWIPE_LEFT, 282 GestureType::GESTURE_SWIPE_RIGHT 283 }; 284 285 static constexpr GestureType GESTURE_DIRECTION_TO_ID[DIRECTION_NUM][DIRECTION_NUM] = { 286 { 287 GestureType::GESTURE_SWIPE_UP, 288 GestureType::GESTURE_SWIPE_UP_THEN_DOWN, 289 GestureType::GESTURE_SWIPE_UP_THEN_LEFT, 290 GestureType::GESTURE_SWIPE_UP_THEN_RIGHT, 291 }, 292 { 293 GestureType::GESTURE_SWIPE_DOWN_THEN_UP, 294 GestureType::GESTURE_SWIPE_DOWN, 295 GestureType::GESTURE_SWIPE_DOWN_THEN_LEFT, 296 GestureType::GESTURE_SWIPE_DOWN_THEN_RIGHT, 297 298 }, 299 { 300 GestureType::GESTURE_SWIPE_LEFT_THEN_UP, 301 GestureType::GESTURE_SWIPE_LEFT_THEN_DOWN, 302 GestureType::GESTURE_SWIPE_LEFT, 303 GestureType::GESTURE_SWIPE_LEFT_THEN_RIGHT, 304 305 }, 306 { 307 GestureType::GESTURE_SWIPE_RIGHT_THEN_UP, 308 GestureType::GESTURE_SWIPE_RIGHT_THEN_DOWN, 309 GestureType::GESTURE_SWIPE_RIGHT_THEN_LEFT, 310 GestureType::GESTURE_SWIPE_RIGHT 311 } 312 }; 313 314 bool continueDown_ = false; 315 bool isLongpress_ = false; 316 bool isDoubleTapdetecting_ = false; 317 bool isTapDown_ = false; 318 bool isFirstTapUp_ = false; 319 bool isDoubleTap_ = false; 320 bool isRecognizingGesture_ = false; 321 bool isGestureStarted_ = false; 322 int64_t startTime_ = 0; // microsecond 323 float xMinPixels_ = 0; 324 float yMinPixels_ = 0; 325 float threshold_ = 0; 326 int32_t doubleTapScaledSlop_ = 0; 327 MMI::PointerEvent::PointerItem prePointer_ = {}; 328 MMI::PointerEvent::PointerItem startPointer_ = {}; 329 std::vector<Pointer> pointerRoute_ {}; 330 AccessibilityGestureRecognizeListener *listener_ = nullptr; 331 std::unique_ptr<MMI::PointerEvent> pPreUp_ = nullptr; 332 std::shared_ptr<MMI::PointerEvent> pCurDown_ = nullptr; 333 std::shared_ptr<GestureHandler> handler_ = nullptr; 334 std::shared_ptr<AppExecFwk::EventRunner> runner_ = nullptr; 335 }; 336 } // namespace Accessibility 337 } // namespace OHOS 338 #endif // ACCESSIBILITY_GESTURE_RECOGNIZER_H