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 <tuple> | 7 #include <tuple> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 input_handler_manager_ = input_handler_manager; | 72 input_handler_manager_ = input_handler_manager; |
73 } | 73 } |
74 | 74 |
75 void InputEventFilter::RegisterRoutingID(int routing_id) { | 75 void InputEventFilter::RegisterRoutingID(int routing_id) { |
76 base::AutoLock locked(routes_lock_); | 76 base::AutoLock locked(routes_lock_); |
77 routes_.insert(routing_id); | 77 routes_.insert(routing_id); |
78 route_queues_[routing_id] = new MainThreadEventQueue( | 78 route_queues_[routing_id] = new MainThreadEventQueue( |
79 routing_id, this, main_task_runner_, renderer_scheduler_); | 79 routing_id, this, main_task_runner_, renderer_scheduler_); |
80 } | 80 } |
81 | 81 |
| 82 void InputEventFilter::RegisterAssociatedRenderFrameRoutingID( |
| 83 int render_frame_routing_id, |
| 84 int render_view_routing_id) { |
| 85 base::AutoLock locked(routes_lock_); |
| 86 DCHECK(routes_.find(render_view_routing_id) != routes_.end()); |
| 87 associated_routes_[render_frame_routing_id] = render_view_routing_id; |
| 88 } |
| 89 |
82 void InputEventFilter::UnregisterRoutingID(int routing_id) { | 90 void InputEventFilter::UnregisterRoutingID(int routing_id) { |
83 base::AutoLock locked(routes_lock_); | 91 base::AutoLock locked(routes_lock_); |
84 routes_.erase(routing_id); | 92 routes_.erase(routing_id); |
85 route_queues_.erase(routing_id); | 93 route_queues_.erase(routing_id); |
| 94 associated_routes_.erase(routing_id); |
86 } | 95 } |
87 | 96 |
88 void InputEventFilter::DidOverscroll(int routing_id, | 97 void InputEventFilter::DidOverscroll(int routing_id, |
89 const DidOverscrollParams& params) { | 98 const DidOverscrollParams& params) { |
90 SendMessage(std::unique_ptr<IPC::Message>( | 99 SendMessage(std::unique_ptr<IPC::Message>( |
91 new InputHostMsg_DidOverscroll(routing_id, params))); | 100 new InputHostMsg_DidOverscroll(routing_id, params))); |
92 } | 101 } |
93 | 102 |
94 void InputEventFilter::DidStopFlinging(int routing_id) { | 103 void InputEventFilter::DidStopFlinging(int routing_id) { |
95 SendMessage(base::MakeUnique<InputHostMsg_DidStopFlinging>(routing_id)); | 104 SendMessage(base::MakeUnique<InputHostMsg_DidStopFlinging>(routing_id)); |
96 } | 105 } |
97 | 106 |
| 107 void InputEventFilter::QueueClosureForMainThreadEventQueue( |
| 108 int routing_id, |
| 109 const base::Closure& closure) { |
| 110 DCHECK(target_task_runner_->BelongsToCurrentThread()); |
| 111 RouteQueueMap::iterator iter = route_queues_.find(routing_id); |
| 112 if (iter != route_queues_.end()) { |
| 113 iter->second->QueueClosure(closure); |
| 114 return; |
| 115 } |
| 116 |
| 117 // For some reason we didn't find an event queue for the route. |
| 118 // Don't drop the task on the floor allow it to execute. |
| 119 NOTREACHED(); |
| 120 main_task_runner_->PostTask(FROM_HERE, closure); |
| 121 } |
| 122 |
98 void InputEventFilter::DispatchNonBlockingEventToMainThread( | 123 void InputEventFilter::DispatchNonBlockingEventToMainThread( |
99 int routing_id, | 124 int routing_id, |
100 ui::WebScopedInputEvent event, | 125 ui::WebScopedInputEvent event, |
101 const ui::LatencyInfo& latency_info) { | 126 const ui::LatencyInfo& latency_info) { |
102 DCHECK(target_task_runner_->BelongsToCurrentThread()); | 127 DCHECK(target_task_runner_->BelongsToCurrentThread()); |
103 RouteQueueMap::iterator iter = route_queues_.find(routing_id); | 128 RouteQueueMap::iterator iter = route_queues_.find(routing_id); |
104 if (iter != route_queues_.end()) { | 129 if (iter != route_queues_.end()) { |
105 iter->second->HandleEvent(std::move(event), latency_info, | 130 iter->second->HandleEvent(std::move(event), latency_info, |
106 DISPATCH_TYPE_NON_BLOCKING, | 131 DISPATCH_TYPE_NON_BLOCKING, |
107 INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); | 132 INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 194 |
170 // If TimeTicks is not consistent across processes we cannot use the event's | 195 // If TimeTicks is not consistent across processes we cannot use the event's |
171 // platform timestamp in this process. Instead the time that the event is | 196 // platform timestamp in this process. Instead the time that the event is |
172 // received on the IO thread is used as the event's timestamp. | 197 // received on the IO thread is used as the event's timestamp. |
173 base::TimeTicks received_time; | 198 base::TimeTicks received_time; |
174 if (!base::TimeTicks::IsConsistentAcrossProcesses()) | 199 if (!base::TimeTicks::IsConsistentAcrossProcesses()) |
175 received_time = base::TimeTicks::Now(); | 200 received_time = base::TimeTicks::Now(); |
176 | 201 |
177 TRACE_EVENT0("input", "InputEventFilter::OnMessageReceived::InputMessage"); | 202 TRACE_EVENT0("input", "InputEventFilter::OnMessageReceived::InputMessage"); |
178 | 203 |
| 204 int routing_id = message.routing_id(); |
179 { | 205 { |
180 base::AutoLock locked(routes_lock_); | 206 base::AutoLock locked(routes_lock_); |
181 if (routes_.find(message.routing_id()) == routes_.end()) | 207 if (routes_.find(routing_id) == routes_.end()) { |
182 return false; | 208 // |routes_| is based on the RenderView routing_id but the routing_id |
| 209 // may be from a RenderFrame. Messages from RenderFrames should be handled |
| 210 // synchronously with the associated RenderView as well. |
| 211 // Use the associated table to see if we have a mapping from |
| 212 // RenderFrame->RenderView if so use the queue for that routing id. |
| 213 // TODO(dtapuska): Input messages should NOT be sent to RenderFrames and |
| 214 // RenderViews; they should only goto one and this code will be |
| 215 // unnecessary as this would break for mojo which doesn't guarantee |
| 216 // ordering on different channels but Chrome IPC does. |
| 217 auto associated_routing_id = associated_routes_.find(routing_id); |
| 218 if (associated_routing_id == associated_routes_.end() || |
| 219 routes_.find(associated_routing_id->second) == routes_.end()) { |
| 220 return false; |
| 221 } |
| 222 routing_id = associated_routing_id->second; |
| 223 } |
183 } | 224 } |
184 | 225 |
185 bool postedTask = target_task_runner_->PostTask( | 226 bool postedTask = target_task_runner_->PostTask( |
186 FROM_HERE, base::Bind(&InputEventFilter::ForwardToHandler, this, message, | 227 FROM_HERE, base::Bind(&InputEventFilter::ForwardToHandler, this, |
187 received_time)); | 228 routing_id, message, received_time)); |
188 LOG_IF(WARNING, !postedTask) << "PostTask failed"; | 229 LOG_IF(WARNING, !postedTask) << "PostTask failed"; |
189 return true; | 230 return true; |
190 } | 231 } |
191 | 232 |
192 InputEventFilter::~InputEventFilter() {} | 233 InputEventFilter::~InputEventFilter() {} |
193 | 234 |
194 void InputEventFilter::ForwardToHandler(const IPC::Message& message, | 235 void InputEventFilter::ForwardToHandler(int associated_routing_id, |
| 236 const IPC::Message& message, |
195 base::TimeTicks received_time) { | 237 base::TimeTicks received_time) { |
196 DCHECK(input_handler_manager_); | 238 DCHECK(input_handler_manager_); |
197 DCHECK(target_task_runner_->BelongsToCurrentThread()); | 239 DCHECK(target_task_runner_->BelongsToCurrentThread()); |
198 TRACE_EVENT1("input", "InputEventFilter::ForwardToHandler", | 240 TRACE_EVENT1("input", "InputEventFilter::ForwardToHandler", |
199 "message_type", GetInputMessageTypeName(message)); | 241 "message_type", GetInputMessageTypeName(message)); |
200 | 242 |
201 if (message.type() != InputMsg_HandleInputEvent::ID) { | 243 if (message.type() != InputMsg_HandleInputEvent::ID) { |
202 TRACE_EVENT_INSTANT0( | 244 TRACE_EVENT_INSTANT0( |
203 "input", | 245 "input", |
204 "InputEventFilter::ForwardToHandler::ForwardToMainListener", | 246 "InputEventFilter::ForwardToHandler::ForwardToMainListener", |
205 TRACE_EVENT_SCOPE_THREAD); | 247 TRACE_EVENT_SCOPE_THREAD); |
206 CHECK(main_task_runner_->PostTask(FROM_HERE, | 248 input_handler_manager_->QueueClosureForMainThreadEventQueue( |
207 base::Bind(main_listener_, message))) | 249 associated_routing_id, base::Bind(main_listener_, message)); |
208 << "PostTask failed"; | |
209 return; | 250 return; |
210 } | 251 } |
211 | 252 |
212 int routing_id = message.routing_id(); | |
213 InputMsg_HandleInputEvent::Param params; | 253 InputMsg_HandleInputEvent::Param params; |
214 if (!InputMsg_HandleInputEvent::Read(&message, ¶ms)) | 254 if (!InputMsg_HandleInputEvent::Read(&message, ¶ms)) |
215 return; | 255 return; |
216 ui::WebScopedInputEvent event = | 256 ui::WebScopedInputEvent event = |
217 ui::WebInputEventTraits::Clone(*std::get<0>(params)); | 257 ui::WebInputEventTraits::Clone(*std::get<0>(params)); |
218 ui::LatencyInfo latency_info = std::get<2>(params); | 258 ui::LatencyInfo latency_info = std::get<2>(params); |
219 InputEventDispatchType dispatch_type = std::get<3>(params); | 259 InputEventDispatchType dispatch_type = std::get<3>(params); |
220 | 260 |
| 261 // HandleInputEvent is always sent to the RenderView routing ID |
| 262 // so it should be the same as the message routing ID. |
| 263 DCHECK(associated_routing_id == message.routing_id()); |
221 DCHECK(event); | 264 DCHECK(event); |
222 DCHECK(dispatch_type == DISPATCH_TYPE_BLOCKING || | 265 DCHECK(dispatch_type == DISPATCH_TYPE_BLOCKING || |
223 dispatch_type == DISPATCH_TYPE_NON_BLOCKING); | 266 dispatch_type == DISPATCH_TYPE_NON_BLOCKING); |
224 | 267 |
225 if (!received_time.is_null()) | 268 if (!received_time.is_null()) |
226 event->setTimeStampSeconds(ui::EventTimeStampToSeconds(received_time)); | 269 event->setTimeStampSeconds(ui::EventTimeStampToSeconds(received_time)); |
227 | 270 |
228 input_handler_manager_->HandleInputEvent( | 271 input_handler_manager_->HandleInputEvent( |
229 routing_id, std::move(event), latency_info, | 272 associated_routing_id, std::move(event), latency_info, |
230 base::Bind(&InputEventFilter::DidForwardToHandlerAndOverscroll, this, | 273 base::Bind(&InputEventFilter::DidForwardToHandlerAndOverscroll, this, |
231 routing_id, dispatch_type)); | 274 associated_routing_id, dispatch_type)); |
232 }; | 275 }; |
233 | 276 |
234 void InputEventFilter::DidForwardToHandlerAndOverscroll( | 277 void InputEventFilter::DidForwardToHandlerAndOverscroll( |
235 int routing_id, | 278 int routing_id, |
236 InputEventDispatchType dispatch_type, | 279 InputEventDispatchType dispatch_type, |
237 InputEventAckState ack_state, | 280 InputEventAckState ack_state, |
238 ui::WebScopedInputEvent event, | 281 ui::WebScopedInputEvent event, |
239 const ui::LatencyInfo& latency_info, | 282 const ui::LatencyInfo& latency_info, |
240 std::unique_ptr<DidOverscrollParams> overscroll_params) { | 283 std::unique_ptr<DidOverscrollParams> overscroll_params) { |
241 bool send_ack = dispatch_type == DISPATCH_TYPE_BLOCKING; | 284 bool send_ack = dispatch_type == DISPATCH_TYPE_BLOCKING; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 return; | 361 return; |
319 } | 362 } |
320 | 363 |
321 CHECK(target_task_runner_->PostTask( | 364 CHECK(target_task_runner_->PostTask( |
322 FROM_HERE, | 365 FROM_HERE, |
323 base::Bind(&InputEventFilter::NeedsMainFrame, this, routing_id))) | 366 base::Bind(&InputEventFilter::NeedsMainFrame, this, routing_id))) |
324 << "PostTask failed"; | 367 << "PostTask failed"; |
325 } | 368 } |
326 | 369 |
327 } // namespace content | 370 } // namespace content |
OLD | NEW |