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_IMMEDIATE_INPUT_ROUTER_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_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_filter.h"
14 #include "content/browser/renderer_host/input/input_router.h"
15 #include "content/browser/renderer_host/input/touch_event_queue.h"
16 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
17 #include "content/public/browser/native_web_keyboard_event.h"
29 class InputAckHandler;
30 class InputRouterClient;
31 class OverscrollController;
32 class RenderWidgetHostImpl;
34 // A default implementation for browser input event routing. Input commands are
35 // forwarded to the renderer immediately upon receipt.
36 class CONTENT_EXPORT ImmediateInputRouter
37 : public NON_EXPORTED_BASE(InputRouter),
38 public NON_EXPORTED_BASE(GestureEventFilterClient),
39 public NON_EXPORTED_BASE(TouchEventQueueClient),
40 public NON_EXPORTED_BASE(TouchpadTapSuppressionControllerClient) {
42 ImmediateInputRouter(IPC::Sender* sender,
43 InputRouterClient* client,
44 InputAckHandler* ack_handler,
46 virtual ~ImmediateInputRouter();
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;
67 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
70 friend class ImmediateInputRouterTest;
71 friend class MockRenderWidgetHost;
73 // TouchpadTapSuppressionControllerClient
74 virtual void SendMouseEventImmediately(
75 const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
77 // TouchEventQueueClient
78 virtual void SendTouchEventImmediately(
79 const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
80 virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
81 InputEventAckState ack_result) OVERRIDE;
83 // GetureEventFilterClient
84 virtual void SendGestureEventImmediately(
85 const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
86 virtual void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
87 InputEventAckState ack_result) OVERRIDE;
89 bool SendMoveCaret(scoped_ptr<IPC::Message> message);
90 bool SendSelectRange(scoped_ptr<IPC::Message> message);
91 bool Send(IPC::Message* message);
93 // Filters and forwards |input_event| to the appropriate handler.
94 void FilterAndSendWebInputEvent(const WebKit::WebInputEvent& input_event,
95 const ui::LatencyInfo& latency_info,
96 bool is_keyboard_shortcut);
98 // Utility routine for filtering and forwarding |input_event| to the
99 // appropriate handler. |input_event| will be offered to the overscroll
100 // controller, client and renderer, in that order.
101 void OfferToHandlers(const WebKit::WebInputEvent& input_event,
102 const ui::LatencyInfo& latency_info,
103 bool is_keyboard_shortcut);
105 // Returns true if |input_event| was consumed by the overscroll controller.
106 bool OfferToOverscrollController(const WebKit::WebInputEvent& input_event,
107 const ui::LatencyInfo& latency_info);
109 // Returns true if |input_event| was consumed by the client.
110 bool OfferToClient(const WebKit::WebInputEvent& input_event,
111 const ui::LatencyInfo& latency_info);
113 // Returns true if |input_event| was successfully sent to the renderer
114 // as an async IPC Message.
115 bool OfferToRenderer(const WebKit::WebInputEvent& input_event,
116 const ui::LatencyInfo& latency_info,
117 bool is_keyboard_shortcut);
119 // IPC message handlers
120 void OnInputEventAck(WebKit::WebInputEvent::Type event_type,
121 InputEventAckState ack_result,
122 const ui::LatencyInfo& latency_info);
123 void OnMsgMoveCaretAck();
124 void OnSelectRangeAck();
125 void OnHasTouchEventHandlers(bool has_handlers);
127 // Indicates the source of an ack provided to |ProcessInputEventAck()|.
128 // The source is tracked by |current_ack_source_|, which aids in ack routing.
132 OVERSCROLL_CONTROLLER,
135 // Note: This function may result in |this| being deleted, and as such
136 // should be the last method called in any internal chain of event handling.
137 void ProcessInputEventAck(WebKit::WebInputEvent::Type event_type,
138 InputEventAckState ack_result,
139 const ui::LatencyInfo& latency_info,
140 AckSource ack_source);
142 // Dispatches the ack'ed event to |ack_handler_|.
143 void ProcessKeyboardAck(WebKit::WebInputEvent::Type type,
144 InputEventAckState ack_result);
146 // Forwards a valid |next_mouse_move_| if |type| is MouseMove.
147 void ProcessMouseAck(WebKit::WebInputEvent::Type type,
148 InputEventAckState ack_result);
150 // Dispatches the ack'ed event to |ack_handler_|, forwarding queued events
151 // from |coalesced_mouse_wheel_events_|.
152 void ProcessWheelAck(InputEventAckState ack_result,
153 const ui::LatencyInfo& latency);
155 // Forwards the event ack to |gesture_event_filter|, potentially triggering
156 // dispatch of queued gesture events.
157 void ProcessGestureAck(WebKit::WebInputEvent::Type type,
158 InputEventAckState ack_result,
159 const ui::LatencyInfo& latency);
161 // Forwards the event ack to |touch_event_queue_|, potentially triggering
162 // dispatch of queued touch events, or the creation of gesture events.
163 void ProcessTouchAck(InputEventAckState ack_result,
164 const ui::LatencyInfo& latency);
166 // Forwards |ack_result| to the client's OverscrollController, if necessary.
167 void ProcessAckForOverscroll(const WebKit::WebInputEvent& event,
168 InputEventAckState ack_result);
170 void HandleGestureScroll(const GestureEventWithLatencyInfo& gesture_event);
172 void SimulateTouchGestureWithMouse(
173 const MouseEventWithLatencyInfo& mouse_event);
175 bool IsInOverscrollGesture() const;
177 int routing_id() const { return routing_id_; }
180 IPC::Sender* sender_;
181 InputRouterClient* client_;
182 InputAckHandler* ack_handler_;
185 // (Similar to |mouse_move_pending_|.) True while waiting for SelectRange_ACK.
186 bool select_range_pending_;
188 // (Similar to |next_mouse_move_|.) The next SelectRange to send, if any.
189 scoped_ptr<IPC::Message> next_selection_range_;
191 // (Similar to |mouse_move_pending_|.) True while waiting for MoveCaret_ACK.
192 bool move_caret_pending_;
194 // (Similar to |next_mouse_move_|.) The next MoveCaret to send, if any.
195 scoped_ptr<IPC::Message> next_move_caret_;
197 // True if a mouse move event was sent to the render view and we are waiting
198 // for a corresponding InputHostMsg_HandleInputEvent_ACK message.
199 bool mouse_move_pending_;
201 // The next mouse move event to send (only non-null while mouse_move_pending_
203 scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move_;
205 // (Similar to |mouse_move_pending_|.) True if a mouse wheel event was sent
206 // and we are waiting for a corresponding ack.
207 bool mouse_wheel_pending_;
208 MouseWheelEventWithLatencyInfo current_wheel_event_;
210 typedef std::deque<MouseWheelEventWithLatencyInfo> WheelEventQueue;
212 // (Similar to |next_mouse_move_|.) The next mouse wheel events to send.
213 // Unlike mouse moves, mouse wheel events received while one is pending are
214 // coalesced (by accumulating deltas) if they match the previous event in
215 // modifiers. On the Mac, in particular, mouse wheel events are received at a
216 // high rate; not waiting for the ack results in jankiness, and using the same
217 // mechanism as for mouse moves (just dropping old events when multiple ones
218 // would be queued) results in very slow scrolling.
219 WheelEventQueue coalesced_mouse_wheel_events_;
221 // The time when an input event was sent to the RenderWidget.
222 base::TimeTicks input_event_start_time_;
224 // Queue of keyboard events that we need to track.
225 typedef std::deque<NativeWebKeyboardEvent> KeyQueue;
227 // A queue of keyboard events. We can't trust data from the renderer so we
228 // stuff key events into a queue and pop them out on ACK, feeding our copy
229 // back to whatever unhandled handler instead of the returned version.
232 // Keeps track of whether the webpage has any touch event handler. If it does,
233 // then touch events are sent to the renderer. Otherwise, the touch events are
234 // not sent to the renderer.
235 bool has_touch_handler_;
237 // The source of the ack within the scope of |ProcessInputEventAck()|.
238 // Defaults to ACK_SOURCE_NONE.
239 AckSource current_ack_source_;
241 scoped_ptr<TouchEventQueue> touch_event_queue_;
242 scoped_ptr<GestureEventFilter> gesture_event_filter_;
244 DISALLOW_COPY_AND_ASSIGN(ImmediateInputRouter);
247 } // namespace content
249 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_H_