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