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 {
CreateWebSocketHandshakeThrottle() {
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
......
......@@ -1114,6 +1114,14 @@ void LocalFrameClientImpl::FrameRectsChanged(const IntRect& 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>
LocalFrameClientImpl::CreateWorkerFetchContext() {
DCHECK(web_frame_->Client());
......
......@@ -277,6 +277,10 @@ class LocalFrameClientImpl final : public LocalFrameClient {
void FrameRectsChanged(const IntRect&) override;
bool IsPluginHandledExternally(HTMLPlugInElement&,
const KURL&,
const String&) override;
std::unique_ptr<WebWorkerFetchContext> CreateWorkerFetchContext() override;
std::unique_ptr<WebContentSettingsClient> CreateWorkerContentSettingsClient()
override;
......
......@@ -418,6 +418,15 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
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.
virtual std::unique_ptr<WebWorkerFetchContext> CreateWorkerFetchContext() {
return nullptr;
......
......@@ -69,6 +69,16 @@ enum PluginRequestObjectResult {
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
const Vector<String>& PluginParameters::Names() const {
......@@ -148,6 +158,12 @@ void HTMLPlugInElement::SetFocused(bool focused, WebFocusType focus_type) {
bool HTMLPlugInElement::RequestObjectInternal(
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())
return false;
......@@ -159,9 +175,20 @@ bool HTMLPlugInElement::RequestObjectInternal(
if (!AllowedToLoadObject(completed_url, service_type_))
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();
if (object_type == ObjectContentType::kFrame ||
object_type == ObjectContentType::kImage) {
object_type == ObjectContentType::kImage || handled_externally_) {
// If the plugin element already contains a subframe,
// loadOrRedirectSubframe will re-use it. Otherwise, it will create a
// new frame and set it as the LayoutEmbeddedContent's EmbeddedContentView,
......@@ -489,13 +516,7 @@ HTMLPlugInElement::ObjectContentType HTMLPlugInElement::GetObjectContentType()
KURL url = GetDocument().CompleteURL(url_);
if (mime_type.IsEmpty()) {
// Try to guess the MIME type based off the extension.
String filename = url.LastPathComponent();
int extension_pos = filename.ReverseFind('.');
if (extension_pos >= 0) {
String extension = filename.Substring(extension_pos + 1);
mime_type = MIMETypeRegistry::GetWellKnownMIMETypeForExtension(extension);
}
mime_type = GetMIMETypeFromURL(url);
if (mime_type.IsEmpty())
return ObjectContentType::kFrame;
}
......
......@@ -224,6 +224,8 @@ class CORE_EXPORT HTMLPlugInElement
// off embedded_content_view_ here while the plugin is persisting but not
// being displayed.
Member<WebPluginContainerImpl> persisted_plugin_;
bool handled_externally_ = false;
};
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