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_filter.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/public/browser/native_web_keyboard_event.h"
     19 
     20 namespace IPC {
     21 class Sender;
     22 }
     23 
     24 namespace ui {
     25 struct LatencyInfo;
     26 }
     27 
     28 namespace content {
     29 
     30 class InputAckHandler;
     31 class InputRouterClient;
     32 class OverscrollController;
     33 class RenderWidgetHostImpl;
     34 
     35 // A default implementation for browser input event routing.
     36 class CONTENT_EXPORT InputRouterImpl
     37     : public NON_EXPORTED_BASE(InputRouter),
     38       public NON_EXPORTED_BASE(GestureEventFilterClient),
     39       public NON_EXPORTED_BASE(TouchEventQueueClient),
     40       public NON_EXPORTED_BASE(TouchpadTapSuppressionControllerClient) {
     41  public:
     42   InputRouterImpl(IPC::Sender* sender,
     43                   InputRouterClient* client,
     44                   InputAckHandler* ack_handler,
     45                   int routing_id);
     46   virtual ~InputRouterImpl();
     47 
     48   // InputRouter
     49   virtual void Flush() OVERRIDE;
     50   virtual bool SendInput(scoped_ptr<IPC::Message> message) OVERRIDE;
     51   virtual void SendMouseEvent(
     52       const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
     53   virtual void SendWheelEvent(
     54       const MouseWheelEventWithLatencyInfo& wheel_event) OVERRIDE;
     55   virtual void SendKeyboardEvent(
     56       const NativeWebKeyboardEvent& key_event,
     57       const ui::LatencyInfo& latency_info,
     58       bool is_keyboard_shortcut) OVERRIDE;
     59   virtual void SendGestureEvent(
     60       const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
     61   virtual void SendTouchEvent(
     62       const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
     63   virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const OVERRIDE;
     64   virtual bool ShouldForwardTouchEvent() const OVERRIDE;
     65   virtual void OnViewUpdated(int view_flags) OVERRIDE;
     66 
     67   // IPC::Listener
     68   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
     69 
     70 private:
     71   friend class InputRouterImplTest;
     72   friend class MockRenderWidgetHost;
     73 
     74   // TouchpadTapSuppressionControllerClient
     75   virtual void SendMouseEventImmediately(
     76       const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
     77 
     78   // TouchEventQueueClient
     79   virtual void SendTouchEventImmediately(
     80       const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
     81   virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
     82                                InputEventAckState ack_result) OVERRIDE;
     83 
     84   // GetureEventFilterClient
     85   virtual void SendGestureEventImmediately(
     86       const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
     87   virtual void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
     88                                  InputEventAckState ack_result) OVERRIDE;
     89 
     90   bool SendMoveCaret(scoped_ptr<IPC::Message> message);
     91   bool SendSelectRange(scoped_ptr<IPC::Message> message);
     92   bool Send(IPC::Message* message);
     93 
     94   // Filters and forwards |input_event| to the appropriate handler.
     95   void FilterAndSendWebInputEvent(const blink::WebInputEvent& input_event,
     96                                   const ui::LatencyInfo& latency_info,
     97                                   bool is_keyboard_shortcut);
     98 
     99   // Utility routine for filtering and forwarding |input_event| to the
    100   // appropriate handler. |input_event| will be offered to the overscroll
    101   // controller, client and renderer, in that order.
    102   void OfferToHandlers(const blink::WebInputEvent& input_event,
    103                        const ui::LatencyInfo& latency_info,
    104                        bool is_keyboard_shortcut);
    105 
    106   // Returns true if |input_event| was consumed by the overscroll controller.
    107   bool OfferToOverscrollController(const blink::WebInputEvent& input_event,
    108                                    const ui::LatencyInfo& latency_info);
    109 
    110   // Returns true if |input_event| was consumed by the client.
    111   bool OfferToClient(const blink::WebInputEvent& input_event,
    112                      const ui::LatencyInfo& latency_info);
    113 
    114   // Returns true if |input_event| was successfully sent to the renderer
    115   // as an async IPC Message.
    116   bool OfferToRenderer(const blink::WebInputEvent& input_event,
    117                        const ui::LatencyInfo& latency_info,
    118                        bool is_keyboard_shortcut);
    119 
    120   // IPC message handlers
    121   void OnInputEventAck(blink::WebInputEvent::Type event_type,
    122                        InputEventAckState ack_result,
    123                        const ui::LatencyInfo& latency_info);
    124   void OnMsgMoveCaretAck();
    125   void OnSelectRangeAck();
    126   void OnHasTouchEventHandlers(bool has_handlers);
    127   void OnSetTouchAction(content::TouchAction touch_action);
    128 
    129   // Indicates the source of an ack provided to |ProcessInputEventAck()|.
    130   // The source is tracked by |current_ack_source_|, which aids in ack routing.
    131   enum AckSource {
    132     RENDERER,
    133     CLIENT,
    134     OVERSCROLL_CONTROLLER,
    135     IGNORING_DISPOSITION,
    136     ACK_SOURCE_NONE
    137   };
    138   // Note: This function may result in |this| being deleted, and as such
    139   // should be the last method called in any internal chain of event handling.
    140   void ProcessInputEventAck(blink::WebInputEvent::Type event_type,
    141                             InputEventAckState ack_result,
    142                             const ui::LatencyInfo& latency_info,
    143                             AckSource ack_source);
    144 
    145   // Dispatches the ack'ed event to |ack_handler_|.
    146   void ProcessKeyboardAck(blink::WebInputEvent::Type type,
    147                           InputEventAckState ack_result);
    148 
    149   // Forwards a valid |next_mouse_move_| if |type| is MouseMove.
    150   void ProcessMouseAck(blink::WebInputEvent::Type type,
    151                        InputEventAckState ack_result);
    152 
    153   // Dispatches the ack'ed event to |ack_handler_|, forwarding queued events
    154   // from |coalesced_mouse_wheel_events_|.
    155   void ProcessWheelAck(InputEventAckState ack_result,
    156                        const ui::LatencyInfo& latency);
    157 
    158   // Forwards the event ack to |gesture_event_filter|, potentially triggering
    159   // dispatch of queued gesture events.
    160   void ProcessGestureAck(blink::WebInputEvent::Type type,
    161                          InputEventAckState ack_result,
    162                          const ui::LatencyInfo& latency);
    163 
    164   // Forwards the event ack to |touch_event_queue_|, potentially triggering
    165   // dispatch of queued touch events, or the creation of gesture events.
    166   void ProcessTouchAck(InputEventAckState ack_result,
    167                        const ui::LatencyInfo& latency);
    168 
    169   // Forwards |ack_result| to the client's OverscrollController, if necessary.
    170   void ProcessAckForOverscroll(const blink::WebInputEvent& event,
    171                                InputEventAckState ack_result);
    172 
    173   void SimulateTouchGestureWithMouse(
    174       const MouseEventWithLatencyInfo& mouse_event);
    175 
    176   bool IsInOverscrollGesture() const;
    177 
    178   int routing_id() const { return routing_id_; }
    179 
    180 
    181   IPC::Sender* sender_;
    182   InputRouterClient* client_;
    183   InputAckHandler* ack_handler_;
    184   int routing_id_;
    185 
    186   // (Similar to |mouse_move_pending_|.) True while waiting for SelectRange_ACK.
    187   bool select_range_pending_;
    188 
    189   // (Similar to |next_mouse_move_|.) The next SelectRange to send, if any.
    190   scoped_ptr<IPC::Message> next_selection_range_;
    191 
    192   // (Similar to |mouse_move_pending_|.) True while waiting for MoveCaret_ACK.
    193   bool move_caret_pending_;
    194 
    195   // (Similar to |next_mouse_move_|.) The next MoveCaret to send, if any.
    196   scoped_ptr<IPC::Message> next_move_caret_;
    197 
    198   // True if a mouse move event was sent to the render view and we are waiting
    199   // for a corresponding InputHostMsg_HandleInputEvent_ACK message.
    200   bool mouse_move_pending_;
    201 
    202   // The next mouse move event to send (only non-null while mouse_move_pending_
    203   // is true).
    204   scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move_;
    205 
    206   // (Similar to |mouse_move_pending_|.) True if a mouse wheel event was sent
    207   // and we are waiting for a corresponding ack.
    208   bool mouse_wheel_pending_;
    209   MouseWheelEventWithLatencyInfo current_wheel_event_;
    210 
    211   typedef std::deque<MouseWheelEventWithLatencyInfo> WheelEventQueue;
    212 
    213   // (Similar to |next_mouse_move_|.) The next mouse wheel events to send.
    214   // Unlike mouse moves, mouse wheel events received while one is pending are
    215   // coalesced (by accumulating deltas) if they match the previous event in
    216   // modifiers. On the Mac, in particular, mouse wheel events are received at a
    217   // high rate; not waiting for the ack results in jankiness, and using the same
    218   // mechanism as for mouse moves (just dropping old events when multiple ones
    219   // would be queued) results in very slow scrolling.
    220   WheelEventQueue coalesced_mouse_wheel_events_;
    221 
    222   // The time when an input event was sent to the RenderWidget.
    223   base::TimeTicks input_event_start_time_;
    224 
    225   // Queue of keyboard events that we need to track.
    226   typedef std::deque<NativeWebKeyboardEvent> KeyQueue;
    227 
    228   // A queue of keyboard events. We can't trust data from the renderer so we
    229   // stuff key events into a queue and pop them out on ACK, feeding our copy
    230   // back to whatever unhandled handler instead of the returned version.
    231   KeyQueue key_queue_;
    232 
    233   // Keeps track of whether the webpage has any touch event handler. If it does,
    234   // then touch events are sent to the renderer. Otherwise, the touch events are
    235   // not sent to the renderer.
    236   bool has_touch_handler_;
    237 
    238   // Whether touch ack timeout handling has been enabled via the command line.
    239   bool touch_ack_timeout_enabled_;
    240   size_t touch_ack_timeout_delay_ms_;
    241 
    242   // The source of the ack within the scope of |ProcessInputEventAck()|.
    243   // Defaults to ACK_SOURCE_NONE.
    244   AckSource current_ack_source_;
    245 
    246   scoped_ptr<TouchEventQueue> touch_event_queue_;
    247   scoped_ptr<GestureEventFilter> gesture_event_filter_;
    248   TouchActionFilter touch_action_filter_;
    249 
    250   DISALLOW_COPY_AND_ASSIGN(InputRouterImpl);
    251 };
    252 
    253 }  // namespace content
    254 
    255 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
    256