From 691dd57a00c82fb247b695b25a60c060fdfc75dd Mon Sep 17 00:00:00 2001 From: jdduke Date: Tue, 2 Dec 2014 12:47:52 -0800 Subject: aw: Provide main thread input filtering and enable the Blink scheduler Currently, WebView does not use the existing InputEventFilter as it performs synchronous input handling on the compositor thread. As the InputEventFilter provides event delegation to the compositor task runner, this also means input events on WebView are not properly routed to the Blink scheduler. As an intermediate workaround, provide a fallback MainThreadInputEventFilter used whenever the (compositor) InputEventFilter is not installed. Note that this handles the WebView case as well as the case where threaded compositing is completely disabled. BUG=431598 Review URL: https://codereview.chromium.org/716783002 Cr-Commit-Position: refs/heads/master@{#306448} --- content/renderer/input/input_event_filter.cc | 14 ++----- content/renderer/input/input_event_filter.h | 7 ++-- .../renderer/input/input_event_filter_unittest.cc | 13 +++---- .../input/main_thread_input_event_filter.cc | 40 +++++++++++++++++++ .../input/main_thread_input_event_filter.h | 45 ++++++++++++++++++++++ 5 files changed, 97 insertions(+), 22 deletions(-) create mode 100644 content/renderer/input/main_thread_input_event_filter.cc create mode 100644 content/renderer/input/main_thread_input_event_filter.h (limited to 'content/renderer/input') diff --git a/content/renderer/input/input_event_filter.cc b/content/renderer/input/input_event_filter.cc index d2e4f7fd..ff9da937 100644 --- a/content/renderer/input/input_event_filter.cc +++ b/content/renderer/input/input_event_filter.cc @@ -40,7 +40,7 @@ const char* GetInputMessageTypeName(const IPC::Message& message) { namespace content { InputEventFilter::InputEventFilter( - IPC::Listener* main_listener, + const base::Callback& main_listener, const scoped_refptr& main_task_runner, const scoped_refptr& target_loop) : main_task_runner_(main_task_runner), @@ -127,10 +127,6 @@ InputEventFilter::~InputEventFilter() { DCHECK(!current_overscroll_params_); } -void InputEventFilter::ForwardToMainListener(const IPC::Message& message) { - main_listener_->OnMessageReceived(message); -} - void InputEventFilter::ForwardToHandler(const IPC::Message& message) { DCHECK(!handler_.is_null()); DCHECK(target_loop_->BelongsToCurrentThread()); @@ -142,9 +138,7 @@ void InputEventFilter::ForwardToHandler(const IPC::Message& message) { "input", "InputEventFilter::ForwardToHandler::ForwardToMainListener", TRACE_EVENT_SCOPE_THREAD); - main_task_runner_->PostTask( - FROM_HERE, - base::Bind(&InputEventFilter::ForwardToMainListener, this, message)); + main_task_runner_->PostTask(FROM_HERE, base::Bind(main_listener_, message)); return; } @@ -176,9 +170,7 @@ void InputEventFilter::ForwardToHandler(const IPC::Message& message) { TRACE_EVENT_SCOPE_THREAD); IPC::Message new_msg = InputMsg_HandleInputEvent( routing_id, event, latency_info, is_keyboard_shortcut); - main_task_runner_->PostTask( - FROM_HERE, - base::Bind(&InputEventFilter::ForwardToMainListener, this, new_msg)); + main_task_runner_->PostTask(FROM_HERE, base::Bind(main_listener_, new_msg)); return; } diff --git a/content/renderer/input/input_event_filter.h b/content/renderer/input/input_event_filter.h index 19eac67..e58798d 100644 --- a/content/renderer/input/input_event_filter.h +++ b/content/renderer/input/input_event_filter.h @@ -8,7 +8,7 @@ #include #include -#include "base/callback_forward.h" +#include "base/callback.h" #include "base/synchronization/lock.h" #include "content/common/content_export.h" #include "content/common/input/input_event_ack_state.h" @@ -40,7 +40,7 @@ class CONTENT_EXPORT InputEventFilter : public InputHandlerManagerClient, public IPC::MessageFilter { public: InputEventFilter( - IPC::Listener* main_listener, + const base::Callback& main_listener, const scoped_refptr& main_task_runner, const scoped_refptr& target_loop); @@ -71,13 +71,12 @@ class CONTENT_EXPORT InputEventFilter : public InputHandlerManagerClient, private: ~InputEventFilter() override; - void ForwardToMainListener(const IPC::Message& message); void ForwardToHandler(const IPC::Message& message); void SendMessage(scoped_ptr message); void SendMessageOnIOThread(scoped_ptr message); scoped_refptr main_task_runner_; - IPC::Listener* main_listener_; + base::Callback main_listener_; // The sender_ only gets invoked on the thread corresponding to io_loop_. scoped_refptr io_loop_; diff --git a/content/renderer/input/input_event_filter_unittest.cc b/content/renderer/input/input_event_filter_unittest.cc index b7befdb..df08796 100644 --- a/content/renderer/input/input_event_filter_unittest.cc +++ b/content/renderer/input/input_event_filter_unittest.cc @@ -126,19 +126,18 @@ void AddEventsToFilter(IPC::MessageFilter* message_filter, class InputEventFilterTest : public testing::Test { public: void SetUp() override { - filter_ = new InputEventFilter(&message_recorder_, - base::MessageLoopProxy::current(), - message_loop_.message_loop_proxy()); - filter_->SetBoundHandler( - base::Bind(&InputEventRecorder::HandleInputEvent, - base::Unretained(&event_recorder_))); + filter_ = new InputEventFilter( + base::Bind(base::IgnoreResult(&IPCMessageRecorder::OnMessageReceived), + base::Unretained(&message_recorder_)), + base::MessageLoopProxy::current(), message_loop_.message_loop_proxy()); + filter_->SetBoundHandler(base::Bind(&InputEventRecorder::HandleInputEvent, + base::Unretained(&event_recorder_))); event_recorder_.set_filter(filter_.get()); filter_->OnFilterAdded(&ipc_sink_); } - protected: base::MessageLoop message_loop_; diff --git a/content/renderer/input/main_thread_input_event_filter.cc b/content/renderer/input/main_thread_input_event_filter.cc new file mode 100644 index 0000000..cd6c2ea --- /dev/null +++ b/content/renderer/input/main_thread_input_event_filter.cc @@ -0,0 +1,40 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/input/main_thread_input_event_filter.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "content/common/input_messages.h" +#include "ipc/ipc_listener.h" + +namespace content { + +MainThreadInputEventFilter::MainThreadInputEventFilter( + const base::Callback& main_listener, + const scoped_refptr& main_task_runner) + : main_listener_(main_listener), main_task_runner_(main_task_runner) { + DCHECK(main_task_runner.get()); +} + +bool MainThreadInputEventFilter::OnMessageReceived( + const IPC::Message& message) { + DCHECK_EQ(static_cast(IPC_MESSAGE_ID_CLASS(message.type())), + InputMsgStart); + bool handled = main_task_runner_->PostTask( + FROM_HERE, base::Bind(main_listener_, message)); + return handled; +} + +bool MainThreadInputEventFilter::GetSupportedMessageClasses( + std::vector* supported_message_classes) const { + supported_message_classes->push_back(InputMsgStart); + return true; +} + +MainThreadInputEventFilter::~MainThreadInputEventFilter() { +} + +} // namespace content diff --git a/content/renderer/input/main_thread_input_event_filter.h b/content/renderer/input/main_thread_input_event_filter.h new file mode 100644 index 0000000..f540a9c --- /dev/null +++ b/content/renderer/input/main_thread_input_event_filter.h @@ -0,0 +1,45 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_INPUT_MAIN_THREAD_INPUT_EVENT_FILTER_H_ +#define CONTENT_RENDERER_INPUT_MAIN_THREAD_INPUT_EVENT_FILTER_H_ + +#include "base/callback.h" +#include "ipc/message_filter.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace IPC { +class Listener; +} + +namespace content { + +// Used to intercept InputMsg* messages and deliver them to the given listener +// via the provided main thread task runner. Note that usage should be +// restricted to cases where compositor-thread event filtering (via +// |InputEventFilter|) is disabled or otherwise unavailable. +class MainThreadInputEventFilter : public IPC::MessageFilter { + public: + MainThreadInputEventFilter( + const base::Callback& main_listener, + const scoped_refptr& main_task_runner); + + // IPC::MessageFilter implementation. + bool OnMessageReceived(const IPC::Message& message) override; + bool GetSupportedMessageClasses( + std::vector* supported_message_classes) const override; + + private: + ~MainThreadInputEventFilter() override; + + base::Callback main_listener_; + scoped_refptr main_task_runner_; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_INPUT_MAIN_THREAD_INPUT_EVENT_FILTER_H_ -- cgit v1.1