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