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/1101161
Reviewed-by: Ehsan Karamad <ekaramad@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Ehsan Karamad <ekaramad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#578554}
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 1ce3fc4..a5c8b8e 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -827,6 +827,15 @@
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
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
index 6bf62e2..f79cb23 100644
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -1114,6 +1114,14 @@
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());
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
index 14a451e9..e417ef7 100644
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -277,6 +277,10 @@
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;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index 7360a10..8f56be5 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -418,6 +418,15 @@
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;
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.cc b/third_party/blink/renderer/core/html/html_plugin_element.cc
index d849d69..47270324 100644
--- a/third_party/blink/renderer/core/html/html_plugin_element.cc
+++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -69,6 +69,16 @@
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 @@
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 @@
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 @@
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;
}
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.h b/third_party/blink/renderer/core/html/html_plugin_element.h
index 62e6624..7581470c 100644
--- a/third_party/blink/renderer/core/html/html_plugin_element.h
+++ b/third_party/blink/renderer/core/html/html_plugin_element.h
@@ -224,6 +224,8 @@
// 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) {