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