• 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_TOUCH_GUIDER_H
17 #define ACCESSIBILITY_TOUCH_GUIDER_H
18 
19 #include <string>
20 #include "accessibility_element_info.h"
21 #include "accessibility_element_operator_callback_stub.h"
22 #include "accessibility_event_transmission.h"
23 #include "accessibility_gesture_recognizer.h"
24 #include "accessibility_multifinger_multitap.h"
25 #include "accessible_ability_manager_service.h"
26 
27 namespace OHOS {
28 namespace Accessibility {
29 class TouchGuider;
30 
31 const int32_t MAX_POINTER_COUNT = 32;
32 const int64_t EXIT_GESTURE_REC_TIMEOUT = 2000; // millisecond
33 const double MAX_DRAG_GESTURE_COSINE = 0.525321989;
34 const int32_t MINI_POINTER_DISTANCE_DIP = 200;
35 const int32_t INDEX_0 = 0;
36 const int32_t INDEX_1 = 1;
37 const int32_t INIT_POINT_ID = -1;
38 const float INIT_MMIPOINT = 0.0f;
39 #define DIVIDE_2(num) ((num) / 2)
40 #define EPSINON 0.01
41 
42 /**
43  * @brief touch Guider state define
44  */
45 enum class TouchGuideState : int32_t {
46     TOUCH_GUIDING,
47     DRAGGING,
48     TRANSMITTING,
49     GESTURE_RECOGNIZING
50 };
51 
52 /**
53  * @brief Click location define
54  */
55 enum ClickLocation : int32_t {
56     CLICK_NONE,
57     CLICK_ACCESSIBILITY_FOCUS,
58     CLICK_LAST_TOUCH_GUIDE
59 };
60 
61 /**
62  * @brief struct to record injected pointers.
63  */
64 struct InjectedEventRecorder {
65     int32_t downPointers;
66     int32_t downPointerNum;
67     int64_t lastDownTime;
68     std::shared_ptr<MMI::PointerEvent> lastHoverEvent;
69 };
70 
71 /**
72  * @brief struct to record received pointers.
73  */
74 struct ReceivedEventRecorder {
75     int32_t pointerDownX[MAX_POINTER_COUNT];
76     int32_t pointerDownY[MAX_POINTER_COUNT];
77     int64_t pointerActionTime[MAX_POINTER_COUNT];
78     std::shared_ptr<MMI::PointerEvent> lastEvent;
79 };
80 
81 enum ChangeAction : int32_t {
82     NO_CHANGE,
83     HOVER_MOVE,
84     POINTER_DOWN,
85     POINTER_UP,
86     POINTER_MOVE,
87 };
88 
89 class TGEventHandler : public AppExecFwk::EventHandler {
90 public:
91     TGEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner,
92                  TouchGuider &tgServer);
93     virtual ~TGEventHandler() = default;
94     /**
95      * @brief Process the event of install system bundles.
96      * @param event Indicates the event to be processed.
97      */
98     virtual void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override;
99 
100 private:
101     /**
102      * @brief Send HoverEnter and HoverMove to Multimodal.
103      */
104     void HoverEnterAndMoveRunner();
105 
106     /**
107      * @brief Send HoverExit to Multimodal.
108      */
109     void HoverExitRunner();
110     TouchGuider &tgServer_;
111 };
112 
113 class TouchGuider : public EventTransmission {
114 public:
115     static constexpr uint32_t EXIT_GESTURE_REC_MSG = 0;
116     static constexpr uint32_t SEND_HOVER_ENTER_MOVE_MSG = 1;
117     static constexpr uint32_t SEND_HOVER_EXIT_MSG = 2;
118     static constexpr uint32_t SEND_TOUCH_INTERACTION_END_MSG = 3;
119     static constexpr uint32_t SEND_TOUCH_GUIDE_END_MSG = 4;
120 
121     /**
122      * @brief A constructor used to create a touchGuide instance.
123      */
124     TouchGuider();
125 
126     /**
127      * @brief A destructor used to delete the touchGuide instance.
128      */
~TouchGuider()129     ~TouchGuider() {}
130 
131     /**
132      * @brief TouchGuide start up.
133      */
134     void StartUp();
135 
136     /**
137      * @brief Handle pointer events from previous event stream node.
138      *
139      * @param event  the pointer event to be handled.
140      * @return true: the event has been processed and does not need to be passed to the next node;
141      *         false: the event is not processed.
142      */
143     bool OnPointerEvent(MMI::PointerEvent &event) override;
144 
145     /**
146      * @brief Destroy event state.
147      */
148     void DestroyEvents() override;
149 
150     /**
151      * @brief Send pointer down event to multimodal input.
152      * @param event event the touch event from Multimodal, set the down point to the event and send.
153      * @param action point action send to multimode.
154      */
155     void SendPointerDownEventToMultimodal(MMI::PointerEvent event, int32_t action);
156 
157     /**
158      * @brief Send event to multimodal input.
159      * @param event the event prepared to send to Multimodal
160      * @param action the action of the event
161      */
162     void SendEventToMultimodal(MMI::PointerEvent &event, int32_t action);
163 
164     /**
165      * @brief Send accessibility event to specific AccessibleAbility.
166      * @param eventType the type of the event
167      */
168     void SendAccessibilityEventToAA(EventType eventType);
169 
170     /**
171      * @brief Send gesture event to specific AccessibleAbility.
172      * @param gestureId the gesture id of the event
173      */
174     void SendGestureEventToAA(GestureType gestureId);
175 
176     /**
177      * @brief Get hover enter and move event.
178      * @return Returns pointerEvents_ list.
179      */
180     std::list<MMI::PointerEvent> getHoverEnterAndMoveEvent();
181 
182     /**
183      * @brief Clear hover enter and move event.
184      */
185     void ClearHoverEnterAndMoveEvent();
186 
187     /**
188      * @brief Get last received event.
189      * @return Returns last event ptr.
190      */
191     std::shared_ptr<MMI::PointerEvent> getLastReceivedEvent();
192 
193      /* For TouchGuide */
OnTouchInteractionStart()194     inline void OnTouchInteractionStart()
195     {
196         isTouchStart_ = true;
197     }
198 
OnTouchInteractionEnd()199     inline void OnTouchInteractionEnd()
200     {
201         isTouchStart_ = false;
202     }
203 
204     /**
205      * @brief whether touch guide end.
206      * @return true if touch guide end, else false.
207      */
IsTouchInteractionEnd()208     inline bool IsTouchInteractionEnd()
209     {
210         return isTouchStart_ == false;
211     }
212 
213     /**
214      * @brief Perform action on Accessibility Focus.
215      * @param action the action of Accessibility node.
216      * @return Returns true if the action perform successfully; returns false code otherwise.
217      */
218     bool ExecuteActionOnAccessibilityFocused(const ActionType &action);
219 
220     static int64_t lastDoubleTapTime;
221 private:
222     class TouchGuideListener : public AccessibilityGestureRecognizeListener {
223     public:
224         /**
225          * @brief A constructor used to create a TouchGuideListener instance.
226          */
TouchGuideListener(TouchGuider & server)227         explicit TouchGuideListener(TouchGuider &server) : server_(server) {};
228 
229         /**
230          * @brief Prepare to send the event corresponding to the single tap to the Multimodal.
231          * @param event the touch event from Multimodal
232          */
233         bool OnDoubleTap(MMI::PointerEvent &event) override;
234 
235         /**
236          * @brief Send GESTURE_BEGIN to AccessibleAbility.
237          */
238         bool OnStarted() override;
239 
240         /**
241          * @brief Send GESTURE_BEGIN to AccessibleAbility when multi finger gesture start.
242          * @param isTwoFingerGesture whether the gesture is triggered by two finger.
243          */
244         void MultiFingerGestureOnStarted(bool isTwoFingerGesture) override;
245 
246         /**
247          * @brief Send GESTURE_END and TOUCH_END to AccessibleAbility.
248          * @param gestureId the id of gesture
249          */
250         bool OnCompleted(GestureType gestureId) override;
251 
252         /**
253          * @brief Send GESTURE_END and TOUCH_END to AccessibleAbility when multi finger gesture complete.
254          * @param gestureId the id of gesture.
255          */
256         void MultiFingerGestureOnCompleted(GestureType gestureId) override;
257 
258         /**
259          * @brief The gesture has been cancelled.
260          * @param event the touch event from Multimodal
261          */
262         bool OnCancelled(MMI::PointerEvent &event) override;
263 
264         /**
265          * @brief The gesture has been cancelled.
266          * @param isNoDelayFlag  whether the gesture recognize process is immediately canceled.
267          */
268         void MultiFingerGestureOnCancelled(const bool isNoDelayFlag) override;
269     private:
270         TouchGuider &server_;
271     };
272 
273     class ElementOperatorCallbackImpl : public AccessibilityElementOperatorCallbackStub {
274     public:
275         ElementOperatorCallbackImpl() = default;
276         ~ElementOperatorCallbackImpl() = default;
277 
278         virtual void SetSearchElementInfoByAccessibilityIdResult(const std::vector<AccessibilityElementInfo> &infos,
279             const int32_t requestId) override;
280         virtual void SetSearchElementInfoByTextResult(const std::vector<AccessibilityElementInfo> &infos,
281             const int32_t requestId) override;
282         virtual void SetFindFocusedElementInfoResult(const AccessibilityElementInfo &info,
283             const int32_t requestId) override;
284         virtual void SetFocusMoveSearchResult(const AccessibilityElementInfo &info, const int32_t requestId) override;
285         virtual void SetExecuteActionResult(const bool succeeded, const int32_t requestId) override;
286 
287     private:
288         std::promise<void> promise_;
289         bool executeActionResult_ = false;
290         AccessibilityElementInfo accessibilityInfoResult_ = {};
291         std::vector<AccessibilityElementInfo> elementInfosResult_;
292 
293         friend class TouchGuider;
294     };
295 
296     /**
297      * @brief Determine whether to clear the touchguide.
298      */
299     void Clear();
300 
301     /**
302      * @brief clear the touchguide.
303      * @param event the last event from Multimodal
304      */
305     void Clear(MMI::PointerEvent &event);
306 
307     /**
308      * @brief Handle touch events on touchExploring state.
309      * @param event the touch event from Multimodal
310      */
311     void HandleTouchGuidingState(MMI::PointerEvent &event);
312 
313     /**
314      * @brief Handle touch events on dragging state.
315      * @param event the touch event from Multimodal
316      */
317     void HandleDraggingState(MMI::PointerEvent &event);
318 
319     /**
320      * @brief Handle touch events on transmitting state.
321      * @param event the touch event from Multimodal
322      */
323     void HandleTransmitingState(MMI::PointerEvent &event);
324 
325     /**
326      * @brief Determine whether it is a drag gesture.
327      * @param event the touch event from Multimodal
328      * @return whether the dragGesture is accepted.
329      */
330     bool IsDragGestureAccept(MMI::PointerEvent &event);
331 
332     /**
333      * @brief Get the offset of current points and touch down points.
334      * @param event the current touch event from Multimodal.
335      * @param firstPointOffset the first finger offset result, xAxis offset and yAxis offset.
336      * @param firstPointOffset the second finger offset result, xAxis offset and yAxis offset.
337      */
338     void GetPointOffset(MMI::PointerEvent &event, std::vector<float> &firstPointOffset,
339         std::vector<float> &secondPointOffset) const;
340 
341     /**
342      * @brief Determine whether it is a move gesture.
343      * @param event the touch event from Multimodal.
344      * @return whether this is a scolling.
345      */
346     bool IsRealMoveState(MMI::PointerEvent &event) const;
347 
348     /**
349      * @brief Get Angle Cos value.
350      * @param offsetX the X value
351      * @param offsetY the Y value
352      * @param isGetX whether is the Angle corresponding to the X axis
353      * @return Angle Cos value.
354      */
355     float GetAngleCos(float offsetX, float offsetY, bool isGetX);
356 
357     /**
358      * @brief Get the info of injected event.
359      * @param event the event prepared to send to Multimodal
360      */
361     void RecordInjectedEvent(MMI::PointerEvent &event);
362 
363     /**
364      * @brief Get the info of Received event.
365      * @param event event the touch event from Multimodal
366      */
367     void RecordReceivedEvent(MMI::PointerEvent &event);
368 
369     /**
370      * @brief Clear received recorder info.
371      */
372     void ClearReceivedEventRecorder();
373 
374     /**
375      * @brief Clear Injected recorder info.
376      */
377     void ClearInjectedEventRecorder();
378 
379     /**
380      * @brief Send exit event to multimodal.
381      */
382     void SendExitEvents();
383 
384     /**
385      * @brief Send all down events to multimodal.
386      * @param event the event prepared to send to Multimodal
387      */
388     void SendAllDownEvents(MMI::PointerEvent &event);
389 
390     /**
391      * @brief Send all up events to multimodal.
392      * @param event the event prepared to send to Multimodal
393      */
394     void SendAllUpEvents(MMI::PointerEvent &event);
395 
396     /**
397      * @brief Send all up events to multimodal.
398      * @param event the event prepared to send to Multimodal
399      */
400     void SendUpForAllInjectedEvent(MMI::PointerEvent &event);
401 
402     /**
403      * @brief Send exit message.
404      */
405     void PostGestureRecognizeExit();
406 
407     /**
408      * @brief Send enter and move message.
409      * @param event event the touch event from Multimodal
410      */
411     void PostHoverEnterAndMove(MMI::PointerEvent &event);
412 
413     /**
414      * @brief Send exit message.
415      */
416     void PostHoverExit();
417 
418     /**
419      * @brief Send accessibility event message.
420      * @param innerEventID the id of inner event
421      */
422     void PostAccessibilityEvent(uint32_t innerEventID);
423 
424     /**
425      * @brief Cancel message.
426      * @param innerEventID the id of inner event
427      */
428     void CancelPostEvent(uint32_t innerEventID);
429 
430     /**
431      * @brief Cancel message if it has been sent.
432      * @param innerEventID the id of inner event
433      */
434     void CancelPostEventIfNeed(uint32_t innerEventID);
435 
436     /**
437      * @brief Check whether it has been sending.
438      * @param innerEventID the id of inner event
439      */
440     bool HasEventPending(uint32_t innerEventID);
441 
442     /**
443      * @brief Force send and remove event.
444      * @param innerEventID the id of inner event
445      * @param event event the touch event from Multimodal
446      */
447     void ForceSendAndRemoveEvent(uint32_t innerEventID, MMI::PointerEvent &event);
448 
449     /**
450      * @brief Handle down events on touchExploring state.
451      * @param event event the touch event from Multimodal
452      */
453     void HandleTouchGuidingStateInnerDown(MMI::PointerEvent &event);
454 
455     /**
456      * @brief Handle move events on touchExploring state.
457      * @param event event the touch event from Multimodal
458      */
459     void HandleTouchGuidingStateInnerMove(MMI::PointerEvent &event);
460 
461     /**
462      * @brief Handle move events on dragging state.
463      * @param event event the touch event from Multimodal
464      */
465     void HandleDraggingStateInnerMove(MMI::PointerEvent &event);
466 
467     /**
468      * @brief Ignore repeat execute action.
469      */
470     bool IgnoreRepeatExecuteAction();
471 
472     int32_t currentState_ = -1;
473     int32_t longPressPointId_ = INIT_POINT_ID;
474     float longPressOffsetX_ = INIT_MMIPOINT;
475     float longPressOffsetY_ = INIT_MMIPOINT;
476     bool isTouchStart_ = false;
477     bool isTouchGuiding_ = false;
478     ReceivedEventRecorder receivedRecorder_ = {};
479     InjectedEventRecorder injectedRecorder_ = {};
480     std::list<MMI::PointerEvent> pointerEvents_ {};
481     AccessibilityGestureRecognizer gestureRecognizer_;
482     AccessibilityMultiTapGestureRecognizer multiFingerGestureRecognizer_;
483     std::unique_ptr<TouchGuideListener> touchGuideListener_ = nullptr;
484     std::shared_ptr<TGEventHandler> handler_ = nullptr;
485     std::shared_ptr<AppExecFwk::EventRunner> runner_ = nullptr;
486 };
487 } // namespace Accessibility
488 } // namespace OHOS
489 #endif // ACCESSIBILITY_TOUCH_GUIDER_H