summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-07 21:24:08 +0000
committerjdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-07 21:24:08 +0000
commitb025568b97cd2c3f0e47ef456f463cd1fcdb0a0f (patch)
treef00e60e285595b3cbcefca94fb17d39ffefa3263
parent9c34c413c27316bf196bf3d430b99722ea21755a (diff)
downloadchromium_src-b025568b97cd2c3f0e47ef456f463cd1fcdb0a0f.zip
chromium_src-b025568b97cd2c3f0e47ef456f463cd1fcdb0a0f.tar.gz
chromium_src-b025568b97cd2c3f0e47ef456f463cd1fcdb0a0f.tar.bz2
Fix WebView compositor input handling
Recent changes to compositor input handling deprecated existing hooks for Android WebView. This patch addresses these changes, allowing the browser to perform synchronous, in-process input event handling when the UI and compositor threads are merged. In particular, an InputHandlerManagerClient allows the embedder to customize delivery of and response to InputEvents. BUG=241641 Review URL: https://chromiumcodereview.appspot.com/15920002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204933 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/android/content_view_core_impl.cc9
-rw-r--r--content/browser/android/content_view_core_impl.h6
-rw-r--r--content/browser/android/in_process/DEPS2
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.cc33
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.h11
-rw-r--r--content/browser/android/in_process/synchronous_input_event_filter.cc44
-rw-r--r--content/browser/android/in_process/synchronous_input_event_filter.h46
-rw-r--r--content/browser/android/sync_input_event_filter.cc31
-rw-r--r--content/browser/android/sync_input_event_filter.h39
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc13
-rw-r--r--content/content_browser.gypi4
-rw-r--r--content/content_renderer.gypi1
-rw-r--r--content/renderer/android/synchronous_compositor_factory.h5
-rw-r--r--content/renderer/gpu/input_event_filter.cc19
-rw-r--r--content/renderer/gpu/input_event_filter.h19
-rw-r--r--content/renderer/gpu/input_event_filter_unittest.cc8
-rw-r--r--content/renderer/gpu/input_handler_manager.cc52
-rw-r--r--content/renderer/gpu/input_handler_manager.h23
-rw-r--r--content/renderer/gpu/input_handler_manager_client.h44
-rw-r--r--content/renderer/gpu/input_handler_proxy.h1
-rw-r--r--content/renderer/render_thread_impl.cc25
-rw-r--r--content/renderer/render_thread_impl.h3
22 files changed, 272 insertions, 166 deletions
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 9093c2b..846fa91 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -17,7 +17,6 @@
#include "content/browser/android/interstitial_page_delegate_android.h"
#include "content/browser/android/load_url_params.h"
#include "content/browser/android/media_player_manager_impl.h"
-#include "content/browser/android/sync_input_event_filter.h"
#include "content/browser/android/touch_point.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/browser/renderer_host/java/java_bound_object.h"
@@ -688,14 +687,6 @@ float ContentViewCoreImpl::GetOverdrawBottomHeightDip() const {
/ GetDpiScale();
}
-InputEventAckState ContentViewCoreImpl::FilterInputEvent(
- const WebKit::WebInputEvent& input_event) {
- if (!input_event_filter_)
- return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
-
- return input_event_filter_->HandleInputEvent(input_event);
-}
-
void ContentViewCoreImpl::AttachLayer(scoped_refptr<cc::Layer> layer) {
root_layer_->AddChild(layer);
}
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index c1e5c21..4581e69 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -33,7 +33,6 @@ class WindowAndroid;
namespace content {
class RenderWidgetHostViewAndroid;
-class SyncInputEventFilter;
// TODO(jrg): this is a shell. Upstream the rest.
class ContentViewCoreImpl : public ContentViewCore,
@@ -296,8 +295,6 @@ class ContentViewCoreImpl : public ContentViewCore,
gfx::Size GetViewportSizeOffsetDip() const;
float GetOverdrawBottomHeightDip() const;
- InputEventAckState FilterInputEvent(const WebKit::WebInputEvent& input_event);
-
void AttachLayer(scoped_refptr<cc::Layer> layer);
void RemoveLayer(scoped_refptr<cc::Layer> layer);
void SetVSyncNotificationEnabled(bool enabled);
@@ -361,9 +358,6 @@ class ContentViewCoreImpl : public ContentViewCore,
std::vector<UpdateFrameInfoCallback> update_frame_info_callbacks_;
- // Optional browser-side input event filtering.
- scoped_ptr<SyncInputEventFilter> input_event_filter_;
-
DISALLOW_COPY_AND_ASSIGN(ContentViewCoreImpl);
};
diff --git a/content/browser/android/in_process/DEPS b/content/browser/android/in_process/DEPS
index 98af01f..a8ba3f4 100644
--- a/content/browser/android/in_process/DEPS
+++ b/content/browser/android/in_process/DEPS
@@ -1,6 +1,6 @@
include_rules = [
# Required for SynchronousCompositor (in --single-process mode only).
"+content/public/renderer/android",
- "+content/renderer/android",
+ "+content/renderer",
# Include joth@chromium.org on the review for any additions to this file.
]
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc
index 4b70c9b..ea72bc7 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_impl.cc
@@ -6,6 +6,7 @@
#include "base/lazy_instance.h"
#include "base/message_loop.h"
+#include "content/browser/android/in_process/synchronous_input_event_filter.h"
#include "content/public/browser/android/synchronous_compositor_client.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
@@ -49,6 +50,17 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
new SynchronousCompositorOutputSurface(routing_id));
return output_surface.PassAs<cc::OutputSurface>();
}
+
+ virtual InputHandlerManagerClient* GetInputHandlerManagerClient() OVERRIDE {
+ return synchronous_input_event_filter();
+ }
+
+ SynchronousInputEventFilter* synchronous_input_event_filter() {
+ return &synchronous_input_event_filter_;
+ }
+
+ private:
+ SynchronousInputEventFilter synchronous_input_event_filter_;
};
base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
@@ -59,10 +71,11 @@ base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl);
// static
-SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
- int routing_id) {
- RenderViewHost* rvh = RenderViewHost::FromID(GetInProcessRendererId(),
- routing_id);
+SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id,
+ int routing_id) {
+ if (g_factory == NULL)
+ return NULL;
+ RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id);
if (!rvh)
return NULL;
WebContents* contents = WebContents::FromRenderViewHost(rvh);
@@ -71,6 +84,11 @@ SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
return FromWebContents(contents);
}
+SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
+ int routing_id) {
+ return FromID(GetInProcessRendererId(), routing_id);
+}
+
SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents)
: compositor_client_(NULL),
output_surface_(NULL),
@@ -139,6 +157,13 @@ void SynchronousCompositorImpl::SetContinuousInvalidate(bool enable) {
compositor_client_->SetContinuousInvalidate(enable);
}
+InputEventAckState SynchronousCompositorImpl::HandleInputEvent(
+ const WebKit::WebInputEvent& input_event) {
+ DCHECK(CalledOnValidThread());
+ return g_factory.Get().synchronous_input_event_filter()->HandleInputEvent(
+ routing_id_, input_event);
+}
+
// Not using base::NonThreadSafe as we want to enforce a more exacting threading
// requirement: SynchronousCompositorImpl() must only be used on the UI thread.
bool SynchronousCompositorImpl::CalledOnValidThread() const {
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h
index 3659ca0..c6aced8 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -9,9 +9,14 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/android/in_process/synchronous_compositor_output_surface.h"
+#include "content/port/common/input_event_ack_state.h"
#include "content/public/browser/android/synchronous_compositor.h"
#include "content/public/browser/web_contents_user_data.h"
+namespace WebKit {
+class WebInputEvent;
+}
+
namespace content {
// The purpose of this class is to act as the intermediary between the various
@@ -24,8 +29,14 @@ class SynchronousCompositorImpl
public SynchronousCompositorOutputSurfaceDelegate,
public WebContentsUserData<SynchronousCompositorImpl> {
public:
+ // When used from browser code, use both |process_id| and |routing_id|.
+ static SynchronousCompositorImpl* FromID(int process_id, int routing_id);
+ // When handling upcalls from renderer code, use this version; the process id
+ // is implicitly that of the in-process renderer.
static SynchronousCompositorImpl* FromRoutingID(int routing_id);
+ InputEventAckState HandleInputEvent(const WebKit::WebInputEvent& input_event);
+
// SynchronousCompositor
virtual bool IsHwReady() OVERRIDE;
virtual void SetClient(SynchronousCompositorClient* compositor_client)
diff --git a/content/browser/android/in_process/synchronous_input_event_filter.cc b/content/browser/android/in_process/synchronous_input_event_filter.cc
new file mode 100644
index 0000000..3e0c09a
--- /dev/null
+++ b/content/browser/android/in_process/synchronous_input_event_filter.cc
@@ -0,0 +1,44 @@
+// Copyright 2013 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/browser/android/in_process/synchronous_input_event_filter.h"
+
+#include "content/public/browser/browser_thread.h"
+
+using WebKit::WebInputEvent;
+
+namespace content {
+
+SynchronousInputEventFilter::SynchronousInputEventFilter() {
+}
+
+SynchronousInputEventFilter::~SynchronousInputEventFilter() {
+}
+
+InputEventAckState SynchronousInputEventFilter::HandleInputEvent(
+ int routing_id,
+ const WebKit::WebInputEvent& input_event) {
+ // The handler will be empty both before renderer initialization and after
+ // renderer destruction. It's possible that this will be reached in such a
+ // state. While not good, it should also not be fatal.
+ if (handler_.is_null())
+ return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
+
+ return handler_.Run(routing_id, &input_event);
+}
+
+void SynchronousInputEventFilter::SetBoundHandler(const Handler& handler) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&SynchronousInputEventFilter::SetBoundHandlerOnUIThread,
+ base::Unretained(this), handler));
+}
+
+void SynchronousInputEventFilter::SetBoundHandlerOnUIThread(
+ const Handler& handler) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ handler_ = handler;
+}
+
+} // namespace content
diff --git a/content/browser/android/in_process/synchronous_input_event_filter.h b/content/browser/android/in_process/synchronous_input_event_filter.h
new file mode 100644
index 0000000..75b5be1
--- /dev/null
+++ b/content/browser/android/in_process/synchronous_input_event_filter.h
@@ -0,0 +1,46 @@
+// Copyright 2013 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_BROWSER_ANDOIRD_IN_PROCESS_SYNCHRONOUS_INPUT_EVENT_FILTER_H_
+#define CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_INPUT_EVENT_FILTER_H_
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "content/port/common/input_event_ack_state.h"
+#include "content/renderer/gpu/input_handler_manager_client.h"
+
+namespace WebKit {
+class WebInputEvent;
+}
+
+namespace content {
+
+// This class perform synchronous, in-process InputEvent handling.
+//
+// The provided |handler| process WebInputEvents synchronously on the merged
+// UI and compositing thread. If the event goes unhandled, that is reflected in
+// the InputEventAckState; no forwarding is performed.
+class SynchronousInputEventFilter : public InputHandlerManagerClient {
+ public:
+ SynchronousInputEventFilter();
+ virtual ~SynchronousInputEventFilter();
+
+ InputEventAckState HandleInputEvent(int routing_id,
+ const WebKit::WebInputEvent& input_event);
+
+ // InputHandlerManagerClient implementation.
+ virtual void SetBoundHandler(const Handler& handler) OVERRIDE;
+ virtual void DidAddInputHandler(int routing_id) OVERRIDE {}
+ virtual void DidRemoveInputHandler(int routing_id) OVERRIDE {}
+
+ private:
+ void SetBoundHandlerOnUIThread(const Handler& handler);
+
+ Handler handler_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_ANDROID_SYNCHRONOUS_INPUT_EVENT_FILTER_H_
diff --git a/content/browser/android/sync_input_event_filter.cc b/content/browser/android/sync_input_event_filter.cc
deleted file mode 100644
index fb252c36..0000000
--- a/content/browser/android/sync_input_event_filter.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2013 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 "base/debug/trace_event.h"
-#include "content/browser/android/sync_input_event_filter.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
-
-using WebKit::WebInputEvent;
-
-namespace content {
-
-//------------------------------------------------------------------------------
-
-SyncInputEventFilter::SyncInputEventFilter() {
-}
-
-SyncInputEventFilter::~SyncInputEventFilter() {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-InputEventAckState SyncInputEventFilter::HandleInputEvent(
- const WebInputEvent& event) {
- return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
-}
-
-void SyncInputEventFilter::ClearInputHandler() {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-} // namespace content
diff --git a/content/browser/android/sync_input_event_filter.h b/content/browser/android/sync_input_event_filter.h
deleted file mode 100644
index e2ce90b..0000000
--- a/content/browser/android/sync_input_event_filter.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2013 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_BROWSER_ANDROID_SYNC_INPUT_EVENT_FILTER_H_
-#define CONTENT_BROWSER_ANDROID_SYNC_INPUT_EVENT_FILTER_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "content/port/common/input_event_ack_state.h"
-
-namespace WebKit {
-class WebInputEvent;
-}
-
-namespace content {
-
-// Performs synchronous event filtering, to be used for browser-side,
-// in-process event handling when the UI and compositor share threads.
-// The filter is associated with at most one view, and one event handler.
-class SyncInputEventFilter {
- public:
-
- SyncInputEventFilter();
- ~SyncInputEventFilter();
-
- InputEventAckState HandleInputEvent(const WebKit::WebInputEvent& input_event);
- void ClearInputHandler();
-
- private:
- // Used to DCHECK that input_handler_ changes are made on the correct thread.
- base::ThreadChecker thread_checker_;
-
- DISALLOW_COPY_AND_ASSIGN(SyncInputEventFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_SYNC_INPUT_EVENT_FILTER_H_
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 408f753..88b4acf 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -19,6 +19,7 @@
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
#include "content/browser/android/content_view_core_impl.h"
+#include "content/browser/android/in_process/synchronous_compositor_impl.h"
#include "content/browser/android/overscroll_glow.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
@@ -829,10 +830,14 @@ void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
const WebKit::WebInputEvent& input_event) {
- if (!content_view_core_)
- return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
-
- return content_view_core_->FilterInputEvent(input_event);
+ if (host_) {
+ SynchronousCompositorImpl* compositor =
+ SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
+ host_->GetRoutingID());
+ if (compositor)
+ return compositor->HandleInputEvent(input_event);
+ }
+ return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
}
void RenderWidgetHostViewAndroid::OnAccessibilityNotifications(
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 41dc8d1..7f8c4c5 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -251,6 +251,8 @@
'browser/android/in_process/synchronous_compositor_impl.h',
'browser/android/in_process/synchronous_compositor_output_surface.cc',
'browser/android/in_process/synchronous_compositor_output_surface.h',
+ 'browser/android/in_process/synchronous_input_event_filter.cc',
+ 'browser/android/in_process/synchronous_input_event_filter.h',
'browser/android/interstitial_page_delegate_android.cc',
'browser/android/interstitial_page_delegate_android.h',
'browser/android/load_url_params.cc',
@@ -263,8 +265,6 @@
'browser/android/overscroll_glow.cc',
'browser/android/surface_texture_peer_browser_impl.cc',
'browser/android/surface_texture_peer_browser_impl.h',
- 'browser/android/sync_input_event_filter.h',
- 'browser/android/sync_input_event_filter.cc',
'browser/android/touch_point.cc',
'browser/android/touch_point.h',
'browser/android/tracing_intent_handler.cc',
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index aca8515..07f946f 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -111,6 +111,7 @@
'renderer/gpu/input_handler_proxy.h',
'renderer/gpu/input_handler_manager.cc',
'renderer/gpu/input_handler_manager.h',
+ 'renderer/gpu/input_handler_manager_client.h',
'renderer/gpu/input_handler_wrapper.cc',
'renderer/gpu/input_handler_wrapper.h',
'renderer/gpu/gpu_benchmarking_extension.cc',
diff --git a/content/renderer/android/synchronous_compositor_factory.h b/content/renderer/android/synchronous_compositor_factory.h
index 9c8fdce..06e7c36 100644
--- a/content/renderer/android/synchronous_compositor_factory.h
+++ b/content/renderer/android/synchronous_compositor_factory.h
@@ -18,6 +18,8 @@ class OutputSurface;
namespace content {
+class InputHandlerManagerClient;
+
// Decouples creation from usage of the parts needed for the synchonous
// compositor rendering path. In practice this is only used in single
// process mode (namely, for Android WebView) hence the implementation of
@@ -34,6 +36,9 @@ class SynchronousCompositorFactory {
virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(
int routing_id) = 0;
+ // The factory maintains ownership of the returned interface.
+ virtual InputHandlerManagerClient* GetInputHandlerManagerClient() = 0;
+
protected:
SynchronousCompositorFactory() {}
~SynchronousCompositorFactory() {}
diff --git a/content/renderer/gpu/input_event_filter.cc b/content/renderer/gpu/input_event_filter.cc
index 9085c156..4032e8f 100644
--- a/content/renderer/gpu/input_event_filter.cc
+++ b/content/renderer/gpu/input_event_filter.cc
@@ -15,23 +15,25 @@ namespace content {
InputEventFilter::InputEventFilter(
IPC::Listener* main_listener,
- const scoped_refptr<base::MessageLoopProxy>& target_loop,
- const Handler& handler)
+ const scoped_refptr<base::MessageLoopProxy>& target_loop)
: main_loop_(base::MessageLoopProxy::current()),
main_listener_(main_listener),
sender_(NULL),
- target_loop_(target_loop),
- handler_(handler) {
- DCHECK(target_loop_.get());
- DCHECK(!handler_.is_null());
+ target_loop_(target_loop) {
+ DCHECK(target_loop_);
+}
+
+void InputEventFilter::SetBoundHandler(const Handler& handler) {
+ DCHECK(main_loop_->BelongsToCurrentThread());
+ handler_ = handler;
}
-void InputEventFilter::AddRoute(int routing_id) {
+void InputEventFilter::DidAddInputHandler(int routing_id) {
base::AutoLock locked(routes_lock_);
routes_.insert(routing_id);
}
-void InputEventFilter::RemoveRoute(int routing_id) {
+void InputEventFilter::DidRemoveInputHandler(int routing_id) {
base::AutoLock locked(routes_lock_);
routes_.erase(routing_id);
}
@@ -93,6 +95,7 @@ void InputEventFilter::ForwardToMainListener(const IPC::Message& message) {
}
void InputEventFilter::ForwardToHandler(const IPC::Message& message) {
+ DCHECK(!handler_.is_null());
DCHECK(target_loop_->BelongsToCurrentThread());
if (message.type() != InputMsg_HandleInputEvent::ID) {
diff --git a/content/renderer/gpu/input_event_filter.h b/content/renderer/gpu/input_event_filter.h
index 693aefa..499003c 100644
--- a/content/renderer/gpu/input_event_filter.h
+++ b/content/renderer/gpu/input_event_filter.h
@@ -12,6 +12,7 @@
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
#include "content/port/common/input_event_ack_state.h"
+#include "content/renderer/gpu/input_handler_manager_client.h"
#include "ipc/ipc_channel_proxy.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
@@ -26,11 +27,11 @@
namespace content {
class CONTENT_EXPORT InputEventFilter
- : public IPC::ChannelProxy::MessageFilter {
+ : public InputHandlerManagerClient,
+ public IPC::ChannelProxy::MessageFilter {
public:
- typedef base::Callback<InputEventAckState(
- int /*routing_id*/,
- const WebKit::WebInputEvent*)> Handler;
+ InputEventFilter(IPC::Listener* main_listener,
+ const scoped_refptr<base::MessageLoopProxy>& target_loop);
// The |handler| is invoked on the thread associated with |target_loop| to
// handle input events matching the filtered routes.
@@ -42,13 +43,9 @@ class CONTENT_EXPORT InputEventFilter
// is left to the eventual handler to deliver the corresponding
// InputHostMsg_HandleInputEvent_ACK.
//
- InputEventFilter(IPC::Listener* main_listener,
- const scoped_refptr<base::MessageLoopProxy>& target_loop,
- const Handler& handler);
-
- // Define the message routes to be filtered.
- void AddRoute(int routing_id);
- void RemoveRoute(int routing_id);
+ virtual void SetBoundHandler(const Handler& handler) OVERRIDE;
+ virtual void DidAddInputHandler(int routing_id) OVERRIDE;
+ virtual void DidRemoveInputHandler(int routing_id) OVERRIDE;
// IPC::ChannelProxy::MessageFilter methods:
virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
diff --git a/content/renderer/gpu/input_event_filter_unittest.cc b/content/renderer/gpu/input_event_filter_unittest.cc
index 7fbeafe..8f48f12 100644
--- a/content/renderer/gpu/input_event_filter_unittest.cc
+++ b/content/renderer/gpu/input_event_filter_unittest.cc
@@ -135,9 +135,11 @@ class InputEventFilterTest : public testing::Test {
virtual void SetUp() OVERRIDE {
filter_ = new InputEventFilter(
&message_recorder_,
- message_loop_.message_loop_proxy(),
+ 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_);
@@ -170,7 +172,7 @@ TEST_F(InputEventFilterTest, Basic) {
EXPECT_EQ(0U, event_recorder_.record_count());
EXPECT_EQ(0U, message_recorder_.message_count());
- filter_->AddRoute(kTestRoutingID);
+ filter_->DidAddInputHandler(kTestRoutingID);
AddEventsToFilter(filter_.get(), kEvents, arraysize(kEvents));
ASSERT_EQ(arraysize(kEvents), ipc_sink_.message_count());
@@ -245,7 +247,7 @@ TEST_F(InputEventFilterTest, Basic) {
}
TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
- filter_->AddRoute(kTestRoutingID);
+ filter_->DidAddInputHandler(kTestRoutingID);
event_recorder_.set_send_to_widget(true);
diff --git a/content/renderer/gpu/input_handler_manager.cc b/content/renderer/gpu/input_handler_manager.cc
index 15c49cc..61617a9 100644
--- a/content/renderer/gpu/input_handler_manager.cc
+++ b/content/renderer/gpu/input_handler_manager.cc
@@ -8,8 +8,8 @@
#include "base/debug/trace_event.h"
#include "cc/input/input_handler.h"
#include "content/renderer/gpu/input_event_filter.h"
+#include "content/renderer/gpu/input_handler_manager_client.h"
#include "content/renderer/gpu/input_handler_wrapper.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebActiveWheelFlingParameters.h"
using WebKit::WebInputEvent;
@@ -34,38 +34,38 @@ InputEventAckState InputEventDispositionToAck(
} // namespace
InputHandlerManager::InputHandlerManager(
- IPC::Listener* main_listener,
- const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy)
- : message_loop_proxy_(message_loop_proxy) {
- filter_ =
- new InputEventFilter(main_listener,
- message_loop_proxy,
- base::Bind(&InputHandlerManager::HandleInputEvent,
+ const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
+ InputHandlerManagerClient* client)
+ : message_loop_proxy_(message_loop_proxy),
+ client_(client) {
+ DCHECK(client_);
+ client_->SetBoundHandler(base::Bind(&InputHandlerManager::HandleInputEvent,
base::Unretained(this)));
}
InputHandlerManager::~InputHandlerManager() {
-}
-
-IPC::ChannelProxy::MessageFilter*
-InputHandlerManager::GetMessageFilter() const {
- return filter_.get();
+ client_->SetBoundHandler(InputHandlerManagerClient::Handler());
}
void InputHandlerManager::AddInputHandler(
int routing_id,
const base::WeakPtr<cc::InputHandler>& input_handler,
const base::WeakPtr<RenderViewImpl>& render_view_impl) {
- DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
-
- message_loop_proxy_->PostTask(
- FROM_HERE,
- base::Bind(&InputHandlerManager::AddInputHandlerOnCompositorThread,
- base::Unretained(this),
- routing_id,
- base::MessageLoopProxy::current(),
- input_handler,
- render_view_impl));
+ if (message_loop_proxy_->BelongsToCurrentThread()) {
+ AddInputHandlerOnCompositorThread(routing_id,
+ base::MessageLoopProxy::current(),
+ input_handler,
+ render_view_impl);
+ } else {
+ message_loop_proxy_->PostTask(
+ FROM_HERE,
+ base::Bind(&InputHandlerManager::AddInputHandlerOnCompositorThread,
+ base::Unretained(this),
+ routing_id,
+ base::MessageLoopProxy::current(),
+ input_handler,
+ render_view_impl));
+ }
}
void InputHandlerManager::AddInputHandlerOnCompositorThread(
@@ -76,7 +76,7 @@ void InputHandlerManager::AddInputHandlerOnCompositorThread(
DCHECK(message_loop_proxy_->BelongsToCurrentThread());
// The handler could be gone by this point if the compositor has shut down.
- if (!input_handler.get())
+ if (!input_handler)
return;
// The same handler may be registered for a route multiple times.
@@ -84,7 +84,7 @@ void InputHandlerManager::AddInputHandlerOnCompositorThread(
return;
TRACE_EVENT0("InputHandlerManager::AddInputHandler", "AddingRoute");
- filter_->AddRoute(routing_id);
+ client_->DidAddInputHandler(routing_id);
input_handlers_[routing_id] =
make_scoped_refptr(new InputHandlerWrapper(this,
routing_id, main_loop, input_handler, render_view_impl));
@@ -95,7 +95,7 @@ void InputHandlerManager::RemoveInputHandler(int routing_id) {
TRACE_EVENT0("InputHandlerManager::RemoveInputHandler", "RemovingRoute");
- filter_->RemoveRoute(routing_id);
+ client_->DidRemoveInputHandler(routing_id);
input_handlers_.erase(routing_id);
}
diff --git a/content/renderer/gpu/input_handler_manager.h b/content/renderer/gpu/input_handler_manager.h
index 598e944..904db0d 100644
--- a/content/renderer/gpu/input_handler_manager.h
+++ b/content/renderer/gpu/input_handler_manager.h
@@ -7,10 +7,10 @@
#include <map>
+#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/port/common/input_event_ack_state.h"
#include "content/renderer/render_view_impl.h"
-#include "ipc/ipc_channel_proxy.h"
namespace base {
class MessageLoopProxy;
@@ -26,26 +26,20 @@ class WebInputEvent;
namespace content {
-class InputEventFilter;
class InputHandlerWrapper;
+class InputHandlerManagerClient;
// InputHandlerManager class manages InputHandlerProxy instances for
// the WebViews in this renderer.
class InputHandlerManager {
public:
- // |main_listener| refers to the central IPC message listener that lives on
- // the main thread, where all incoming IPC messages are first handled.
- // |message_loop_proxy| is the MessageLoopProxy of the compositor thread.
- // The underlying MessageLoop must outlive this object.
+ // |message_loop_proxy| is the MessageLoopProxy of the compositor thread. Both
+ // the underlying MessageLoop and supplied |client| must outlive this object.
InputHandlerManager(
- IPC::Listener* main_listener,
- const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy);
+ const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
+ InputHandlerManagerClient* client);
~InputHandlerManager();
- // This MessageFilter should be added to allow input events to be redirected
- // to the compositor's thread.
- IPC::ChannelProxy::MessageFilter* GetMessageFilter() const;
-
// Callable from the main thread only.
void AddInputHandler(
int routing_id,
@@ -59,9 +53,6 @@ class InputHandlerManager {
InputEventAckState HandleInputEvent(int routing_id,
const WebKit::WebInputEvent* input_event);
- // Called from the compositor's thread.
- InputEventFilter* filter() { return filter_.get(); }
-
private:
// Called from the compositor's thread.
void AddInputHandlerOnCompositorThread(
@@ -75,7 +66,7 @@ class InputHandlerManager {
InputHandlerMap input_handlers_;
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
- scoped_refptr<InputEventFilter> filter_;
+ InputHandlerManagerClient* client_;
};
} // namespace content
diff --git a/content/renderer/gpu/input_handler_manager_client.h b/content/renderer/gpu/input_handler_manager_client.h
new file mode 100644
index 0000000..deb7839
--- /dev/null
+++ b/content/renderer/gpu/input_handler_manager_client.h
@@ -0,0 +1,44 @@
+// Copyright 2013 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_GPU_INPUT_HANDLER_MANAGER_CLIENT_H_
+#define CONTENT_RENDERER_GPU_INPUT_HANDLER_MANAGER_CLIENT_H_
+
+#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "content/common/content_export.h"
+
+namespace WebKit {
+class WebInputEvent;
+}
+
+namespace content {
+
+class CONTENT_EXPORT InputHandlerManagerClient {
+ public:
+ virtual ~InputHandlerManagerClient() {}
+
+ // The Manager will supply a |handler| when bound to the client. This is valid
+ // until the manager shuts down, at which point it supplies a null |handler|.
+ // The client should only makes calls to |handler| on the compositor thread.
+ typedef base::Callback<InputEventAckState(
+ int /*routing_id*/, const WebKit::WebInputEvent*)> Handler;
+
+ // Called from the main thread.
+ virtual void SetBoundHandler(const Handler& handler) = 0;
+
+ // Called from the compositor thread.
+ virtual void DidAddInputHandler(int routing_id) = 0;
+ virtual void DidRemoveInputHandler(int routing_id) = 0;
+
+ protected:
+ InputHandlerManagerClient() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InputHandlerManagerClient);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_INPUT_HANDLER_MANAGER_CLIENT_H_
diff --git a/content/renderer/gpu/input_handler_proxy.h b/content/renderer/gpu/input_handler_proxy.h
index 5c857ee..3784771 100644
--- a/content/renderer/gpu/input_handler_proxy.h
+++ b/content/renderer/gpu/input_handler_proxy.h
@@ -10,7 +10,6 @@
#include "base/memory/scoped_ptr.h"
#include "cc/input/input_handler.h"
#include "content/common/content_export.h"
-#include "content/port/common/input_event_ack_state.h"
#include "third_party/WebKit/public/platform/WebGestureCurve.h"
#include "third_party/WebKit/public/platform/WebGestureCurveTarget.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebActiveWheelFlingParameters.h"
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 2ed9c18..5bb608c 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -57,6 +57,7 @@
#include "content/renderer/gpu/compositor_output_surface.h"
#include "content/renderer/gpu/gpu_benchmarking_extension.h"
#include "content/renderer/gpu/input_handler_manager.h"
+#include "content/renderer/gpu/input_event_filter.h"
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/media/audio_message_filter.h"
#include "content/renderer/media/audio_renderer_mixer_manager.h"
@@ -456,9 +457,10 @@ void RenderThreadImpl::Shutdown() {
}
compositor_thread_.reset();
- if (input_handler_manager_) {
- RemoveFilter(input_handler_manager_->GetMessageFilter());
- input_handler_manager_.reset();
+ input_handler_manager_.reset();
+ if (input_event_filter_) {
+ RemoveFilter(input_event_filter_.get());
+ input_event_filter_ = NULL;
}
if (webkit_platform_support_)
@@ -775,9 +777,22 @@ void RenderThreadImpl::EnsureWebKitInitialized() {
false));
}
+ InputHandlerManagerClient* input_handler_manager_client = NULL;
+#if defined(OS_ANDROID)
+ if (SynchronousCompositorFactory* factory =
+ SynchronousCompositorFactory::GetInstance()) {
+ input_handler_manager_client = factory->GetInputHandlerManagerClient();
+ }
+#endif
+ if (!input_handler_manager_client) {
+ input_event_filter_ =
+ new InputEventFilter(this, compositor_message_loop_proxy_);
+ AddFilter(input_event_filter_.get());
+ input_handler_manager_client = input_event_filter_.get();
+ }
input_handler_manager_.reset(
- new InputHandlerManager(this, compositor_message_loop_proxy_));
- AddFilter(input_handler_manager_->GetMessageFilter());
+ new InputHandlerManager(compositor_message_loop_proxy_,
+ input_handler_manager_client));
}
scoped_refptr<base::MessageLoopProxy> output_surface_loop;
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index cf48425..1d92af2 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -77,6 +77,7 @@ class DevToolsAgentFilter;
class DomStorageDispatcher;
class GpuChannelHost;
class IndexedDBDispatcher;
+class InputEventFilter;
class InputHandlerManager;
class MediaStreamCenter;
class MediaStreamDependencyFactory;
@@ -437,6 +438,8 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread,
// regardless of whether |compositor_thread_| is overriden.
scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy_;
+ // May be null if unused by the |input_handler_manager_|.
+ scoped_refptr<InputEventFilter> input_event_filter_;
scoped_ptr<InputHandlerManager> input_handler_manager_;
scoped_refptr<IPC::ForwardingMessageFilter> compositor_output_surface_filter_;