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