• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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