Commit 9539fccf authored by Ehsan Karamad's avatar Ehsan Karamad Committed by Commit Bot

[ MimeHandlerView ] Do not create PluginDocument

This CL is the second part in the implementation of navigation to PDF
resources with frame-based MimeHandlerView. This change implements the
logic for creating a MimeHandlerViewFrameContainer in response to
browser's request. To this end, when handling the resource request
response for a PDF mime-type, DOMImplementation avoids creating a
PluginDocument and implements an HTMLDocument instead. The document is
then populated with the templated HTML page injected by the plugin
response interceptor.

Design document:
https://docs.google.com/document/d/1_gJv4_fewyfjI7lcUgFX14iQxDudtEMrsjjWKpkI5BI/edit

Bug: 659750
Change-Id: I9a4490d99391d746333f76979e98682fa6742be7
Reviewed-on: https://chromium-review.googlesource.com/c/1477921Reviewed-by: default avatarJames MacLean <wjmaclean@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Reviewed-by: default avatarEhsan Karamad <ekaramad@chromium.org>
Commit-Queue: Ehsan Karamad <ekaramad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#634499}
parent aecde1de
...@@ -71,6 +71,8 @@ class MimeHandlerViewContainerBase : public blink::WebAssociatedURLLoaderClient, ...@@ -71,6 +71,8 @@ class MimeHandlerViewContainerBase : public blink::WebAssociatedURLLoaderClient,
void DidFinishLoading() override; void DidFinishLoading() override;
protected: protected:
MimeHandlerViewContainerBase();
virtual void CreateMimeHandlerViewGuestIfNecessary(); virtual void CreateMimeHandlerViewGuestIfNecessary();
virtual void OnRetryCreatingMimeHandlerViewGuest(int32_t element_instance_id); virtual void OnRetryCreatingMimeHandlerViewGuest(int32_t element_instance_id);
virtual void OnDestroyFrameContainer(int32_t element_instance_id); virtual void OnDestroyFrameContainer(int32_t element_instance_id);
......
...@@ -30,7 +30,8 @@ void MimeHandlerViewContainerManager::BindRequest( ...@@ -30,7 +30,8 @@ void MimeHandlerViewContainerManager::BindRequest(
} }
MimeHandlerViewContainerManager::MimeHandlerViewContainerManager( MimeHandlerViewContainerManager::MimeHandlerViewContainerManager(
int32_t routing_id) {} int32_t routing_id)
: render_frame_routing_id_(routing_id) {}
MimeHandlerViewContainerManager::~MimeHandlerViewContainerManager() {} MimeHandlerViewContainerManager::~MimeHandlerViewContainerManager() {}
...@@ -39,6 +40,16 @@ void MimeHandlerViewContainerManager::CreateFrameContainer( ...@@ -39,6 +40,16 @@ void MimeHandlerViewContainerManager::CreateFrameContainer(
const std::string& mime_type, const std::string& mime_type,
const std::string& view_id) { const std::string& view_id) {
// TODO(ekaramad): Implement (https://crbug.com/659750). // TODO(ekaramad): Implement (https://crbug.com/659750).
auto* render_frame =
content::RenderFrame::FromRoutingID(render_frame_routing_id_);
if (!render_frame)
return;
DCHECK(MimeHandlerViewFrameContainer::IsSupportedMimeType(mime_type));
auto* child = render_frame->GetWebFrame()->FirstChild();
if (!child || child->IsWebRemoteFrame())
return;
MimeHandlerViewFrameContainer::CreateWithFrame(
child->ToWebLocalFrame(), resource_url, mime_type, view_id);
} }
} // namespace extensions } // namespace extensions
...@@ -30,9 +30,7 @@ class MimeHandlerViewContainerManager ...@@ -30,9 +30,7 @@ class MimeHandlerViewContainerManager
const std::string& view_id) override; const std::string& view_id) override;
private: private:
GURL resource_url_; const int32_t render_frame_routing_id_;
std::string mime_type_;
std::string view_id_;
DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewContainerManager); DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewContainerManager);
}; };
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "content/public/common/webplugininfo.h" #include "content/public/common/webplugininfo.h"
#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_thread.h"
#include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_frame.h" #include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame.h"
...@@ -19,15 +20,6 @@ ...@@ -19,15 +20,6 @@
namespace extensions { namespace extensions {
namespace {
bool IsSupportedMimeType(const std::string& mime_type) {
return mime_type == "text/pdf" || mime_type == "application/pdf" ||
mime_type == "text/csv";
}
} // namespace
class MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver class MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver
: public content::RenderFrameObserver { : public content::RenderFrameObserver {
public: public:
...@@ -54,6 +46,13 @@ void MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver::OnDestruct() { ...@@ -54,6 +46,13 @@ void MimeHandlerViewFrameContainer::RenderFrameLifetimeObserver::OnDestruct() {
container_->OnDestroyFrameContainer(container_->element_instance_id_); container_->OnDestroyFrameContainer(container_->element_instance_id_);
} }
// static.
bool MimeHandlerViewFrameContainer::IsSupportedMimeType(
const std::string& mime_type) {
return mime_type == "text/pdf" || mime_type == "application/pdf" ||
mime_type == "text/csv";
}
// static // static
bool MimeHandlerViewFrameContainer::Create( bool MimeHandlerViewFrameContainer::Create(
const blink::WebElement& plugin_element, const blink::WebElement& plugin_element,
...@@ -77,6 +76,16 @@ bool MimeHandlerViewFrameContainer::Create( ...@@ -77,6 +76,16 @@ bool MimeHandlerViewFrameContainer::Create(
element_instance_id); element_instance_id);
} }
// static
void MimeHandlerViewFrameContainer::CreateWithFrame(
blink::WebLocalFrame* web_frame,
const GURL& resource_url,
const std::string& mime_type,
const std::string& view_id) {
new MimeHandlerViewFrameContainer(web_frame, resource_url, mime_type,
view_id);
}
MimeHandlerViewFrameContainer::MimeHandlerViewFrameContainer( MimeHandlerViewFrameContainer::MimeHandlerViewFrameContainer(
const blink::WebElement& plugin_element, const blink::WebElement& plugin_element,
const GURL& resource_url, const GURL& resource_url,
...@@ -92,23 +101,27 @@ MimeHandlerViewFrameContainer::MimeHandlerViewFrameContainer( ...@@ -92,23 +101,27 @@ MimeHandlerViewFrameContainer::MimeHandlerViewFrameContainer(
element_instance_id_(element_instance_id), element_instance_id_(element_instance_id),
render_frame_lifetime_observer_( render_frame_lifetime_observer_(
new RenderFrameLifetimeObserver(GetEmbedderRenderFrame(), this)) { new RenderFrameLifetimeObserver(GetEmbedderRenderFrame(), this)) {
is_embedded_ = IsEmbedded(); is_embedded_ = true;
if (is_embedded_) { SendResourceRequest();
SendResourceRequest(); }
} else {
// TODO(ekaramad): Currently the full page version gets the same treatment MimeHandlerViewFrameContainer::MimeHandlerViewFrameContainer(
// as the embedded version of MimeHandlerViewFrameContainer; they both send blink::WebLocalFrame* web_local_frame,
// a request for the resource. The full page version however should not as const GURL& resource_url,
// there is already an intercepted stream for the navigation. Change the const std::string& mime_type,
// logic here to a) IsEmbedded() return false for full page, b) the current const std::string& view_id)
// intercepted stream is used and no new URLRequest is sent for the : MimeHandlerViewContainerBase(
// resource, and c) ensure creation of MimeHandlerViewFrameContainer does content::RenderFrame::FromWebFrame(
// not lead to its destruction right away or the Create() method above would web_local_frame->Parent()->ToWebLocalFrame()),
// incorrectly return |true|. Note that currently calling content::WebPluginInfo(),
// CreateMimeHandlerViewGuestIfNecessary() could lead to the destruction of mime_type,
// |this| when |plugin_element| does not have a content frame. resource_url),
NOTREACHED(); element_instance_id_(content::RenderThread::Get()->GenerateRoutingID()) {
} is_embedded_ = false;
view_id_ = view_id;
plugin_frame_routing_id_ =
content::RenderFrame::FromWebFrame(web_local_frame)->GetRoutingID();
MimeHandlerViewContainerBase::CreateMimeHandlerViewGuestIfNecessary();
} }
MimeHandlerViewFrameContainer::~MimeHandlerViewFrameContainer() {} MimeHandlerViewFrameContainer::~MimeHandlerViewFrameContainer() {}
...@@ -149,7 +162,10 @@ gfx::Size MimeHandlerViewFrameContainer::GetElementSize() const { ...@@ -149,7 +162,10 @@ gfx::Size MimeHandlerViewFrameContainer::GetElementSize() const {
} }
blink::WebFrame* MimeHandlerViewFrameContainer::GetContentFrame() const { blink::WebFrame* MimeHandlerViewFrameContainer::GetContentFrame() const {
return blink::WebFrame::FromFrameOwnerElement(plugin_element_); if (is_embedded_)
return blink::WebFrame::FromFrameOwnerElement(plugin_element_);
return GetEmbedderRenderFrame()->GetWebFrame()->FirstChild();
} }
// mime_handler::BeforeUnloadControl implementation. // mime_handler::BeforeUnloadControl implementation.
...@@ -159,13 +175,4 @@ void MimeHandlerViewFrameContainer::SetShowBeforeUnloadDialog( ...@@ -159,13 +175,4 @@ void MimeHandlerViewFrameContainer::SetShowBeforeUnloadDialog(
// TODO(ekaramad): Implement. // TODO(ekaramad): Implement.
} }
bool MimeHandlerViewFrameContainer::IsEmbedded() const {
// TODO(ekaramad): This is currently sending a request regardless of whether
// or not this embed is due to frame navigation to resource. For such cases,
// the renderer has already started a resource request and we should not send
// twice. Find a way to get the intercepted stream and avoid sending an extra
// request here.
return true;
}
} // namespace extensions } // namespace extensions
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
namespace blink { namespace blink {
class WebElement; class WebElement;
class WebFrame; class WebFrame;
class WebLocalFrame;
} // namespace blink } // namespace blink
namespace content { namespace content {
...@@ -26,6 +27,7 @@ namespace extensions { ...@@ -26,6 +27,7 @@ namespace extensions {
// for an embedded MimeHandlerView extension in a cross-origin frame. // for an embedded MimeHandlerView extension in a cross-origin frame.
class MimeHandlerViewFrameContainer : public MimeHandlerViewContainerBase { class MimeHandlerViewFrameContainer : public MimeHandlerViewContainerBase {
public: public:
static bool IsSupportedMimeType(const std::string& mime_type);
static bool Create(const blink::WebElement& plugin_element, static bool Create(const blink::WebElement& plugin_element,
const GURL& resource_url, const GURL& resource_url,
const std::string& mime_type, const std::string& mime_type,
...@@ -35,12 +37,24 @@ class MimeHandlerViewFrameContainer : public MimeHandlerViewContainerBase { ...@@ -35,12 +37,24 @@ class MimeHandlerViewFrameContainer : public MimeHandlerViewContainerBase {
private: private:
class RenderFrameLifetimeObserver; class RenderFrameLifetimeObserver;
friend class RenderFrameLifetimeObserver; friend class RenderFrameLifetimeObserver;
friend class MimeHandlerViewContainerManager;
static void CreateWithFrame(blink::WebLocalFrame* web_frame,
const GURL& resource_url,
const std::string& mime_type,
const std::string& view_id);
MimeHandlerViewFrameContainer(blink::WebLocalFrame* web_frame,
const GURL& resource_url,
const std::string& mime_type,
const std::string& view_id);
MimeHandlerViewFrameContainer(const blink::WebElement& plugin_element, MimeHandlerViewFrameContainer(const blink::WebElement& plugin_element,
const GURL& resource_url, const GURL& resource_url,
const std::string& mime_type, const std::string& mime_type,
const content::WebPluginInfo& plugin_info, const content::WebPluginInfo& plugin_info,
int32_t element_instance_id); int32_t element_instance_id);
~MimeHandlerViewFrameContainer() override; ~MimeHandlerViewFrameContainer() override;
// MimeHandlerViewContainerBase overrides. // MimeHandlerViewContainerBase overrides.
...@@ -58,13 +72,6 @@ class MimeHandlerViewFrameContainer : public MimeHandlerViewContainerBase { ...@@ -58,13 +72,6 @@ class MimeHandlerViewFrameContainer : public MimeHandlerViewContainerBase {
bool show_dialog, bool show_dialog,
SetShowBeforeUnloadDialogCallback callback) override; SetShowBeforeUnloadDialogCallback callback) override;
// Returns true if the container is considered as "embedded". A non-embedded
// MimeHandlerViewFrameContainer is the one which is created as a result of
// navigating a frame (either <iframe> or top-level) to a corresponding
// MimeHandlerView mimetype. For such containers there is no need to request
// the resource immediately.
bool IsEmbedded() const;
void OnMessageReceived(const IPC::Message& message); void OnMessageReceived(const IPC::Message& message);
blink::WebElement plugin_element_; blink::WebElement plugin_element_;
......
...@@ -258,8 +258,10 @@ Document* DOMImplementation::createDocument(const String& type, ...@@ -258,8 +258,10 @@ Document* DOMImplementation::createDocument(const String& type,
// We do not want QuickTime to take over all image types, obviously. // We do not want QuickTime to take over all image types, obviously.
if ((type == "application/pdf" || type == "text/pdf") && plugin_data && if ((type == "application/pdf" || type == "text/pdf") && plugin_data &&
plugin_data->SupportsMimeType(type)) { plugin_data->SupportsMimeType(type)) {
return PluginDocument::Create( return RuntimeEnabledFeatures::MimeHandlerViewInCrossProcessFrameEnabled()
init, plugin_data->PluginBackgroundColorForMimeType(type)); ? HTMLDocument::Create(init)
: PluginDocument::Create(
init, plugin_data->PluginBackgroundColorForMimeType(type));
} }
// multipart/x-mixed-replace is only supported for images. // multipart/x-mixed-replace is only supported for images.
if (MIMETypeRegistry::IsSupportedImageResourceMIMEType(type) || if (MIMETypeRegistry::IsSupportedImageResourceMIMEType(type) ||
......
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