| 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 |