OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/input/input_event_filter.h" | 5 #include "content/renderer/input/input_event_filter.h" |
6 | 6 |
| 7 #include "base/auto_reset.h" |
7 #include "base/bind.h" | 8 #include "base/bind.h" |
8 #include "base/command_line.h" | 9 #include "base/command_line.h" |
9 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
10 #include "base/location.h" | 11 #include "base/location.h" |
11 #include "base/message_loop/message_loop_proxy.h" | 12 #include "base/message_loop/message_loop_proxy.h" |
12 #include "cc/input/input_handler.h" | 13 #include "cc/input/input_handler.h" |
13 #include "content/common/input/did_overscroll_params.h" | 14 #include "content/common/input/did_overscroll_params.h" |
14 #include "content/common/input/web_input_event_traits.h" | 15 #include "content/common/input/web_input_event_traits.h" |
15 #include "content/common/input_messages.h" | 16 #include "content/common/input_messages.h" |
16 #include "content/common/view_messages.h" | 17 #include "content/common/view_messages.h" |
(...skipping 21 matching lines...) Expand all Loading... |
38 | 39 |
39 namespace content { | 40 namespace content { |
40 | 41 |
41 InputEventFilter::InputEventFilter( | 42 InputEventFilter::InputEventFilter( |
42 IPC::Listener* main_listener, | 43 IPC::Listener* main_listener, |
43 const scoped_refptr<base::MessageLoopProxy>& target_loop) | 44 const scoped_refptr<base::MessageLoopProxy>& target_loop) |
44 : main_loop_(base::MessageLoopProxy::current()), | 45 : main_loop_(base::MessageLoopProxy::current()), |
45 main_listener_(main_listener), | 46 main_listener_(main_listener), |
46 sender_(NULL), | 47 sender_(NULL), |
47 target_loop_(target_loop), | 48 target_loop_(target_loop), |
48 overscroll_notifications_enabled_(false) { | 49 overscroll_notifications_enabled_(false), |
| 50 current_overscroll_params_(NULL) { |
49 DCHECK(target_loop_.get()); | 51 DCHECK(target_loop_.get()); |
50 overscroll_notifications_enabled_ = | 52 overscroll_notifications_enabled_ = |
51 CommandLine::ForCurrentProcess()->HasSwitch( | 53 CommandLine::ForCurrentProcess()->HasSwitch( |
52 switches::kEnableOverscrollNotifications); | 54 switches::kEnableOverscrollNotifications); |
53 } | 55 } |
54 | 56 |
55 void InputEventFilter::SetBoundHandler(const Handler& handler) { | 57 void InputEventFilter::SetBoundHandler(const Handler& handler) { |
56 DCHECK(main_loop_->BelongsToCurrentThread()); | 58 DCHECK(main_loop_->BelongsToCurrentThread()); |
57 handler_ = handler; | 59 handler_ = handler; |
58 } | 60 } |
59 | 61 |
60 void InputEventFilter::DidAddInputHandler(int routing_id, | 62 void InputEventFilter::DidAddInputHandler(int routing_id, |
61 cc::InputHandler* input_handler) { | 63 cc::InputHandler* input_handler) { |
62 base::AutoLock locked(routes_lock_); | 64 base::AutoLock locked(routes_lock_); |
63 routes_.insert(routing_id); | 65 routes_.insert(routing_id); |
64 } | 66 } |
65 | 67 |
66 void InputEventFilter::DidRemoveInputHandler(int routing_id) { | 68 void InputEventFilter::DidRemoveInputHandler(int routing_id) { |
67 base::AutoLock locked(routes_lock_); | 69 base::AutoLock locked(routes_lock_); |
68 routes_.erase(routing_id); | 70 routes_.erase(routing_id); |
69 } | 71 } |
70 | 72 |
71 void InputEventFilter::DidOverscroll(int routing_id, | 73 void InputEventFilter::DidOverscroll(int routing_id, |
72 const DidOverscrollParams& params) { | 74 const DidOverscrollParams& params) { |
73 if (!overscroll_notifications_enabled_) | 75 if (!overscroll_notifications_enabled_) |
74 return; | 76 return; |
75 | 77 |
76 SendMessage(ViewHostMsg_DidOverscroll(routing_id, params)); | 78 if (current_overscroll_params_) { |
| 79 current_overscroll_params_->reset(new DidOverscrollParams(params)); |
| 80 return; |
| 81 } |
| 82 |
| 83 SendMessage(scoped_ptr<IPC::Message>( |
| 84 new InputHostMsg_DidOverscroll(routing_id, params))); |
77 } | 85 } |
78 | 86 |
79 void InputEventFilter::DidStopFlinging(int routing_id) { | 87 void InputEventFilter::DidStopFlinging(int routing_id) { |
80 SendMessage(ViewHostMsg_DidStopFlinging(routing_id)); | 88 SendMessage( |
| 89 scoped_ptr<IPC::Message>(new ViewHostMsg_DidStopFlinging(routing_id))); |
81 } | 90 } |
82 | 91 |
83 void InputEventFilter::OnFilterAdded(IPC::Channel* channel) { | 92 void InputEventFilter::OnFilterAdded(IPC::Channel* channel) { |
84 io_loop_ = base::MessageLoopProxy::current(); | 93 io_loop_ = base::MessageLoopProxy::current(); |
85 sender_ = channel; | 94 sender_ = channel; |
86 } | 95 } |
87 | 96 |
88 void InputEventFilter::OnFilterRemoved() { | 97 void InputEventFilter::OnFilterRemoved() { |
89 sender_ = NULL; | 98 sender_ = NULL; |
90 } | 99 } |
(...skipping 23 matching lines...) Expand all Loading... |
114 return false; | 123 return false; |
115 } | 124 } |
116 | 125 |
117 target_loop_->PostTask( | 126 target_loop_->PostTask( |
118 FROM_HERE, | 127 FROM_HERE, |
119 base::Bind(&InputEventFilter::ForwardToHandler, this, message)); | 128 base::Bind(&InputEventFilter::ForwardToHandler, this, message)); |
120 return true; | 129 return true; |
121 } | 130 } |
122 | 131 |
123 InputEventFilter::~InputEventFilter() { | 132 InputEventFilter::~InputEventFilter() { |
| 133 DCHECK(!current_overscroll_params_); |
124 } | 134 } |
125 | 135 |
126 void InputEventFilter::ForwardToMainListener(const IPC::Message& message) { | 136 void InputEventFilter::ForwardToMainListener(const IPC::Message& message) { |
127 main_listener_->OnMessageReceived(message); | 137 main_listener_->OnMessageReceived(message); |
128 } | 138 } |
129 | 139 |
130 void InputEventFilter::ForwardToHandler(const IPC::Message& message) { | 140 void InputEventFilter::ForwardToHandler(const IPC::Message& message) { |
131 DCHECK(!handler_.is_null()); | 141 DCHECK(!handler_.is_null()); |
132 DCHECK(target_loop_->BelongsToCurrentThread()); | 142 DCHECK(target_loop_->BelongsToCurrentThread()); |
133 TRACE_EVENT1("input", "InputEventFilter::ForwardToHandler", | 143 TRACE_EVENT1("input", "InputEventFilter::ForwardToHandler", |
(...skipping 13 matching lines...) Expand all Loading... |
147 | 157 |
148 int routing_id = message.routing_id(); | 158 int routing_id = message.routing_id(); |
149 InputMsg_HandleInputEvent::Param params; | 159 InputMsg_HandleInputEvent::Param params; |
150 if (!InputMsg_HandleInputEvent::Read(&message, ¶ms)) | 160 if (!InputMsg_HandleInputEvent::Read(&message, ¶ms)) |
151 return; | 161 return; |
152 const WebInputEvent* event = params.a; | 162 const WebInputEvent* event = params.a; |
153 ui::LatencyInfo latency_info = params.b; | 163 ui::LatencyInfo latency_info = params.b; |
154 bool is_keyboard_shortcut = params.c; | 164 bool is_keyboard_shortcut = params.c; |
155 DCHECK(event); | 165 DCHECK(event); |
156 | 166 |
157 InputEventAckState ack = handler_.Run(routing_id, event, &latency_info); | 167 // Intercept |DidOverscroll| notifications, bundling any triggered overscroll |
| 168 // response with the input event ack. |
| 169 scoped_ptr<DidOverscrollParams> overscroll_params; |
| 170 base::AutoReset<scoped_ptr<DidOverscrollParams>*> |
| 171 auto_reset_current_overscroll_params(¤t_overscroll_params_, |
| 172 &overscroll_params); |
158 | 173 |
159 if (ack == INPUT_EVENT_ACK_STATE_NOT_CONSUMED) { | 174 InputEventAckState ack_state = handler_.Run(routing_id, event, &latency_info); |
| 175 |
| 176 if (ack_state == INPUT_EVENT_ACK_STATE_NOT_CONSUMED) { |
| 177 DCHECK(!overscroll_params); |
160 TRACE_EVENT_INSTANT0( | 178 TRACE_EVENT_INSTANT0( |
161 "input", | 179 "input", |
162 "InputEventFilter::ForwardToHandler::ForwardToMainListener", | 180 "InputEventFilter::ForwardToHandler::ForwardToMainListener", |
163 TRACE_EVENT_SCOPE_THREAD); | 181 TRACE_EVENT_SCOPE_THREAD); |
164 IPC::Message new_msg = InputMsg_HandleInputEvent( | 182 IPC::Message new_msg = InputMsg_HandleInputEvent( |
165 routing_id, event, latency_info, is_keyboard_shortcut); | 183 routing_id, event, latency_info, is_keyboard_shortcut); |
166 main_loop_->PostTask( | 184 main_loop_->PostTask( |
167 FROM_HERE, | 185 FROM_HERE, |
168 base::Bind(&InputEventFilter::ForwardToMainListener, | 186 base::Bind(&InputEventFilter::ForwardToMainListener, |
169 this, new_msg)); | 187 this, new_msg)); |
170 return; | 188 return; |
171 } | 189 } |
172 | 190 |
173 if (!WebInputEventTraits::IgnoresAckDisposition(*event)) | 191 if (WebInputEventTraits::IgnoresAckDisposition(*event)) |
174 SendACK(event->type, ack, latency_info, routing_id); | 192 return; |
| 193 |
| 194 InputHostMsg_HandleInputEvent_ACK_Params ack; |
| 195 ack.type = event->type; |
| 196 ack.state = ack_state; |
| 197 ack.latency = latency_info; |
| 198 ack.overscroll = overscroll_params.Pass(); |
| 199 SendMessage(scoped_ptr<IPC::Message>( |
| 200 new InputHostMsg_HandleInputEvent_ACK(routing_id, ack))); |
175 } | 201 } |
176 | 202 |
177 void InputEventFilter::SendACK(blink::WebInputEvent::Type type, | 203 void InputEventFilter::SendMessage(scoped_ptr<IPC::Message> message) { |
178 InputEventAckState ack_result, | 204 DCHECK(target_loop_->BelongsToCurrentThread()); |
179 const ui::LatencyInfo& latency_info, | 205 |
180 int routing_id) { | 206 io_loop_->PostTask(FROM_HERE, |
181 SendMessage(InputHostMsg_HandleInputEvent_ACK( | 207 base::Bind(&InputEventFilter::SendMessageOnIOThread, |
182 routing_id, type, ack_result, latency_info)); | 208 this, |
| 209 base::Passed(&message))); |
183 } | 210 } |
184 | 211 |
185 void InputEventFilter::SendMessage(const IPC::Message& message) { | 212 void InputEventFilter::SendMessageOnIOThread(scoped_ptr<IPC::Message> message) { |
186 DCHECK(target_loop_->BelongsToCurrentThread()); | |
187 | |
188 io_loop_->PostTask( | |
189 FROM_HERE, | |
190 base::Bind(&InputEventFilter::SendMessageOnIOThread, this, message)); | |
191 } | |
192 | |
193 void InputEventFilter::SendMessageOnIOThread(const IPC::Message& message) { | |
194 DCHECK(io_loop_->BelongsToCurrentThread()); | 213 DCHECK(io_loop_->BelongsToCurrentThread()); |
195 | 214 |
196 if (!sender_) | 215 if (!sender_) |
197 return; // Filter was removed. | 216 return; // Filter was removed. |
198 | 217 |
199 sender_->Send(new IPC::Message(message)); | 218 sender_->Send(message.release()); |
200 } | 219 } |
201 | 220 |
202 } // namespace content | 221 } // namespace content |
OLD | NEW |