Commit 604ef9e1 authored by Ehsan Karamad's avatar Ehsan Karamad Committed by Commit Bot

[ MimeHandlerView ] Fix a loading race

When a resource is intercepted at PluginResponseInterceptorURLLoader, it lets
MimeHandlerViewAttachHelper override the response (which injects a static HTML
page that embeds a GuestView). At this stage, the attach helper post the
creation of MimeHandlerViewEmbedder class to UI (the MHVE will monitor the set
up of MimeHandlerView).

This opens up room for race: if the resource loading finishes sooner and
ReadyToCommitNavigation is called before MimeHandlerViewEmbedder is created then
the MimeHandlerView won't load.

This CL, fixes this problem by deferring load until MimeHandlerViewEmbedder is
created on UI thread.

Bug: 659750, 961731
Change-Id: I8b6e5cc0fb6035464384b50fd182cb00a73ec4f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1605162Reviewed-by: default avatarJames MacLean <wjmaclean@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarŁukasz Anforowicz <lukasza@chromium.org>
Commit-Queue: Ehsan Karamad <ekaramad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#658743}
parent 2071aeb6
......@@ -72,9 +72,13 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(
uint32_t data_pipe_size = 64U;
// Provide the MimeHandlerView code a chance to override the payload. This is
// the case where the resource is handled by frame-based MimeHandlerView.
extensions::MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
*defer = extensions::MimeHandlerViewAttachHelper::
OverrideBodyForInterceptedResponse(
frame_tree_node_id_, response_url, response_head->mime_type, view_id,
&payload, &data_pipe_size);
&payload, &data_pipe_size,
base::BindOnce(
&PluginResponseInterceptorURLLoaderThrottle::ResumeLoad,
base::Unretained(this)));
mojo::DataPipe data_pipe(data_pipe_size);
uint32_t len = static_cast<uint32_t>(payload.size());
......@@ -118,3 +122,7 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(
-1 /* render_process_id */, -1 /* render_frame_id */,
nullptr /* stream */, std::move(transferrable_loader), response_url));
}
void PluginResponseInterceptorURLLoaderThrottle::ResumeLoad() {
delegate_->Resume();
}
......@@ -36,6 +36,9 @@ class PluginResponseInterceptorURLLoaderThrottle
void WillProcessResponse(const GURL& response_url,
network::ResourceResponseHead* response_head,
bool* defer) override;
// Resumes loading for an intercepted response. This would give the extension
// layer chance to initialize its browser side state.
void ResumeLoad();
content::ResourceContext* const resource_context_;
const int resource_type_;
......
......@@ -89,25 +89,29 @@ MimeHandlerViewAttachHelper* MimeHandlerViewAttachHelper::Get(
}
// static
void MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
bool MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
int32_t navigating_frame_tree_node_id,
const GURL& resource_url,
const std::string& mime_type,
const std::string& stream_id,
std::string* payload,
uint32_t* data_pipe_size) {
uint32_t* data_pipe_size,
base::OnceClosure resume_load) {
if (!content::MimeHandlerViewMode::UsesCrossProcessFrame())
return;
return false;
auto color = GetBackgroundColorStringForMimeType(resource_url, mime_type);
auto html_str =
base::StringPrintf(kFullPageMimeHandlerViewHTML, SkColorGetR(color),
SkColorGetG(color), SkColorGetB(color));
payload->assign(html_str);
*data_pipe_size = kFullPageMimeHandlerViewDataPipeSize;
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
base::PostTaskWithTraitsAndReply(
FROM_HERE, {BrowserThread::UI},
base::BindOnce(CreateFullPageMimeHandlerView,
navigating_frame_tree_node_id,
resource_url, mime_type, stream_id));
navigating_frame_tree_node_id, resource_url, mime_type,
stream_id),
std::move(resume_load));
return true;
}
void MimeHandlerViewAttachHelper::RenderProcessHostDestroyed(
......
......@@ -10,6 +10,7 @@
#include <map>
#include <string>
#include "base/bind_helpers.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "content/public/browser/render_process_host_observer.h"
......@@ -43,14 +44,17 @@ class MimeHandlerViewAttachHelper : content::RenderProcessHostObserver {
// renderer is notified to start the MimHandlerView creation process. The
// mentioned child frame will be used to attach the GuestView's WebContents to
// the outer WebContents (WebContents associated with
// |navigating_frame_tree_node_id|).
static void OverrideBodyForInterceptedResponse(
// |navigating_frame_tree_node_id|). When this method returns true, the
// corresponding resource load will be halted until |resume| is invoked. This
// provides an opportunity for UI thread initializations.
static bool OverrideBodyForInterceptedResponse(
int32_t navigating_frame_tree_node_id,
const GURL& resource_url,
const std::string& mime_type,
const std::string& stream_id,
std::string* payload,
uint32_t* data_pipe_size);
uint32_t* data_pipe_size,
base::OnceClosure resume_load = base::DoNothing());
~MimeHandlerViewAttachHelper() override;
......
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