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
20namespace IPC {
21class Sender;
22}
23
24namespace ui {
25struct LatencyInfo;
26}
27
28namespace content {
29
30class InputAckHandler;
31class InputRouterClient;
32class OverscrollController;
33class RenderWidgetHostImpl;
34
35// A default implementation for browser input event routing.
36class 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
70private:
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