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_INPUT_ROUTER_IMPL_H_
      6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
      7 
      8 #include <queue>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/time/time.h"
     13 #include "content/browser/renderer_host/input/gesture_event_queue.h"
     14 #include "content/browser/renderer_host/input/input_router.h"
     15 #include "content/browser/renderer_host/input/touch_action_filter.h"
     16 #include "content/browser/renderer_host/input/touch_event_queue.h"
     17 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
     18 #include "content/common/input/input_event_stream_validator.h"
     19 #include "content/public/browser/native_web_keyboard_event.h"
     20 
     21 struct InputHostMsg_HandleInputEvent_ACK_Params;
     22 
     23 namespace IPC {
     24 class Sender;
     25 }
     26 
     27 namespace ui {
     28 struct LatencyInfo;
     29 }
     30 
     31 namespace content {
     32 
     33 class InputAckHandler;
     34 class InputRouterClient;
     35 class OverscrollController;
     36 class RenderWidgetHostImpl;
     37 struct DidOverscrollParams;
     38 
     39 // A default implementation for browser input event routing.
     40 class CONTENT_EXPORT InputRouterImpl
     41     : public NON_EXPORTED_BASE(InputRouter),
     42       public NON_EXPORTED_BASE(GestureEventQueueClient),
     43       public NON_EXPORTED_BASE(TouchEventQueueClient),
     44       public NON_EXPORTED_BASE(TouchpadTapSuppressionControllerClient) {
     45  public:
     46   struct CONTENT_EXPORT Config {
     47     Config();
     48     GestureEventQueue::Config gesture_config;
     49     TouchEventQueue::Config touch_config;
     50   };
     51 
     52   InputRouterImpl(IPC::Sender* sender,
     53                   InputRouterClient* client,
     54                   InputAckHandler* ack_handler,
     55                   int routing_id,
     56                   const Config& config);
     57   virtual ~InputRouterImpl();
     58 
     59   // InputRouter
     60   virtual void Flush() OVERRIDE;
     61   virtual bool SendInput(scoped_ptr<IPC::Message> message) OVERRIDE;
     62   virtual void SendMouseEvent(
     63       const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
     64   virtual void SendWheelEvent(
     65       const MouseWheelEventWithLatencyInfo& wheel_event) OVERRIDE;
     66   virtual void SendKeyboardEvent(
     67       const NativeWebKeyboardEvent& key_event,
     68       const ui::LatencyInfo& latency_info,
     69       bool is_keyboard_shortcut) OVERRIDE;
     70   virtual void SendGestureEvent(
     71       const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
     72   virtual void SendTouchEvent(
     73       const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
     74   virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const OVERRIDE;
     75   virtual bool ShouldForwardTouchEvent() const OVERRIDE;
     76   virtual void OnViewUpdated(int view_flags) OVERRIDE;
     77   virtual bool HasPendingEvents() const OVERRIDE;
     78 
     79   // IPC::Listener
     80   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
     81 
     82 private:
     83   friend class InputRouterImplTest;
     84 
     85   // TouchpadTapSuppressionControllerClient
     86   virtual void SendMouseEventImmediately(
     87       const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
     88 
     89   // TouchEventQueueClient
     90   virtual void SendTouchEventImmediately(
     91       const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
     92   virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
     93                                InputEventAckState ack_result) OVERRIDE;
     94 
     95   // GetureEventFilterClient
     96   virtual void SendGestureEventImmediately(
     97       const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
     98   virtual void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
     99                                  InputEventAckState ack_result) OVERRIDE;
    100 
    101   bool SendMoveCaret(scoped_ptr<IPC::Message> message);
    102   bool SendSelectRange(scoped_ptr<IPC::Message> message);
    103   bool Send(IPC::Message* message);
    104 
    105   // Filters and forwards |input_event| to the appropriate handler.
    106   void FilterAndSendWebInputEvent(const blink::WebInputEvent& input_event,
    107                                   const ui::LatencyInfo& latency_info,
    108                                   bool is_keyboard_shortcut);
    109 
    110   // Utility routine for filtering and forwarding |input_event| to the
    111   // appropriate handler. |input_event| will be offered to the overscroll
    112   // controller, client and renderer, in that order.
    113   void OfferToHandlers(const blink::WebInputEvent& input_event,
    114                        const ui::LatencyInfo& latency_info,
    115                        bool is_keyboard_shortcut);
    116 
    117   // Returns true if |input_event| was consumed by the overscroll controller.
    118   bool OfferToOverscrollController(const blink::WebInputEvent& input_event,
    119                                    const ui::LatencyInfo& latency_info);
    120 
    121   // Returns true if |input_event| was consumed by the client.
    122   bool OfferToClient(const blink::WebInputEvent& input_event,
    123                      const ui::LatencyInfo& latency_info);
    124 
    125   // Returns true if |input_event| was successfully sent to the renderer
    126   // as an async IPC Message.
    127   bool OfferToRenderer(const blink::WebInputEvent& input_event,
    128                        const ui::LatencyInfo& latency_info,
    129                        bool is_keyboard_shortcut);
    130 
    131   // A data structure that attaches some metadata to a WebMouseWheelEvent
    132   // and its latency info.
    133   struct QueuedWheelEvent {
    134     QueuedWheelEvent();
    135     QueuedWheelEvent(const MouseWheelEventWithLatencyInfo& event,
    136                      bool synthesized_from_pinch);
    137     ~QueuedWheelEvent();
    138 
    139     MouseWheelEventWithLatencyInfo event;
    140     bool synthesized_from_pinch;
    141   };
    142 
    143   // Enqueue or send a mouse wheel event.
    144   void SendWheelEvent(const QueuedWheelEvent& wheel_event);
    145 
    146   // Given a Touchpad GesturePinchUpdate event, create and send a synthetic
    147   // wheel event for it.
    148   void SendSyntheticWheelEventForPinch(
    149       const GestureEventWithLatencyInfo& pinch_event);
    150 
    151   // IPC message handlers
    152   void OnInputEventAck(const InputHostMsg_HandleInputEvent_ACK_Params& ack);
    153   void OnDidOverscroll(const DidOverscrollParams& params);
    154   void OnMsgMoveCaretAck();
    155   void OnSelectRangeAck();
    156   void OnHasTouchEventHandlers(bool has_handlers);
    157   void OnSetTouchAction(TouchAction touch_action);
    158 
    159   // Indicates the source of an ack provided to |ProcessInputEventAck()|.
    160   // The source is tracked by |current_ack_source_|, which aids in ack routing.
    161   enum AckSource {
    162     RENDERER,
    163     CLIENT,
    164     IGNORING_DISPOSITION,
    165     ACK_SOURCE_NONE
    166   };
    167   // Note: This function may result in |this| being deleted, and as such
    168   // should be the last method called in any internal chain of event handling.
    169   void ProcessInputEventAck(blink::WebInputEvent::Type event_type,
    170                             InputEventAckState ack_result,
    171                             const ui::LatencyInfo& latency_info,
    172                             AckSource ack_source);
    173 
    174   // Dispatches the ack'ed event to |ack_handler_|.
    175   void ProcessKeyboardAck(blink::WebInputEvent::Type type,
    176                           InputEventAckState ack_result);
    177 
    178   // Forwards a valid |next_mouse_move_| if |type| is MouseMove.
    179   void ProcessMouseAck(blink::WebInputEvent::Type type,
    180                        InputEventAckState ack_result);
    181 
    182   // Dispatches the ack'ed event to |ack_handler_|, forwarding queued events
    183   // from |coalesced_mouse_wheel_events_|.
    184   void ProcessWheelAck(InputEventAckState ack_result,
    185                        const ui::LatencyInfo& latency);
    186 
    187   // Forwards the event ack to |gesture_event_queue|, potentially triggering
    188   // dispatch of queued gesture events.
    189   void ProcessGestureAck(blink::WebInputEvent::Type type,
    190                          InputEventAckState ack_result,
    191                          const ui::LatencyInfo& latency);
    192 
    193   // Forwards the event ack to |touch_event_queue_|, potentially triggering
    194   // dispatch of queued touch events, or the creation of gesture events.
    195   void ProcessTouchAck(InputEventAckState ack_result,
    196                        const ui::LatencyInfo& latency);
    197 
    198   // Called when a touch timeout-affecting bit has changed, in turn toggling the
    199   // touch ack timeout feature of the |touch_event_queue_| as appropriate. Input
    200   // to that determination includes current view properties and the allowed
    201   // touch action. Note that this will only affect platforms that have a
    202   // non-zero touch timeout configuration.
    203   void UpdateTouchAckTimeoutEnabled();
    204 
    205   // If a flush has been requested, signals a completed flush to the client if
    206   // all events have been dispatched (i.e., |HasPendingEvents()| is false).
    207   void SignalFlushedIfNecessary();
    208 
    209   bool IsInOverscrollGesture() const;
    210 
    211   int routing_id() const { return routing_id_; }
    212 
    213 
    214   IPC::Sender* sender_;
    215   InputRouterClient* client_;
    216   InputAckHandler* ack_handler_;
    217   int routing_id_;
    218 
    219   // (Similar to |mouse_move_pending_|.) True while waiting for SelectRange_ACK.
    220   bool select_range_pending_;
    221 
    222   // (Similar to |next_mouse_move_|.) The next SelectRange to send, if any.
    223   scoped_ptr<IPC::Message> next_selection_range_;
    224 
    225   // (Similar to |mouse_move_pending_|.) True while waiting for MoveCaret_ACK.
    226   bool move_caret_pending_;
    227 
    228   // (Similar to |next_mouse_move_|.) The next MoveCaret to send, if any.
    229   scoped_ptr<IPC::Message> next_move_caret_;
    230 
    231   // True if a mouse move event was sent to the render view and we are waiting
    232   // for a corresponding InputHostMsg_HandleInputEvent_ACK message.
    233   bool mouse_move_pending_;
    234 
    235   // The next mouse move event to send (only non-null while mouse_move_pending_
    236   // is true).
    237   scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move_;
    238 
    239   // (Similar to |mouse_move_pending_|.) True if a mouse wheel event was sent
    240   // and we are waiting for a corresponding ack.
    241   bool mouse_wheel_pending_;
    242   QueuedWheelEvent current_wheel_event_;
    243 
    244   // (Similar to |next_mouse_move_|.) The next mouse wheel events to send.
    245   // Unlike mouse moves, mouse wheel events received while one is pending are
    246   // coalesced (by accumulating deltas) if they match the previous event in
    247   // modifiers. On the Mac, in particular, mouse wheel events are received at a
    248   // high rate; not waiting for the ack results in jankiness, and using the same
    249   // mechanism as for mouse moves (just dropping old events when multiple ones
    250   // would be queued) results in very slow scrolling.
    251   typedef std::deque<QueuedWheelEvent> WheelEventQueue;
    252   WheelEventQueue coalesced_mouse_wheel_events_;
    253 
    254   // A queue of keyboard events. We can't trust data from the renderer so we
    255   // stuff key events into a queue and pop them out on ACK, feeding our copy
    256   // back to whatever unhandled handler instead of the returned version.
    257   typedef std::deque<NativeWebKeyboardEvent> KeyQueue;
    258   KeyQueue key_queue_;
    259 
    260   // The time when an input event was sent to the client.
    261   base::TimeTicks input_event_start_time_;
    262 
    263   // Cached flags from |OnViewUpdated()|, defaults to 0.
    264   int current_view_flags_;
    265 
    266   // The source of the ack within the scope of |ProcessInputEventAck()|.
    267   // Defaults to ACK_SOURCE_NONE.
    268   AckSource current_ack_source_;
    269 
    270   // Whether a call to |Flush()| has yet been accompanied by a |DidFlush()| call
    271   // to the client_ after all events have been dispatched/acked.
    272   bool flush_requested_;
    273 
    274   TouchEventQueue touch_event_queue_;
    275   GestureEventQueue gesture_event_queue_;
    276   TouchActionFilter touch_action_filter_;
    277   InputEventStreamValidator input_stream_validator_;
    278   InputEventStreamValidator output_stream_validator_;
    279 
    280   DISALLOW_COPY_AND_ASSIGN(InputRouterImpl);
    281 };
    282 
    283 }  // namespace content
    284 
    285 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
    286