diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-13 17:03:52 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-13 17:03:52 +0000 |
commit | 04741728117ac420a3b4fd483a96a3a087e79b17 (patch) | |
tree | e3265747f56d0a77c151bebae41f0d6ba8357aaa /android_webview | |
parent | 63e53c9725753134e65458fc8b61b313382dccb5 (diff) | |
download | chromium_src-04741728117ac420a3b4fd483a96a3a087e79b17.zip chromium_src-04741728117ac420a3b4fd483a96a3a087e79b17.tar.gz chromium_src-04741728117ac420a3b4fd483a96a3a087e79b17.tar.bz2 |
Fix race condition introduced in r242200 where AwContentsIoThreadClient is queried before a subframe's entry is added.
This happened because the entry was updated on the UI thread through WebContentsObserver::RenderFrameCreated. The race condition was that the IO thread could dispatch a resource request for that subframe before the map is updated.
The fix is to send a message from the renderer to the IO thread when a subframe is created so that the map is updated before any resouce requests arrive.
BUG=304341
R=mkosiba@chromium.org
Review URL: https://codereview.chromium.org/135443002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244521 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview')
5 files changed, 47 insertions, 0 deletions
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 9bbd2b6..0a5ed1e 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc @@ -7,6 +7,7 @@ #include "android_webview/browser/aw_browser_context.h" #include "android_webview/browser/aw_browser_main_parts.h" #include "android_webview/browser/aw_contents_client_bridge_base.h" +#include "android_webview/browser/aw_contents_io_thread_client.h" #include "android_webview/browser/aw_cookie_access_policy.h" #include "android_webview/browser/aw_quota_permission_context.h" #include "android_webview/browser/aw_web_preferences_populater.h" @@ -56,6 +57,7 @@ public: void OnShouldOverrideUrlLoading(int routing_id, const base::string16& url, bool* ignore_navigation); + void OnSubFrameCreated(int parent_render_frame_id, int child_render_frame_id); private: virtual ~AwContentsMessageFilter(); @@ -85,6 +87,7 @@ bool AwContentsMessageFilter::OnMessageReceived(const IPC::Message& message, IPC_BEGIN_MESSAGE_MAP_EX(AwContentsMessageFilter, message, *message_was_ok) IPC_MESSAGE_HANDLER(AwViewHostMsg_ShouldOverrideUrlLoading, OnShouldOverrideUrlLoading) + IPC_MESSAGE_HANDLER(AwViewHostMsg_SubFrameCreated, OnSubFrameCreated) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -106,6 +109,12 @@ void AwContentsMessageFilter::OnShouldOverrideUrlLoading( } } +void AwContentsMessageFilter::OnSubFrameCreated(int parent_render_frame_id, + int child_render_frame_id) { + AwContentsIoThreadClient::SubFrameCreated( + process_id_, parent_render_frame_id, child_render_frame_id); +} + class AwAccessTokenStore : public content::AccessTokenStore { public: AwAccessTokenStore() { } diff --git a/android_webview/browser/aw_contents_io_thread_client.h b/android_webview/browser/aw_contents_io_thread_client.h index 11c17f7..8186739 100644 --- a/android_webview/browser/aw_contents_io_thread_client.h +++ b/android_webview/browser/aw_contents_io_thread_client.h @@ -62,6 +62,11 @@ class AwContentsIoThreadClient { static scoped_ptr<AwContentsIoThreadClient> FromID(int render_process_id, int render_frame_id); + // Called on the IO thread when a subframe is created. + static void SubFrameCreated(int render_process_id, + int parent_render_frame_id, + int child_render_frame_id); + // This method is called on the IO thread only. virtual scoped_ptr<InterceptedRequestData> ShouldInterceptRequest( const GURL& location, diff --git a/android_webview/common/render_view_messages.h b/android_webview/common/render_view_messages.h index 35266dd..4aefc35 100644 --- a/android_webview/common/render_view_messages.h +++ b/android_webview/common/render_view_messages.h @@ -110,3 +110,8 @@ IPC_SYNC_MESSAGE_CONTROL2_1(AwViewHostMsg_ShouldOverrideUrlLoading, int /* render_frame_id id */, base::string16 /* in - url */, bool /* out - result */) + +// Sent when a subframe is created. +IPC_MESSAGE_CONTROL2(AwViewHostMsg_SubFrameCreated, + int /* parent_render_frame_id */, + int /* child_render_frame_id */) diff --git a/android_webview/native/aw_contents_io_thread_client_impl.cc b/android_webview/native/aw_contents_io_thread_client_impl.cc index ccdbbff..0082683 100644 --- a/android_webview/native/aw_contents_io_thread_client_impl.cc +++ b/android_webview/native/aw_contents_io_thread_client_impl.cc @@ -166,6 +166,22 @@ AwContentsIoThreadClient::FromID(int render_process_id, int render_frame_id) { } // static +void AwContentsIoThreadClient::SubFrameCreated(int render_process_id, + int parent_render_frame_id, + int child_render_frame_id) { + pair<int, int> parent_rfh_id(render_process_id, parent_render_frame_id); + pair<int, int> child_rfh_id(render_process_id, child_render_frame_id); + IoThreadClientData client_data; + if (!RfhToIoThreadClientMap::GetInstance()->Get(parent_rfh_id, + &client_data)) { + NOTREACHED(); + return; + } + + RfhToIoThreadClientMap::GetInstance()->Set(child_rfh_id, client_data); +} + +// static void AwContentsIoThreadClientImpl::RegisterPendingContents( WebContents* web_contents) { IoThreadClientData client_data; diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc index 09f5a5c..cc2c3b3 100644 --- a/android_webview/renderer/aw_content_renderer_client.cc +++ b/android_webview/renderer/aw_content_renderer_client.cc @@ -21,6 +21,7 @@ #include "content/public/renderer/navigation_state.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h" +#include "content/public/renderer/render_view.h" #include "net/base/net_errors.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURL.h" @@ -116,6 +117,17 @@ bool AwContentRendererClient::HandleNavigation( void AwContentRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { new AwPermissionClient(render_frame); + + // TODO(jam): when a RenderFrame is per WebFrame, this can be simplified by + // getting a RenderFrame's WebFrame and calling its parent() method. + content::RenderFrame* parent_frame = + render_frame->GetRenderView()->GetMainRenderFrame(); + if (parent_frame && parent_frame != render_frame) { + // Avoid any race conditions from having the browser's UI thread tell the IO + // thread that a subframe was created. + RenderThread::Get()->Send(new AwViewHostMsg_SubFrameCreated( + parent_frame->GetRoutingID(), render_frame->GetRoutingID())); + } } void AwContentRendererClient::RenderViewCreated( |