diff options
author | steveblock@chromium.org <steveblock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-09 14:44:20 +0000 |
---|---|---|
committer | steveblock@chromium.org <steveblock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-09 14:44:20 +0000 |
commit | 64d0e19684d021f3a27e1acfa733f7e47c041808 (patch) | |
tree | 501fc5dda927814f2e140fada44e473354350e4f /content/renderer/java | |
parent | abcbab71fbf680a104bcac287851be609efddc14 (diff) | |
download | chromium_src-64d0e19684d021f3a27e1acfa733f7e47c041808.zip chromium_src-64d0e19684d021f3a27e1acfa733f7e47c041808.tar.gz chromium_src-64d0e19684d021f3a27e1acfa733f7e47c041808.tar.bz2 |
Fix a race condition in the Java Bridge when adding objects
JavaBridgeDispatcherHost::AddNamedObject() currently has a race condition, as
it posts to the WEBKIT thread before sending the injected object to the
renderer. See bug for details.
To fix this, JavaBridgeDispatcherHost::AddNamedObject() now creates the
NPVariant_Param synchronously, and immediately sends this to the renderer. This
requires use of a route ID generator which is shared with the
JavaBridgeChannelHost. Creation of the JavaBridgeChannelHost and the
corresponding NPObjectStub is done asynchronously on the WEBKIT thread.
This means that the channel handle is not available when the Java Bridge is
first initialized in the renderer. To overcome this, the renderer obtains it
from the browser with a new sync IPC call.
- RenderViewImpl - OnJavaBridgeInit() no longer supplies a channel handle.
- JavaBridgeDispatcher - Lazily gets channel handle from browser.
- JavaBridgeDispatcherHost - Now a RVH obsever to provide channel handle.
Uses shared route ID generator to synchronously create the NPVariant_Param
when a new object is injected. Creates the JavaBridgeChannelHost and the
corresponding NPObjectStub asynchronously on the WEBKIT thread.
- JavaBridgeChannelHost - Shares a route ID generator with the
JavaBridgeDispatcherHost.
BUG=106691
Review URL: http://codereview.chromium.org/8834013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113802 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/java')
-rw-r--r-- | content/renderer/java/java_bridge_dispatcher.cc | 16 | ||||
-rw-r--r-- | content/renderer/java/java_bridge_dispatcher.h | 5 |
2 files changed, 17 insertions, 4 deletions
diff --git a/content/renderer/java/java_bridge_dispatcher.cc b/content/renderer/java/java_bridge_dispatcher.cc index 20b047a..e623cce 100644 --- a/content/renderer/java/java_bridge_dispatcher.cc +++ b/content/renderer/java/java_bridge_dispatcher.cc @@ -16,9 +16,18 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" JavaBridgeDispatcher::JavaBridgeDispatcher( - content::RenderView* render_view, - const IPC::ChannelHandle& channel_handle) + content::RenderView* render_view) : RenderViewObserver(render_view) { +} + +void JavaBridgeDispatcher::EnsureChannelIsSetUp() { + if (channel_.get()) { + return; + } + + IPC::ChannelHandle channel_handle; + Send(new JavaBridgeHostMsg_GetChannelHandle(routing_id(), &channel_handle)); + channel_.reset(JavaBridgeChannel::GetJavaBridgeChannel( channel_handle, ChildProcess::current()->io_message_loop_proxy())); } @@ -62,6 +71,9 @@ void JavaBridgeDispatcher::OnAddNamedObject( const string16& name, const NPVariant_Param& variant_param) { DCHECK_EQ(variant_param.type, NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID); + + EnsureChannelIsSetUp(); + // This creates an NPObject, wrapped as an NPVariant. We don't need the // containing window or the page URL, as we don't do re-entrant sync IPC. NPVariant variant; diff --git a/content/renderer/java/java_bridge_dispatcher.h b/content/renderer/java/java_bridge_dispatcher.h index 7359951..a7d877ef 100644 --- a/content/renderer/java/java_bridge_dispatcher.h +++ b/content/renderer/java/java_bridge_dispatcher.h @@ -19,8 +19,7 @@ class JavaBridgeChannel; // again. class JavaBridgeDispatcher : public content::RenderViewObserver { public: - JavaBridgeDispatcher(content::RenderView* render_view, - const IPC::ChannelHandle& channel_handle); + JavaBridgeDispatcher(content::RenderView* render_view); virtual ~JavaBridgeDispatcher(); private: @@ -33,6 +32,8 @@ class JavaBridgeDispatcher : public content::RenderViewObserver { const NPVariant_Param& variant_param); void OnRemoveNamedObject(const string16& name); + void EnsureChannelIsSetUp(); + // Objects that will be bound to the window when the window object is next // cleared. We hold a ref to these. typedef std::map<string16, NPVariant> ObjectMap; |