touch_disposition_gesture_filter.h revision 116680a4aac90f2aa7413d9095a592090648e557
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
15namespace ui {
16
17// Interface with which the |TouchDispositionGestureFilter| forwards gestures
18// for a given touch event.
19class 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.
26class 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  bool needs_tap_ending_event_;
99  bool needs_show_press_event_;
100  bool needs_fling_ending_event_;
101  bool needs_scroll_ending_event_;
102
103  DISALLOW_COPY_AND_ASSIGN(TouchDispositionGestureFilter);
104};
105
106}  // namespace ui
107
108#endif  // UI_EVENTS_GESTURE_DETECTION_TOUCH_DISPOSITION_GESTURE_FILTER_H_
109