Commit 04741728 authored by jam@chromium.org's avatar jam@chromium.org

Fix race condition introduced in r242200 where AwContentsIoThreadClient is...

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
parent 63e53c97
......@@ -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() { }
......
......@@ -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,
......
......@@ -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 */)
......@@ -165,6 +165,22 @@ AwContentsIoThreadClient::FromID(int render_process_id, int render_frame_id) {
client_data.pending_association, java_delegate));
}
// 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) {
......
......@@ -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(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment