Home | History | Annotate | Download | only in input
      1 // Copyright 2013 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 CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_
      6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_
      7 
      8 #include <deque>
      9 #include <map>
     10 
     11 #include "base/basictypes.h"
     12 #include "content/common/content_export.h"
     13 #include "content/port/browser/event_with_latency_info.h"
     14 #include "content/port/common/input_event_ack_state.h"
     15 #include "third_party/WebKit/public/web/WebInputEvent.h"
     16 
     17 namespace content {
     18 
     19 class CoalescedWebTouchEvent;
     20 
     21 // Interface with which TouchEventQueue can forward touch events, and dispatch
     22 // touch event responses.
     23 class CONTENT_EXPORT TouchEventQueueClient {
     24  public:
     25   virtual ~TouchEventQueueClient() {}
     26 
     27   virtual void SendTouchEventImmediately(
     28       const TouchEventWithLatencyInfo& event) = 0;
     29 
     30   virtual void OnTouchEventAck(
     31       const TouchEventWithLatencyInfo& event,
     32       InputEventAckState ack_result) = 0;
     33 };
     34 
     35 // A queue for throttling and coalescing touch-events.
     36 class CONTENT_EXPORT TouchEventQueue {
     37  public:
     38 
     39   // The |client| must outlive the TouchEventQueue.
     40   explicit TouchEventQueue(TouchEventQueueClient* client);
     41   ~TouchEventQueue();
     42 
     43   // Adds an event to the queue. The event may be coalesced with previously
     44   // queued events (e.g. consecutive touch-move events can be coalesced into a
     45   // single touch-move event). The event may also be immediately forwarded to
     46   // the renderer (e.g. when there are no other queued touch event).
     47   void QueueEvent(const TouchEventWithLatencyInfo& event);
     48 
     49   // Notifies the queue that a touch-event has been processed by the renderer.
     50   // At this point, the queue may send one or more gesture events and/or
     51   // additional queued touch-events to the renderer.
     52   void ProcessTouchAck(InputEventAckState ack_result,
     53                        const ui::LatencyInfo& latency_info);
     54 
     55   // When GestureScrollBegin is received, we send a touch cancel to renderer,
     56   // route all the following touch events directly to client, and ignore the
     57   // ack for the touch cancel. When Gesture{ScrollEnd,FlingStart} is received,
     58   // resume the normal flow of sending touch events to the renderer.
     59   void OnGestureScrollEvent(const GestureEventWithLatencyInfo& gesture_event);
     60 
     61   // Empties the queue of touch events. This may result in any number of gesture
     62   // events being sent to the renderer.
     63   void FlushQueue();
     64 
     65   // Returns whether the currently pending touch event (waiting ACK) is for
     66   // a touch start event.
     67   bool IsPendingAckTouchStart() const;
     68 
     69   // Sets whether a delayed touch ack will cancel and flush the current
     70   // touch sequence.
     71   void SetAckTimeoutEnabled(bool enabled, size_t ack_timeout_delay_ms);
     72 
     73   bool empty() const WARN_UNUSED_RESULT {
     74     return touch_queue_.empty();
     75   }
     76 
     77   size_t size() const {
     78     return touch_queue_.size();
     79   }
     80 
     81   bool ack_timeout_enabled() const {
     82     return ack_timeout_enabled_;
     83   }
     84 
     85  private:
     86   class TouchTimeoutHandler;
     87   friend class TouchTimeoutHandler;
     88   friend class TouchEventQueueTest;
     89 
     90   bool HasTimeoutEvent() const;
     91   bool IsTimeoutRunningForTesting() const;
     92   const TouchEventWithLatencyInfo& GetLatestEventForTesting() const;
     93 
     94   // Walks the queue, checking each event for |ShouldForwardToRenderer()|.
     95   // If true, forwards the touch event and stops processing further events.
     96   // If false, acks the event with |INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS|.
     97   void TryForwardNextEventToRenderer();
     98 
     99   // Pops the touch-event from the top of the queue and sends it to the
    100   // TouchEventQueueClient. This reduces the size of the queue by one.
    101   void PopTouchEventToClient(InputEventAckState ack_result,
    102                              const ui::LatencyInfo& renderer_latency_info);
    103 
    104   bool ShouldForwardToRenderer(const blink::WebTouchEvent& event) const;
    105   void ForwardToRenderer(const TouchEventWithLatencyInfo& event);
    106   void UpdateTouchAckStates(const blink::WebTouchEvent& event,
    107                             InputEventAckState ack_result);
    108 
    109 
    110   // Handles touch event forwarding and ack'ed event dispatch.
    111   TouchEventQueueClient* client_;
    112 
    113   typedef std::deque<CoalescedWebTouchEvent*> TouchQueue;
    114   TouchQueue touch_queue_;
    115 
    116   // Maintain the ACK status for each touch point.
    117   typedef std::map<int, InputEventAckState> TouchPointAckStates;
    118   TouchPointAckStates touch_ack_states_;
    119 
    120   // Used to defer touch forwarding when ack dispatch triggers |QueueEvent()|.
    121   // If not NULL, |dispatching_touch_ack_| is the touch event of which the ack
    122   // is being dispatched.
    123   CoalescedWebTouchEvent* dispatching_touch_ack_;
    124 
    125   // Used to prevent touch timeout scheduling if we receive a synchronous
    126   // ack after forwarding a touch event to the client.
    127   bool dispatching_touch_;
    128 
    129   // Don't send touch events to the renderer while scrolling.
    130   bool no_touch_to_renderer_;
    131 
    132   // Whether an event in the current (multi)touch sequence was consumed by the
    133   // renderer.  The touch timeout will never be activated when this is true.
    134   bool renderer_is_consuming_touch_gesture_;
    135 
    136   // Optional handler for timed-out touch event acks, disabled by default.
    137   bool ack_timeout_enabled_;
    138   scoped_ptr<TouchTimeoutHandler> timeout_handler_;
    139 
    140   DISALLOW_COPY_AND_ASSIGN(TouchEventQueue);
    141 };
    142 
    143 }  // namespace content
    144 
    145 #endif  // CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_
    146