Commit 5053971d authored by Ehsan Karamad's avatar Ehsan Karamad Committed by Commit Bot

Introduce API for external handling of plugins

When the contents of a plugin element (<embed> and <object>) are to be
handeld externally inside an extension (most notably PDF) we currently
use browser plugin. BrowserPlugin is used to render GuestView contents
in another process.

However, BrowserPlugin-based guest views have been deprecated and all
guest views except for MimeHandlerViewGuest are not implemented on top
of cross-process frames.

This CL introduces the first steps in fully replacing BrowserPlugin with
corss-process frames.

Different mechanisms for this project have already been discussed in the
design doc:
https://docs.google.com/document/d/10g7Y9cprYKkch9JZ0TBUWaEnHBJT1nzhskQIt1nHbWM/edit#heading=h.ue5a8s290yhk

Bug: 659750, 330264
Change-Id: If273fbbab3e9f4a4591c61b19d54e4cca73c3464
Reviewed-on: https://chromium-review.googlesource.com/1101161Reviewed-by: default avatarEhsan Karamad <ekaramad@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Ehsan Karamad <ekaramad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#578554}
parent 4658d2a7
...@@ -827,6 +827,15 @@ class BLINK_EXPORT WebLocalFrameClient { ...@@ -827,6 +827,15 @@ class BLINK_EXPORT WebLocalFrameClient {
CreateWebSocketHandshakeThrottle() { CreateWebSocketHandshakeThrottle() {
return nullptr; return nullptr;
} }
// Returns true when the contents of plugin are handled externally. This means
// the plugin element will own a content frame but the frame is than used
// externally to load the required handelrs.
virtual bool IsPluginHandledExternally(const WebElement& plugin_element,
const WebURL& url,
const WebString& suggested_mime_type) {
return false;
}
}; };
} // namespace blink } // namespace blink
......
...@@ -1114,6 +1114,14 @@ void LocalFrameClientImpl::FrameRectsChanged(const IntRect& frame_rect) { ...@@ -1114,6 +1114,14 @@ void LocalFrameClientImpl::FrameRectsChanged(const IntRect& frame_rect) {
web_frame_->Client()->FrameRectsChanged(frame_rect); web_frame_->Client()->FrameRectsChanged(frame_rect);
} }
bool LocalFrameClientImpl::IsPluginHandledExternally(
HTMLPlugInElement& plugin_element,
const KURL& resource_url,
const String& suggesed_mime_type) {
return web_frame_->Client()->IsPluginHandledExternally(
&plugin_element, resource_url, suggesed_mime_type);
}
std::unique_ptr<WebWorkerFetchContext> std::unique_ptr<WebWorkerFetchContext>
LocalFrameClientImpl::CreateWorkerFetchContext() { LocalFrameClientImpl::CreateWorkerFetchContext() {
DCHECK(web_frame_->Client()); DCHECK(web_frame_->Client());
......
...@@ -277,6 +277,10 @@ class LocalFrameClientImpl final : public LocalFrameClient { ...@@ -277,6 +277,10 @@ class LocalFrameClientImpl final : public LocalFrameClient {
void FrameRectsChanged(const IntRect&) override; void FrameRectsChanged(const IntRect&) override;
bool IsPluginHandledExternally(HTMLPlugInElement&,
const KURL&,
const String&) override;
std::unique_ptr<WebWorkerFetchContext> CreateWorkerFetchContext() override; std::unique_ptr<WebWorkerFetchContext> CreateWorkerFetchContext() override;
std::unique_ptr<WebContentSettingsClient> CreateWorkerContentSettingsClient() std::unique_ptr<WebContentSettingsClient> CreateWorkerContentSettingsClient()
override; override;
......
...@@ -418,6 +418,15 @@ class CORE_EXPORT LocalFrameClient : public FrameClient { ...@@ -418,6 +418,15 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void FrameRectsChanged(const IntRect&) {} virtual void FrameRectsChanged(const IntRect&) {}
// Returns true when the contents of plugin are handled externally. This means
// the plugin element will own a content frame but the frame is than used
// externally to load the required handelrs.
virtual bool IsPluginHandledExternally(HTMLPlugInElement&,
const KURL&,
const String&) {
return false;
};
// Returns a new WebWorkerFetchContext for a dedicated worker or worklet. // Returns a new WebWorkerFetchContext for a dedicated worker or worklet.
virtual std::unique_ptr<WebWorkerFetchContext> CreateWorkerFetchContext() { virtual std::unique_ptr<WebWorkerFetchContext> CreateWorkerFetchContext() {
return nullptr; return nullptr;
......
...@@ -69,6 +69,16 @@ enum PluginRequestObjectResult { ...@@ -69,6 +69,16 @@ enum PluginRequestObjectResult {
kPluginRequestObjectResultMax kPluginRequestObjectResultMax
}; };
String GetMIMETypeFromURL(const KURL& url) {
String filename = url.LastPathComponent();
int extension_pos = filename.ReverseFind('.');
if (extension_pos >= 0) {
String extension = filename.Substring(extension_pos + 1);
return MIMETypeRegistry::GetWellKnownMIMETypeForExtension(extension);
}
return String();
}
} // anonymous namespace } // anonymous namespace
const Vector<String>& PluginParameters::Names() const { const Vector<String>& PluginParameters::Names() const {
...@@ -148,6 +158,12 @@ void HTMLPlugInElement::SetFocused(bool focused, WebFocusType focus_type) { ...@@ -148,6 +158,12 @@ void HTMLPlugInElement::SetFocused(bool focused, WebFocusType focus_type) {
bool HTMLPlugInElement::RequestObjectInternal( bool HTMLPlugInElement::RequestObjectInternal(
const PluginParameters& plugin_params) { const PluginParameters& plugin_params) {
if (handled_externally_) {
// TODO(ekaramad): Fix this once we know what to do with frames inside
// plugins (https://crbug.com/776510).
return true;
}
if (url_.IsEmpty() && service_type_.IsEmpty()) if (url_.IsEmpty() && service_type_.IsEmpty())
return false; return false;
...@@ -159,9 +175,20 @@ bool HTMLPlugInElement::RequestObjectInternal( ...@@ -159,9 +175,20 @@ bool HTMLPlugInElement::RequestObjectInternal(
if (!AllowedToLoadObject(completed_url, service_type_)) if (!AllowedToLoadObject(completed_url, service_type_))
return false; return false;
handled_externally_ =
GetDocument().GetFrame()->Client()->IsPluginHandledExternally(
*this, completed_url,
service_type_.IsEmpty() ? GetMIMETypeFromURL(completed_url)
: service_type_);
if (handled_externally_) {
// This is a temporary placeholder and the logic around
// |handled_externally_| might change as MimeHandlerView is moving towards
// depending on OOPIFs instead of WebPlugin (https://crbug.com/659750).
completed_url = BlankURL();
}
ObjectContentType object_type = GetObjectContentType(); ObjectContentType object_type = GetObjectContentType();
if (object_type == ObjectContentType::kFrame || if (object_type == ObjectContentType::kFrame ||
object_type == ObjectContentType::kImage) { object_type == ObjectContentType::kImage || handled_externally_) {
// If the plugin element already contains a subframe, // If the plugin element already contains a subframe,
// loadOrRedirectSubframe will re-use it. Otherwise, it will create a // loadOrRedirectSubframe will re-use it. Otherwise, it will create a
// new frame and set it as the LayoutEmbeddedContent's EmbeddedContentView, // new frame and set it as the LayoutEmbeddedContent's EmbeddedContentView,
...@@ -489,13 +516,7 @@ HTMLPlugInElement::ObjectContentType HTMLPlugInElement::GetObjectContentType() ...@@ -489,13 +516,7 @@ HTMLPlugInElement::ObjectContentType HTMLPlugInElement::GetObjectContentType()
KURL url = GetDocument().CompleteURL(url_); KURL url = GetDocument().CompleteURL(url_);
if (mime_type.IsEmpty()) { if (mime_type.IsEmpty()) {
// Try to guess the MIME type based off the extension. // Try to guess the MIME type based off the extension.
String filename = url.LastPathComponent(); mime_type = GetMIMETypeFromURL(url);
int extension_pos = filename.ReverseFind('.');
if (extension_pos >= 0) {
String extension = filename.Substring(extension_pos + 1);
mime_type = MIMETypeRegistry::GetWellKnownMIMETypeForExtension(extension);
}
if (mime_type.IsEmpty()) if (mime_type.IsEmpty())
return ObjectContentType::kFrame; return ObjectContentType::kFrame;
} }
......
...@@ -224,6 +224,8 @@ class CORE_EXPORT HTMLPlugInElement ...@@ -224,6 +224,8 @@ class CORE_EXPORT HTMLPlugInElement
// off embedded_content_view_ here while the plugin is persisting but not // off embedded_content_view_ here while the plugin is persisting but not
// being displayed. // being displayed.
Member<WebPluginContainerImpl> persisted_plugin_; Member<WebPluginContainerImpl> persisted_plugin_;
bool handled_externally_ = false;
}; };
inline bool IsHTMLPlugInElement(const HTMLElement& element) { inline bool IsHTMLPlugInElement(const HTMLElement& element) {
......
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