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.
5 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
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"
21 struct InputHostMsg_HandleInputEvent_ACK_Params;
33 class InputAckHandler;
34 class InputRouterClient;
35 class OverscrollController;
36 class RenderWidgetHostImpl;
37 struct DidOverscrollParams;
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) {
46 struct CONTENT_EXPORT Config {
48 GestureEventQueue::Config gesture_config;
49 TouchEventQueue::Config touch_config;
52 InputRouterImpl(IPC::Sender* sender,
53 InputRouterClient* client,
54 InputAckHandler* ack_handler,
56 const Config& config);
57 virtual ~InputRouterImpl();
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;
80 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
83 friend class InputRouterImplTest;
85 // TouchpadTapSuppressionControllerClient
86 virtual void SendMouseEventImmediately(
87 const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
89 // TouchEventQueueClient
90 virtual void SendTouchEventImmediately(
91 const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
92 virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
93 InputEventAckState ack_result) OVERRIDE;
95 // GetureEventFilterClient
96 virtual void SendGestureEventImmediately(
97 const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
98 virtual void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
99 InputEventAckState ack_result) OVERRIDE;
101 bool SendMoveCaret(scoped_ptr<IPC::Message> message);
102 bool SendSelectRange(scoped_ptr<IPC::Message> message);
103 bool Send(IPC::Message* message);
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);
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);
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);
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);
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);
131 // A data structure that attaches some metadata to a WebMouseWheelEvent
132 // and its latency info.
133 struct QueuedWheelEvent {
135 QueuedWheelEvent(const MouseWheelEventWithLatencyInfo& event,
136 bool synthesized_from_pinch);
139 MouseWheelEventWithLatencyInfo event;
140 bool synthesized_from_pinch;
143 // Enqueue or send a mouse wheel event.
144 void SendWheelEvent(const QueuedWheelEvent& wheel_event);
146 // Given a Touchpad GesturePinchUpdate event, create and send a synthetic
147 // wheel event for it.
148 void SendSyntheticWheelEventForPinch(
149 const GestureEventWithLatencyInfo& pinch_event);
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);
159 // Indicates the source of an ack provided to |ProcessInputEventAck()|.
160 // The source is tracked by |current_ack_source_|, which aids in ack routing.
164 IGNORING_DISPOSITION,
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);
174 // Dispatches the ack'ed event to |ack_handler_|.
175 void ProcessKeyboardAck(blink::WebInputEvent::Type type,
176 InputEventAckState ack_result);
178 // Forwards a valid |next_mouse_move_| if |type| is MouseMove.
179 void ProcessMouseAck(blink::WebInputEvent::Type type,
180 InputEventAckState ack_result);
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);
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);
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);
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();
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();
209 bool IsInOverscrollGesture() const;
211 int routing_id() const { return routing_id_; }
214 IPC::Sender* sender_;
215 InputRouterClient* client_;
216 InputAckHandler* ack_handler_;
219 // (Similar to |mouse_move_pending_|.) True while waiting for SelectRange_ACK.
220 bool select_range_pending_;
222 // (Similar to |next_mouse_move_|.) The next SelectRange to send, if any.
223 scoped_ptr<IPC::Message> next_selection_range_;
225 // (Similar to |mouse_move_pending_|.) True while waiting for MoveCaret_ACK.
226 bool move_caret_pending_;
228 // (Similar to |next_mouse_move_|.) The next MoveCaret to send, if any.
229 scoped_ptr<IPC::Message> next_move_caret_;
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_;
235 // The next mouse move event to send (only non-null while mouse_move_pending_
237 scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move_;
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_;
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_;
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;
260 // The time when an input event was sent to the client.
261 base::TimeTicks input_event_start_time_;
263 // Cached flags from |OnViewUpdated()|, defaults to 0.
264 int current_view_flags_;
266 // The source of the ack within the scope of |ProcessInputEventAck()|.
267 // Defaults to ACK_SOURCE_NONE.
268 AckSource current_ack_source_;
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_;
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_;
280 DISALLOW_COPY_AND_ASSIGN(InputRouterImpl);
283 } // namespace content
285 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_