- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / input / immediate_input_router.h
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_IMMEDIATE_INPUT_ROUTER_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_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_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"
18
19 namespace IPC {
20 class Sender;
21 }
22
23 namespace ui {
24 struct LatencyInfo;
25 }
26
27 namespace content {
28
29 class InputAckHandler;
30 class InputRouterClient;
31 class OverscrollController;
32 class RenderWidgetHostImpl;
33
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) {
41  public:
42   ImmediateInputRouter(IPC::Sender* sender,
43                        InputRouterClient* client,
44                        InputAckHandler* ack_handler,
45                        int routing_id);
46   virtual ~ImmediateInputRouter();
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
66   // IPC::Listener
67   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
68
69 private:
70   friend class ImmediateInputRouterTest;
71   friend class MockRenderWidgetHost;
72
73   // TouchpadTapSuppressionControllerClient
74   virtual void SendMouseEventImmediately(
75       const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
76
77   // TouchEventQueueClient
78   virtual void SendTouchEventImmediately(
79       const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
80   virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
81                                InputEventAckState ack_result) OVERRIDE;
82
83   // GetureEventFilterClient
84   virtual void SendGestureEventImmediately(
85       const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
86   virtual void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
87                                  InputEventAckState ack_result) OVERRIDE;
88
89   bool SendMoveCaret(scoped_ptr<IPC::Message> message);
90   bool SendSelectRange(scoped_ptr<IPC::Message> message);
91   bool Send(IPC::Message* message);
92
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);
97
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);
104
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);
108
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);
112
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);
118
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);
126
127   // Indicates the source of an ack provided to |ProcessInputEventAck()|.
128   // The source is tracked by |current_ack_source_|, which aids in ack routing.
129   enum AckSource {
130     RENDERER,
131     CLIENT,
132     OVERSCROLL_CONTROLLER,
133     ACK_SOURCE_NONE
134   };
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);
141
142   // Dispatches the ack'ed event to |ack_handler_|.
143   void ProcessKeyboardAck(WebKit::WebInputEvent::Type type,
144                           InputEventAckState ack_result);
145
146   // Forwards a valid |next_mouse_move_| if |type| is MouseMove.
147   void ProcessMouseAck(WebKit::WebInputEvent::Type type,
148                        InputEventAckState ack_result);
149
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);
154
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);
160
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);
165
166   // Forwards |ack_result| to the client's OverscrollController, if necessary.
167   void ProcessAckForOverscroll(const WebKit::WebInputEvent& event,
168                                InputEventAckState ack_result);
169
170   void HandleGestureScroll(const GestureEventWithLatencyInfo& gesture_event);
171
172   void SimulateTouchGestureWithMouse(
173       const MouseEventWithLatencyInfo& mouse_event);
174
175   bool IsInOverscrollGesture() const;
176
177   int routing_id() const { return routing_id_; }
178
179
180   IPC::Sender* sender_;
181   InputRouterClient* client_;
182   InputAckHandler* ack_handler_;
183   int routing_id_;
184
185   // (Similar to |mouse_move_pending_|.) True while waiting for SelectRange_ACK.
186   bool select_range_pending_;
187
188   // (Similar to |next_mouse_move_|.) The next SelectRange to send, if any.
189   scoped_ptr<IPC::Message> next_selection_range_;
190
191   // (Similar to |mouse_move_pending_|.) True while waiting for MoveCaret_ACK.
192   bool move_caret_pending_;
193
194   // (Similar to |next_mouse_move_|.) The next MoveCaret to send, if any.
195   scoped_ptr<IPC::Message> next_move_caret_;
196
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_;
200
201   // The next mouse move event to send (only non-null while mouse_move_pending_
202   // is true).
203   scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move_;
204
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_;
209
210   typedef std::deque<MouseWheelEventWithLatencyInfo> WheelEventQueue;
211
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_;
220
221   // The time when an input event was sent to the RenderWidget.
222   base::TimeTicks input_event_start_time_;
223
224   // Queue of keyboard events that we need to track.
225   typedef std::deque<NativeWebKeyboardEvent> KeyQueue;
226
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.
230   KeyQueue key_queue_;
231
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_;
236
237   // The source of the ack within the scope of |ProcessInputEventAck()|.
238   // Defaults to ACK_SOURCE_NONE.
239   AckSource current_ack_source_;
240
241   scoped_ptr<TouchEventQueue> touch_event_queue_;
242   scoped_ptr<GestureEventFilter> gesture_event_filter_;
243
244   DISALLOW_COPY_AND_ASSIGN(ImmediateInputRouter);
245 };
246
247 }  // namespace content
248
249 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_H_