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_IMMEDIATE_INPUT_ROUTER_H_
      6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_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/input_router.h"
     14 #include "content/browser/renderer_host/input/touch_event_queue.h"
     15 #include "content/public/browser/native_web_keyboard_event.h"
     16 
     17 namespace ui {
     18 struct LatencyInfo;
     19 }
     20 
     21 namespace content {
     22 
     23 class GestureEventFilter;
     24 class InputRouterClient;
     25 class RenderProcessHost;
     26 class RenderWidgetHostImpl;
     27 
     28 // A default implementation for browser input event routing. Input commands are
     29 // forwarded to the renderer immediately upon receipt.
     30 class CONTENT_EXPORT ImmediateInputRouter
     31     : public NON_EXPORTED_BASE(InputRouter),
     32       public NON_EXPORTED_BASE(TouchEventQueueClient) {
     33  public:
     34   ImmediateInputRouter(RenderProcessHost* process,
     35                        InputRouterClient* client,
     36                        int routing_id);
     37   virtual ~ImmediateInputRouter();
     38 
     39   // InputRouter
     40   virtual bool SendInput(IPC::Message* message) OVERRIDE;
     41   virtual void SendMouseEvent(
     42       const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
     43   virtual void SendWheelEvent(
     44       const MouseWheelEventWithLatencyInfo& wheel_event) OVERRIDE;
     45   virtual void SendKeyboardEvent(
     46       const NativeWebKeyboardEvent& key_event,
     47       const ui::LatencyInfo& latency_info) OVERRIDE;
     48   virtual void SendGestureEvent(
     49       const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
     50   virtual void SendTouchEvent(
     51       const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
     52   virtual void SendMouseEventImmediately(
     53       const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
     54   virtual void SendTouchEventImmediately(
     55       const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
     56   virtual void SendGestureEventImmediately(
     57       const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
     58   virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const OVERRIDE;
     59   virtual bool ShouldForwardTouchEvent() const OVERRIDE;
     60   virtual bool ShouldForwardGestureEvent(
     61       const GestureEventWithLatencyInfo& gesture_event) const OVERRIDE;
     62   virtual bool HasQueuedGestureEvents() const OVERRIDE;
     63 
     64   // IPC::Listener
     65   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
     66 
     67   GestureEventFilter* gesture_event_filter() {
     68     return gesture_event_filter_.get();
     69   }
     70 
     71   TouchEventQueue* touch_event_queue() {
     72     return touch_event_queue_.get();
     73   }
     74 
     75 private:
     76   // TouchEventQueueClient
     77   virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
     78                                InputEventAckState ack_result) OVERRIDE;
     79 
     80   bool SendMoveCaret(IPC::Message* message);
     81   bool SendSelectRange(IPC::Message* message);
     82   bool Send(IPC::Message* message);
     83 
     84   // Transmits the given input event an as an IPC::Message. This is an internal
     85   // helper for |FilterAndSendInputEvent()| and should not be used otherwise.
     86   void SendWebInputEvent(const WebKit::WebInputEvent& input_event,
     87                          const ui::LatencyInfo& latency_info,
     88                          bool is_keyboard_shortcut);
     89 
     90   // Filters and forwards the given WebInputEvent to |SendWebInputEvent()|. This
     91   // is an internal helper for |Send*Event()| and should not be used otherwise.
     92   void FilterAndSendWebInputEvent(const WebKit::WebInputEvent& input_event,
     93                                   const ui::LatencyInfo& latency_info,
     94                                   bool is_keyboard_shortcut);
     95 
     96   // IPC message handlers
     97   void OnInputEventAck(WebKit::WebInputEvent::Type event_type,
     98                        InputEventAckState ack_result,
     99                        const ui::LatencyInfo& latency_info);
    100   void OnMsgMoveCaretAck();
    101   void OnSelectRangeAck();
    102   void OnHasTouchEventHandlers(bool has_handlers);
    103 
    104   // Handle the event ack. Triggered via |OnInputEventAck()| if the event was
    105   // processed in the renderer, or synchonously from |FilterAndSendInputevent()|
    106   // if the event was filtered by the |client_| prior to sending.
    107   void ProcessInputEventAck(WebKit::WebInputEvent::Type event_type,
    108                             InputEventAckState ack_result,
    109                             const ui::LatencyInfo& latency_info);
    110 
    111   // Called by ProcessInputEventAck() to process a keyboard event ack message.
    112   void ProcessKeyboardAck(int type, InputEventAckState ack_result);
    113 
    114   // Called by ProcessInputEventAck() to process a wheel event ack message.
    115   // This could result in a task being posted to allow additional wheel
    116   // input messages to be coalesced.
    117   void ProcessWheelAck(InputEventAckState ack_result);
    118 
    119   // Called by ProcessInputEventAck() to process a gesture event ack message.
    120   // This validates the gesture for suppression of touchpad taps and sends one
    121   // previously queued coalesced gesture if it exists.
    122   void ProcessGestureAck(int type, InputEventAckState ack_result);
    123 
    124   // Called on ProcessInputEventAck() to process a touch event ack message.
    125   // This can result in a gesture event being generated and sent back to the
    126   // renderer.
    127   void ProcessTouchAck(InputEventAckState ack_result,
    128                        const ui::LatencyInfo& latency_info);
    129 
    130   int routing_id() const { return routing_id_; }
    131 
    132 
    133   RenderProcessHost* process_;
    134   InputRouterClient* client_;
    135   int routing_id_;
    136 
    137   // (Similar to |mouse_move_pending_|.) True while waiting for SelectRange_ACK.
    138   bool select_range_pending_;
    139 
    140   // (Similar to |next_mouse_move_|.) The next SelectRange to send, if any.
    141   scoped_ptr<IPC::Message> next_selection_range_;
    142 
    143   // (Similar to |mouse_move_pending_|.) True while waiting for MoveCaret_ACK.
    144   bool move_caret_pending_;
    145 
    146   // (Similar to |next_mouse_move_|.) The next MoveCaret to send, if any.
    147   scoped_ptr<IPC::Message> next_move_caret_;
    148 
    149   // True if a mouse move event was sent to the render view and we are waiting
    150   // for a corresponding InputHostMsg_HandleInputEvent_ACK message.
    151   bool mouse_move_pending_;
    152 
    153   // The next mouse move event to send (only non-null while mouse_move_pending_
    154   // is true).
    155   scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move_;
    156 
    157   // (Similar to |mouse_move_pending_|.) True if a mouse wheel event was sent
    158   // and we are waiting for a corresponding ack.
    159   bool mouse_wheel_pending_;
    160   MouseWheelEventWithLatencyInfo current_wheel_event_;
    161 
    162   typedef std::deque<MouseWheelEventWithLatencyInfo> WheelEventQueue;
    163 
    164   // (Similar to |next_mouse_move_|.) The next mouse wheel events to send.
    165   // Unlike mouse moves, mouse wheel events received while one is pending are
    166   // coalesced (by accumulating deltas) if they match the previous event in
    167   // modifiers. On the Mac, in particular, mouse wheel events are received at a
    168   // high rate; not waiting for the ack results in jankiness, and using the same
    169   // mechanism as for mouse moves (just dropping old events when multiple ones
    170   // would be queued) results in very slow scrolling.
    171   WheelEventQueue coalesced_mouse_wheel_events_;
    172 
    173   // The time when an input event was sent to the RenderWidget.
    174   base::TimeTicks input_event_start_time_;
    175 
    176   // Queue of keyboard events that we need to track.
    177   typedef std::deque<NativeWebKeyboardEvent> KeyQueue;
    178 
    179   // A queue of keyboard events. We can't trust data from the renderer so we
    180   // stuff key events into a queue and pop them out on ACK, feeding our copy
    181   // back to whatever unhandled handler instead of the returned version.
    182   KeyQueue key_queue_;
    183 
    184   // Keeps track of whether the webpage has any touch event handler. If it does,
    185   // then touch events are sent to the renderer. Otherwise, the touch events are
    186   // not sent to the renderer.
    187   bool has_touch_handler_;
    188 
    189   scoped_ptr<TouchEventQueue> touch_event_queue_;
    190   scoped_ptr<GestureEventFilter> gesture_event_filter_;
    191 
    192   DISALLOW_COPY_AND_ASSIGN(ImmediateInputRouter);
    193 };
    194 
    195 }  // namespace content
    196 
    197 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_H_
    198