| Index: content/renderer/input/input_event_filter.cc
|
| diff --git a/content/renderer/input/input_event_filter.cc b/content/renderer/input/input_event_filter.cc
|
| index 1cb4efe7ea2e119301d96a7ecc5b513f668d2f05..0bae7494ccfbbd7546675e4ec816efb4517fa911 100644
|
| --- a/content/renderer/input/input_event_filter.cc
|
| +++ b/content/renderer/input/input_event_filter.cc
|
| @@ -79,10 +79,19 @@ void InputEventFilter::RegisterRoutingID(int routing_id) {
|
| routing_id, this, main_task_runner_, renderer_scheduler_);
|
| }
|
|
|
| +void InputEventFilter::RegisterAssociatedRenderFrameRoutingID(
|
| + int render_frame_routing_id,
|
| + int render_view_routing_id) {
|
| + base::AutoLock locked(routes_lock_);
|
| + DCHECK(routes_.find(render_view_routing_id) != routes_.end());
|
| + associated_routes_[render_frame_routing_id] = render_view_routing_id;
|
| +}
|
| +
|
| void InputEventFilter::UnregisterRoutingID(int routing_id) {
|
| base::AutoLock locked(routes_lock_);
|
| routes_.erase(routing_id);
|
| route_queues_.erase(routing_id);
|
| + associated_routes_.erase(routing_id);
|
| }
|
|
|
| void InputEventFilter::DidOverscroll(int routing_id,
|
| @@ -95,6 +104,22 @@ void InputEventFilter::DidStopFlinging(int routing_id) {
|
| SendMessage(base::MakeUnique<InputHostMsg_DidStopFlinging>(routing_id));
|
| }
|
|
|
| +void InputEventFilter::QueueClosureForMainThreadEventQueue(
|
| + int routing_id,
|
| + const base::Closure& closure) {
|
| + DCHECK(target_task_runner_->BelongsToCurrentThread());
|
| + RouteQueueMap::iterator iter = route_queues_.find(routing_id);
|
| + if (iter != route_queues_.end()) {
|
| + iter->second->QueueClosure(closure);
|
| + return;
|
| + }
|
| +
|
| + // For some reason we didn't find an event queue for the route.
|
| + // Don't drop the task on the floor allow it to execute.
|
| + NOTREACHED();
|
| + main_task_runner_->PostTask(FROM_HERE, closure);
|
| +}
|
| +
|
| void InputEventFilter::DispatchNonBlockingEventToMainThread(
|
| int routing_id,
|
| ui::WebScopedInputEvent event,
|
| @@ -176,22 +201,39 @@ bool InputEventFilter::OnMessageReceived(const IPC::Message& message) {
|
|
|
| TRACE_EVENT0("input", "InputEventFilter::OnMessageReceived::InputMessage");
|
|
|
| + int routing_id = message.routing_id();
|
| {
|
| base::AutoLock locked(routes_lock_);
|
| - if (routes_.find(message.routing_id()) == routes_.end())
|
| - return false;
|
| + if (routes_.find(routing_id) == routes_.end()) {
|
| + // |routes_| is based on the RenderView routing_id but the routing_id
|
| + // may be from a RenderFrame. Messages from RenderFrames should be handled
|
| + // synchronously with the associated RenderView as well.
|
| + // Use the associated table to see if we have a mapping from
|
| + // RenderFrame->RenderView if so use the queue for that routing id.
|
| + // TODO(dtapuska): Input messages should NOT be sent to RenderFrames and
|
| + // RenderViews; they should only goto one and this code will be
|
| + // unnecessary as this would break for mojo which doesn't guarantee
|
| + // ordering on different channels but Chrome IPC does.
|
| + auto associated_routing_id = associated_routes_.find(routing_id);
|
| + if (associated_routing_id == associated_routes_.end() ||
|
| + routes_.find(associated_routing_id->second) == routes_.end()) {
|
| + return false;
|
| + }
|
| + routing_id = associated_routing_id->second;
|
| + }
|
| }
|
|
|
| bool postedTask = target_task_runner_->PostTask(
|
| - FROM_HERE, base::Bind(&InputEventFilter::ForwardToHandler, this, message,
|
| - received_time));
|
| + FROM_HERE, base::Bind(&InputEventFilter::ForwardToHandler, this,
|
| + routing_id, message, received_time));
|
| LOG_IF(WARNING, !postedTask) << "PostTask failed";
|
| return true;
|
| }
|
|
|
| InputEventFilter::~InputEventFilter() {}
|
|
|
| -void InputEventFilter::ForwardToHandler(const IPC::Message& message,
|
| +void InputEventFilter::ForwardToHandler(int associated_routing_id,
|
| + const IPC::Message& message,
|
| base::TimeTicks received_time) {
|
| DCHECK(input_handler_manager_);
|
| DCHECK(target_task_runner_->BelongsToCurrentThread());
|
| @@ -203,13 +245,11 @@ void InputEventFilter::ForwardToHandler(const IPC::Message& message,
|
| "input",
|
| "InputEventFilter::ForwardToHandler::ForwardToMainListener",
|
| TRACE_EVENT_SCOPE_THREAD);
|
| - CHECK(main_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(main_listener_, message)))
|
| - << "PostTask failed";
|
| + input_handler_manager_->QueueClosureForMainThreadEventQueue(
|
| + associated_routing_id, base::Bind(main_listener_, message));
|
| return;
|
| }
|
|
|
| - int routing_id = message.routing_id();
|
| InputMsg_HandleInputEvent::Param params;
|
| if (!InputMsg_HandleInputEvent::Read(&message, ¶ms))
|
| return;
|
| @@ -218,6 +258,9 @@ void InputEventFilter::ForwardToHandler(const IPC::Message& message,
|
| ui::LatencyInfo latency_info = std::get<2>(params);
|
| InputEventDispatchType dispatch_type = std::get<3>(params);
|
|
|
| + // HandleInputEvent is always sent to the RenderView routing ID
|
| + // so it should be the same as the message routing ID.
|
| + DCHECK(associated_routing_id == message.routing_id());
|
| DCHECK(event);
|
| DCHECK(dispatch_type == DISPATCH_TYPE_BLOCKING ||
|
| dispatch_type == DISPATCH_TYPE_NON_BLOCKING);
|
| @@ -226,9 +269,9 @@ void InputEventFilter::ForwardToHandler(const IPC::Message& message,
|
| event->setTimeStampSeconds(ui::EventTimeStampToSeconds(received_time));
|
|
|
| input_handler_manager_->HandleInputEvent(
|
| - routing_id, std::move(event), latency_info,
|
| + associated_routing_id, std::move(event), latency_info,
|
| base::Bind(&InputEventFilter::DidForwardToHandlerAndOverscroll, this,
|
| - routing_id, dispatch_type));
|
| + associated_routing_id, dispatch_type));
|
| };
|
|
|
| void InputEventFilter::DidForwardToHandlerAndOverscroll(
|
|
|