Home | History | Annotate | Download | only in gesture_detection
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef UI_EVENTS_GESTURE_DETECTION_TOUCH_DISPOSITION_GESTURE_FILTER_H_
      6 #define UI_EVENTS_GESTURE_DETECTION_TOUCH_DISPOSITION_GESTURE_FILTER_H_
      7 
      8 #include <queue>
      9 
     10 #include "ui/events/event_constants.h"
     11 #include "ui/events/gesture_detection/bitset_32.h"
     12 #include "ui/events/gesture_detection/gesture_detection_export.h"
     13 #include "ui/events/gesture_detection/gesture_event_data_packet.h"
     14 
     15 namespace ui {
     16 
     17 // Interface with which the |TouchDispositionGestureFilter| forwards gestures
     18 // for a given touch event.
     19 class GESTURE_DETECTION_EXPORT TouchDispositionGestureFilterClient {
     20  public:
     21   virtual void ForwardGestureEvent(const GestureEventData&) = 0;
     22 };
     23 
     24 // Given a stream of touch-derived gesture packets, produces a refined gesture
     25 // sequence based on the ack dispositions of the generating touch events.
     26 class GESTURE_DETECTION_EXPORT TouchDispositionGestureFilter {
     27  public:
     28   explicit TouchDispositionGestureFilter(
     29       TouchDispositionGestureFilterClient* client);
     30   ~TouchDispositionGestureFilter();
     31 
     32   // To be called upon production of touch-derived gestures by the platform,
     33   // *prior* to the generating touch being forward to the renderer.  In
     34   // particular, |packet| contains [0, n] gestures that correspond to a given
     35   // touch event. It is imperative that a single packet is received for
     36   // *each* touch event, even those that did not produce a gesture.
     37   enum PacketResult {
     38     SUCCESS,              // Packet successfully queued.
     39     INVALID_PACKET_ORDER, // Packets were received in the wrong order, i.e.,
     40                           // TOUCH_BEGIN should always precede other packets.
     41     INVALID_PACKET_TYPE,  // Packet had an invalid type.
     42   };
     43   PacketResult OnGesturePacket(const GestureEventDataPacket& packet);
     44 
     45   // To be called upon receipt of *all* touch event acks.
     46   void OnTouchEventAck(bool event_consumed);
     47 
     48   // Whether there are any active gesture sequences still queued in the filter.
     49   bool IsEmpty() const;
     50 
     51  private:
     52   // A single GestureSequence corresponds to all gestures created
     53   // between the first finger down and the last finger up, including gestures
     54   // generated by timeouts from a statinoary finger.
     55   typedef std::queue<GestureEventDataPacket> GestureSequence;
     56 
     57   // Utility class for maintaining the touch and gesture handling state for the
     58   // current gesture sequence.
     59   class GestureHandlingState {
     60    public:
     61     GestureHandlingState();
     62 
     63     // To be called on each touch event ack.
     64     void OnTouchEventAck(bool event_consumed, bool is_touch_start_event);
     65 
     66     // Returns true iff the gesture should be dropped.
     67     bool Filter(EventType type);
     68 
     69    private:
     70     // True iff the sequence has had any touch down event consumed.
     71     bool start_touch_consumed_;
     72     // True iff the most recently ack'ed touch event was consumed.
     73     bool current_touch_consumed_;
     74     // If the previous gesture of a given type was dropped instead of being
     75     // dispatched, its type will occur in this set.
     76     BitSet32 last_gesture_of_type_dropped_;
     77   };
     78 
     79   void FilterAndSendPacket(const GestureEventDataPacket& packet);
     80   void SendGesture(const GestureEventData& gesture,
     81                    const GestureEventDataPacket& packet);
     82   void CancelTapIfNecessary(const GestureEventDataPacket& packet);
     83   void CancelFlingIfNecessary(const GestureEventDataPacket& packet);
     84   void EndScrollIfNecessary(const GestureEventDataPacket& packet);
     85   void PopGestureSequence();
     86   GestureSequence& Head();
     87   GestureSequence& Tail();
     88 
     89   TouchDispositionGestureFilterClient* client_;
     90   std::queue<GestureSequence> sequences_;
     91 
     92   GestureHandlingState state_;
     93 
     94   // Bookkeeping for inserting synthetic Gesture{Tap,Fling}Cancel events
     95   // when necessary, e.g., GestureTapCancel when scrolling begins, or
     96   // GestureFlingCancel when a user taps following a GestureFlingStart.
     97   int ending_event_motion_event_id_;
     98   MotionEvent::ToolType ending_event_primary_tool_type_;
     99   bool needs_tap_ending_event_;
    100   bool needs_show_press_event_;
    101   bool needs_fling_ending_event_;
    102   bool needs_scroll_ending_event_;
    103 
    104   DISALLOW_COPY_AND_ASSIGN(TouchDispositionGestureFilter);
    105 };
    106 
    107 }  // namespace ui
    108 
    109 #endif  // UI_EVENTS_GESTURE_DETECTION_TOUCH_DISPOSITION_GESTURE_FILTER_H_
    110