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