summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------src/3rdparty0
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/configure/BUILD.root.gn.in3
-rw-r--r--src/core/content_browser_client_qt.cpp44
-rw-r--r--src/core/content_browser_client_qt.h5
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.cpp24
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.h1
-rw-r--r--src/core/extensions/pdf_web_contents_helper_client_qt.h26
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp46
-rw-r--r--src/core/printing/pdf_stream_delegate_qt.cpp91
-rw-r--r--src/core/printing/pdf_stream_delegate_qt.h23
-rw-r--r--src/core/printing/pdf_web_contents_helper_client_qt.cpp56
-rw-r--r--src/core/printing/pdf_web_contents_helper_client_qt.h27
-rw-r--r--src/core/render_widget_host_view_qt.cpp2
-rw-r--r--src/core/render_widget_host_view_qt.h2
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp85
-rw-r--r--src/core/web_contents_adapter.cpp7
17 files changed, 396 insertions, 48 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject c575922203206b5cddb0fcfd492e0e0a4147c3c
+Subproject 8496e134077ac79bb185d7d0f0333cdddb27a67
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index a9c31f911..b8ee2b8e4 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -225,6 +225,8 @@ foreach(arch ${archs})
extend_gn_target(${buildGn} CONDITION QT_FEATURE_webengine_printing_and_pdf
SOURCES
printing/pdfium_document_wrapper_qt.cpp printing/pdfium_document_wrapper_qt.h
+ printing/pdf_web_contents_helper_client_qt.cpp printing/pdf_web_contents_helper_client_qt.h
+ printing/pdf_stream_delegate_qt.cpp printing/pdf_stream_delegate_qt.h
printing/print_view_manager_base_qt.cpp printing/print_view_manager_base_qt.h
printing/print_view_manager_qt.cpp printing/print_view_manager_qt.h
printing/printer_worker.cpp printing/printer_worker.h
diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
index 9a49d6465..24e8563eb 100644
--- a/src/core/configure/BUILD.root.gn.in
+++ b/src/core/configure/BUILD.root.gn.in
@@ -219,6 +219,7 @@ source_set("qtwebengine_sources") {
"//components/plugins/renderer/",
"//content/browser/resources/quota:resources",
"//extensions/buildflags:buildflags",
+ "//pdf:buildflags",
"//printing/buildflags:buildflags",
"//qtwebengine/common:mojo_bindings",
"//rlz/buildflags:buildflags",
@@ -339,9 +340,9 @@ source_set("qtwebengine_sources") {
if (enable_pdf) {
deps += [
"//pdf",
- "//pdf:buildflags",
"//chrome/browser/resources/pdf:resources",
"//components/pdf/browser",
+ "//components/pdf/browser:interceptors",
"//components/pdf/common",
"//components/pdf/renderer",
"//components/printing/browser",
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 973517404..fdca05760 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -27,6 +27,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
+#include "content/public/browser/url_loader_request_interceptor.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
#include "content/public/browser/web_ui_url_loader_factory.h"
@@ -35,6 +36,7 @@
#include "content/public/common/user_agent.h"
#include "extensions/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
+#include "pdf/buildflags.h"
#include "net/ssl/client_cert_identity.h"
#include "net/ssl/client_cert_store.h"
#include "net/ssl/ssl_private_key.h"
@@ -139,6 +141,14 @@
#include "printing/print_view_manager_qt.h"
#endif
+#if BUILDFLAG(ENABLE_PDF)
+#include "printing/pdf_stream_delegate_qt.h"
+
+#include "components/pdf/browser/pdf_navigation_throttle.h"
+#include "components/pdf/browser/pdf_url_loader_request_interceptor.h"
+#include "components/pdf/browser/pdf_web_contents_helper.h"
+#endif
+
#include <QGuiApplication>
#include <QStandardPaths>
#include <qpa/qplatformnativeinterface.h>
@@ -501,7 +511,14 @@ void ContentBrowserClientQt::RegisterAssociatedInterfaceBindersForRenderFrameHos
mojo::PendingAssociatedReceiver<autofill::mojom::AutofillDriver> receiver) {
autofill::ContentAutofillDriverFactory::BindAutofillDriver(std::move(receiver), render_frame_host);
}, &rfh));
-
+#if BUILDFLAG(ENABLE_PDF)
+ associated_registry.AddInterface(
+ base::BindRepeating(
+ [](content::RenderFrameHost *render_frame_host,
+ mojo::PendingAssociatedReceiver<pdf::mojom::PdfService> receiver) {
+ pdf::PDFWebContentsHelper::BindPdfService(std::move(receiver), render_frame_host);
+ }, &rfh));
+#endif // BUILDFLAG(ENABLE_PDF)
ContentBrowserClient::RegisterAssociatedInterfaceBindersForRenderFrameHost(rfh, associated_registry);
}
@@ -829,6 +846,9 @@ std::vector<std::unique_ptr<content::NavigationThrottle>> ContentBrowserClientQt
#if BUILDFLAG(ENABLE_EXTENSIONS)
MaybeAddThrottle(extensions::PDFIFrameNavigationThrottleQt::MaybeCreateThrottleFor(navigation_handle), &throttles);
#endif
+#if BUILDFLAG(ENABLE_PDF)
+ MaybeAddThrottle(pdf::PdfNavigationThrottle::MaybeCreateThrottleFor(navigation_handle, std::make_unique<PdfStreamDelegateQt>()), &throttles);
+#endif // BUILDFLAG(ENABLE_PDF)
return throttles;
}
@@ -1153,6 +1173,9 @@ base::flat_set<std::string> ContentBrowserClientQt::GetPluginMimeTypesWithExtern
}
}
#endif
+#if BUILDFLAG(ENABLE_PDF)
+ mime_types.insert("application/x-google-chrome-pdf");
+#endif
return mime_types;
}
@@ -1190,6 +1213,25 @@ bool ContentBrowserClientQt::WillCreateURLLoaderFactory(
return true;
}
+std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
+ContentBrowserClientQt::WillCreateURLLoaderRequestInterceptors(content::NavigationUIData* navigation_ui_data,
+ int frame_tree_node_id,
+ const scoped_refptr<network::SharedURLLoaderFactory>& network_loader_factory)
+{
+ std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>> interceptors;
+#if BUILDFLAG(ENABLE_PDF)
+ {
+ std::unique_ptr<content::URLLoaderRequestInterceptor> pdf_interceptor =
+ pdf::PdfURLLoaderRequestInterceptor::MaybeCreateInterceptor(
+ frame_tree_node_id, std::make_unique<PdfStreamDelegateQt>());
+ if (pdf_interceptor)
+ interceptors.push_back(std::move(pdf_interceptor));
+ }
+#endif
+
+ return interceptors;
+}
+
bool ContentBrowserClientQt::WillInterceptWebSocket(content::RenderFrameHost *frame)
{
Q_UNUSED(frame);
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index cba68b5d5..4ee5c0228 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -192,7 +192,10 @@ public:
bool HasErrorPage(int http_status_code, content::WebContents *contents) override;
bool HasCustomSchemeHandler(content::BrowserContext *browser_context,
const std::string &scheme) override;
-
+ std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
+ WillCreateURLLoaderRequestInterceptors(content::NavigationUIData *navigation_ui_data,
+ int frame_tree_node_id,
+ const scoped_refptr<network::SharedURLLoaderFactory> &network_loader_factory) override;
bool WillCreateURLLoaderFactory(content::BrowserContext *browser_context,
content::RenderFrameHost *frame,
int render_process_id,
diff --git a/src/core/extensions/extension_web_contents_observer_qt.cpp b/src/core/extensions/extension_web_contents_observer_qt.cpp
index 03f608227..22092be30 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.cpp
+++ b/src/core/extensions/extension_web_contents_observer_qt.cpp
@@ -7,9 +7,8 @@
#include "extension_web_contents_observer_qt.h"
-#include "components/guest_view/browser/guest_view_base.h"
+#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/child_process_security_policy.h"
-#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "extensions/browser/extension_registry.h"
@@ -43,6 +42,17 @@ void ExtensionWebContentsObserverQt::RenderFrameCreated(content::RenderFrameHost
{
ExtensionWebContentsObserver::RenderFrameCreated(render_frame_host);
+ if (web_contents()->IsInnerWebContentsForGuest() && static_cast<content::RenderFrameHostImpl *>(render_frame_host)->is_local_root_subframe()) {
+ content::WebContents *parent = web_contents()->GetOutermostWebContents();
+ QtWebEngineCore::RenderWidgetHostViewQt *main_rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent->GetRenderWidgetHostView());
+ // Main frame of guest WebContents
+ content::RenderWidgetHost *guest_render_widget_host = web_contents()->GetRenderViewHost()->GetWidget();
+ main_rwhv->addGuest(guest_render_widget_host);
+ // The frame which holds the actual PDF content inside the guest
+ content::RenderWidgetHost *pdf_render_widget_host = render_frame_host->GetRenderWidgetHost();
+ main_rwhv->addGuest(pdf_render_widget_host);
+ }
+
const Extension *extension = GetExtensionFromFrame(render_frame_host, false);
if (!extension)
return;
@@ -54,16 +64,6 @@ void ExtensionWebContentsObserverQt::RenderFrameCreated(content::RenderFrameHost
policy->GrantRequestOrigin(process_id, url::Origin::Create(GURL(blink::kChromeUIResourcesURL)));
}
-void ExtensionWebContentsObserverQt::RenderViewReady()
-{
- if (web_contents()->IsInnerWebContentsForGuest()) {
- content::RenderWidgetHost *render_widget_host = web_contents()->GetRenderViewHost()->GetWidget();
- content::WebContents *parent_web_contents = guest_view::GuestViewBase::GetTopLevelWebContents(web_contents());
- QtWebEngineCore::RenderWidgetHostViewQt *parent_rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent_web_contents->GetRenderWidgetHostView());
- parent_rwhv->setGuest(static_cast<content::RenderWidgetHostImpl *>(render_widget_host));
- }
-}
-
WEB_CONTENTS_USER_DATA_KEY_IMPL(ExtensionWebContentsObserverQt);
} // namespace extensions
diff --git a/src/core/extensions/extension_web_contents_observer_qt.h b/src/core/extensions/extension_web_contents_observer_qt.h
index 7af1ee96d..ff50b28e2 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.h
+++ b/src/core/extensions/extension_web_contents_observer_qt.h
@@ -25,7 +25,6 @@ public:
// content::WebContentsObserver overrides.
void RenderFrameCreated(content::RenderFrameHost *render_frame_host) override;
- void RenderViewReady() override;
private:
friend class content::WebContentsUserData<ExtensionWebContentsObserverQt>;
diff --git a/src/core/extensions/pdf_web_contents_helper_client_qt.h b/src/core/extensions/pdf_web_contents_helper_client_qt.h
deleted file mode 100644
index 3465f946c..000000000
--- a/src/core/extensions/pdf_web_contents_helper_client_qt.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H_
-#define PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H_
-
-#include "components/pdf/browser/pdf_web_contents_helper_client.h"
-
-namespace extensions {
-
-class PDFWebContentsHelperClientQt : public pdf::PDFWebContentsHelperClient
-{
-public:
- PDFWebContentsHelperClientQt();
- ~PDFWebContentsHelperClientQt() override;
-
-private:
- // pdf::PDFWebContentsHelperClient:
- void UpdateContentRestrictions(content::WebContents *contents, int content_restrictions) override;
- void OnPDFHasUnsupportedFeature(content::WebContents *contents) override;
- void OnSaveURL(content::WebContents *contents) override;
-};
-
-} // namespace extensions
-
-#endif // PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H_
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
index f6b961018..1bcb3ddea 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -30,6 +30,50 @@
#include <string>
#include <tuple>
+namespace {
+void ClearAllButFrameAncestors(network::mojom::URLResponseHead *response_head)
+{
+ response_head->headers->RemoveHeader("Content-Security-Policy");
+ response_head->headers->RemoveHeader("Content-Security-Policy-Report-Only");
+
+ if (!response_head->parsed_headers)
+ return;
+
+ std::vector<network::mojom::ContentSecurityPolicyPtr> &csp =
+ response_head->parsed_headers->content_security_policy;
+ std::vector<network::mojom::ContentSecurityPolicyPtr> cleared;
+
+ for (auto &policy : csp) {
+ auto frame_ancestors = policy->directives.find(network::mojom::CSPDirectiveName::FrameAncestors);
+ if (frame_ancestors == policy->directives.end())
+ continue;
+
+ auto cleared_policy = network::mojom::ContentSecurityPolicy::New();
+ cleared_policy->self_origin = std::move(policy->self_origin);
+ cleared_policy->header = std::move(policy->header);
+ cleared_policy->header->header_value = "";
+ cleared_policy->directives[network::mojom::CSPDirectiveName::FrameAncestors] = std::move(frame_ancestors->second);
+
+ auto raw_frame_ancestors = policy->raw_directives.find(network::mojom::CSPDirectiveName::FrameAncestors);
+ DCHECK(raw_frame_ancestors != policy->raw_directives.end());
+
+ cleared_policy->header->header_value = "frame-ancestors " + raw_frame_ancestors->second;
+ response_head->headers->AddHeader(
+ cleared_policy->header->type == network::mojom::ContentSecurityPolicyType::kEnforce
+ ? "Content-Security-Policy"
+ : "Content-Security-Policy-Report-Only",
+ cleared_policy->header->header_value);
+ cleared_policy->raw_directives[network::mojom::CSPDirectiveName::FrameAncestors] =
+ std::move(raw_frame_ancestors->second);
+
+ cleared.push_back(std::move(cleared_policy));
+ }
+
+ csp.swap(cleared);
+}
+} // namespace
+
+
namespace QtWebEngineCore {
PluginResponseInterceptorURLLoaderThrottle::PluginResponseInterceptorURLLoaderThrottle(
@@ -73,7 +117,7 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
// Content-Security-Policy, and does not currently respect the policy anyway.
// Ignore CSP served on a PDF response. https://crbug.com/271452
if (extension_id == extension_misc::kPdfExtensionId && response_head->headers)
- response_head->headers->RemoveHeader("Content-Security-Policy");
+ ClearAllButFrameAncestors(response_head);
MimeTypesHandler::ReportUsedHandler(extension_id);
diff --git a/src/core/printing/pdf_stream_delegate_qt.cpp b/src/core/printing/pdf_stream_delegate_qt.cpp
new file mode 100644
index 000000000..bb7b37532
--- /dev/null
+++ b/src/core/printing/pdf_stream_delegate_qt.cpp
@@ -0,0 +1,91 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/pdf/chrome_pdf_stream_delegate.cc:
+
+#include "pdf_stream_delegate_qt.h"
+
+#include "base/no_destructor.h"
+#include "chrome/grit/pdf_resources.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "extensions/common/constants.h"
+#include "ui/base/resource/resource_bundle.h"
+
+// Associates a `pdf::PdfStreamDelegate::StreamInfo` with a `WebContents`.
+// `PdfStreamDelegateQt::MapToOriginalUrl()` initializes this in
+// `PdfNavigationThrottle`, and then `PdfStreamDelegateQt::GetStreamInfo()`
+// returns the stashed result to `PdfURLLoaderRequestInterceptor`.
+class StreamInfoHelper : public content::WebContentsUserData<StreamInfoHelper>
+{
+public:
+ absl::optional<pdf::PdfStreamDelegate::StreamInfo> TakeStreamInfo()
+ { return std::move(stream_info_); }
+
+private:
+ friend class content::WebContentsUserData<StreamInfoHelper>;
+ WEB_CONTENTS_USER_DATA_KEY_DECL();
+
+ StreamInfoHelper(content::WebContents *contents,
+ pdf::PdfStreamDelegate::StreamInfo stream_info)
+ : content::WebContentsUserData<StreamInfoHelper>(*contents),
+ stream_info_(std::move(stream_info)) {}
+
+ absl::optional<pdf::PdfStreamDelegate::StreamInfo> stream_info_;
+};
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(StreamInfoHelper);
+
+PdfStreamDelegateQt::PdfStreamDelegateQt() = default;
+PdfStreamDelegateQt::~PdfStreamDelegateQt() = default;
+
+absl::optional<GURL> PdfStreamDelegateQt::MapToOriginalUrl(content::WebContents *contents, const GURL &stream_url)
+{
+ StreamInfoHelper *helper = StreamInfoHelper::FromWebContents(contents);
+ if (helper) {
+ // PDF viewer and Print Preview only do this once per WebContents.
+ return absl::nullopt;
+ }
+
+ GURL original_url;
+ StreamInfo info;
+
+ extensions::MimeHandlerViewGuest *guest =
+ extensions::MimeHandlerViewGuest::FromWebContents(contents);
+ if (guest) {
+ base::WeakPtr<extensions::StreamContainer> stream = guest->GetStreamWeakPtr();
+ if (!stream || stream->extension_id() != extension_misc::kPdfExtensionId ||
+ stream->stream_url() != stream_url ||
+ !stream->pdf_plugin_attributes()) {
+ return absl::nullopt;
+ }
+
+ original_url = stream->original_url();
+ info.background_color = base::checked_cast<SkColor>(stream->pdf_plugin_attributes()->background_color);
+ info.full_frame = !stream->embedded();
+ info.allow_javascript = stream->pdf_plugin_attributes()->allow_javascript;
+ } else {
+ return absl::nullopt;
+ }
+
+ static const base::NoDestructor<std::string> injected_script(
+ ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
+ IDR_PDF_PDF_INTERNAL_PLUGIN_WRAPPER_ROLLUP_JS));
+
+ info.stream_url = stream_url;
+ info.original_url = original_url;
+ info.injected_script = injected_script.get();
+ StreamInfoHelper::CreateForWebContents(contents, std::move(info));
+ return original_url;
+}
+
+absl::optional<pdf::PdfStreamDelegate::StreamInfo>
+PdfStreamDelegateQt::GetStreamInfo(content::WebContents *contents)
+{
+ StreamInfoHelper *helper = StreamInfoHelper::FromWebContents(contents);
+ if (!helper)
+ return absl::nullopt;
+
+ // Only the call immediately following `MapToOriginalUrl()` requires a valid
+ // `StreamInfo`; subsequent calls should just get nothing.
+ return helper->TakeStreamInfo();
+}
diff --git a/src/core/printing/pdf_stream_delegate_qt.h b/src/core/printing/pdf_stream_delegate_qt.h
new file mode 100644
index 000000000..47621576f
--- /dev/null
+++ b/src/core/printing/pdf_stream_delegate_qt.h
@@ -0,0 +1,23 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PDF_STREAM_DELEGATE_QT_H
+#define PDF_STREAM_DELEGATE_QT_H
+
+#include "components/pdf/browser/pdf_stream_delegate.h"
+
+// based on chrome/browser/pdf/chrome_pdf_stream_delegate.h:
+class PdfStreamDelegateQt : public pdf::PdfStreamDelegate
+{
+public:
+ PdfStreamDelegateQt();
+ PdfStreamDelegateQt(const PdfStreamDelegateQt &) = delete;
+ PdfStreamDelegateQt operator=(const PdfStreamDelegateQt &) = delete;
+ ~PdfStreamDelegateQt() override;
+
+ // pdf::PdfStreamDelegate:
+ absl::optional<GURL> MapToOriginalUrl(content::WebContents *contents, const GURL &stream_url) override;
+ absl::optional<StreamInfo> GetStreamInfo(content::WebContents *contents) override;
+};
+
+#endif // PDF_STREAM_DELEGATE_QT_H
diff --git a/src/core/printing/pdf_web_contents_helper_client_qt.cpp b/src/core/printing/pdf_web_contents_helper_client_qt.cpp
new file mode 100644
index 000000000..7c2a46ebf
--- /dev/null
+++ b/src/core/printing/pdf_web_contents_helper_client_qt.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.cc:
+
+#include "pdf_web_contents_helper_client_qt.h"
+
+#include "content/public/browser/render_process_host.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "extensions/common/constants.h"
+
+namespace {
+bool IsPdfExtensionOrigin(const url::Origin &origin)
+{
+ return origin.scheme() == extensions::kExtensionScheme &&
+ origin.host() == extension_misc::kPdfExtensionId;
+}
+
+// from chrome/browser/pdf/pdf_frame_util.cc:
+content::RenderFrameHost *FindPdfChildFrame(content::RenderFrameHost *rfh)
+{
+ if (!IsPdfExtensionOrigin(rfh->GetLastCommittedOrigin()))
+ return nullptr;
+
+ content::RenderFrameHost *pdf_rfh = nullptr;
+ rfh->ForEachRenderFrameHost(
+ base::BindRepeating(
+ [](content::RenderFrameHost *&pdf_rfh, content::RenderFrameHost *rfh) {
+ if (!rfh->GetProcess()->IsPdf())
+ return;
+
+ DCHECK(IsPdfExtensionOrigin(rfh->GetParent()->GetLastCommittedOrigin()));
+ DCHECK(!pdf_rfh);
+ pdf_rfh = rfh;
+ }, std::ref(pdf_rfh)));
+
+ return pdf_rfh;
+}
+} // namespace
+
+PDFWebContentsHelperClientQt::PDFWebContentsHelperClientQt() = default;
+PDFWebContentsHelperClientQt::~PDFWebContentsHelperClientQt() = default;
+
+content::RenderFrameHost *PDFWebContentsHelperClientQt::FindPdfFrame(content::WebContents *contents)
+{
+ content::RenderFrameHost *main_frame = contents->GetMainFrame();
+ content::RenderFrameHost *pdf_frame = FindPdfChildFrame(main_frame);
+ return pdf_frame ? pdf_frame : main_frame;
+}
+
+void PDFWebContentsHelperClientQt::SetPluginCanSave(content::WebContents *contents, bool can_save)
+{
+ auto *guest_view = extensions::MimeHandlerViewGuest::FromWebContents(contents);
+ if (guest_view)
+ guest_view->SetPluginCanSave(can_save);
+}
diff --git a/src/core/printing/pdf_web_contents_helper_client_qt.h b/src/core/printing/pdf_web_contents_helper_client_qt.h
new file mode 100644
index 000000000..ccc552986
--- /dev/null
+++ b/src/core/printing/pdf_web_contents_helper_client_qt.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H
+#define PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H
+
+#include "components/pdf/browser/pdf_web_contents_helper_client.h"
+
+// based on chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h:
+class PDFWebContentsHelperClientQt : public pdf::PDFWebContentsHelperClient
+{
+public:
+ PDFWebContentsHelperClientQt();
+ PDFWebContentsHelperClientQt(const PDFWebContentsHelperClientQt&) = delete;
+ PDFWebContentsHelperClientQt& operator=(const PDFWebContentsHelperClientQt&) = delete;
+ ~PDFWebContentsHelperClientQt() override;
+
+private:
+ // pdf::PDFWebContentsHelperClient:
+ content::RenderFrameHost* FindPdfFrame(content::WebContents *contents) override;
+ void UpdateContentRestrictions(content::WebContents *contents, int content_restrictions) override {}
+ void OnPDFHasUnsupportedFeature(content::WebContents *contents) override {}
+ void OnSaveURL(content::WebContents *contents) override {}
+ void SetPluginCanSave(content::WebContents *contents, bool can_save) override;
+};
+
+#endif // PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 3c47fed35..2de141bba 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -234,7 +234,7 @@ void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterC
m_adapterClient = nullptr; });
}
-void RenderWidgetHostViewQt::setGuest(content::RenderWidgetHostImpl *rwh)
+void RenderWidgetHostViewQt::addGuest(content::RenderWidgetHost *rwh)
{
rwh->AddInputEventObserver(m_guestInputEventObserver.get());
}
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 75b0515f0..a7c7009f1 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -54,7 +54,7 @@ public:
WebContentsAdapterClient *adapterClient() { return m_adapterClient; }
void setAdapterClient(WebContentsAdapterClient *adapterClient);
RenderWidgetHostViewQtDelegateClient *delegateClient() const { return m_delegateClient.get(); }
- void setGuest(content::RenderWidgetHostImpl *);
+ void addGuest(content::RenderWidgetHost *);
void InitAsChild(gfx::NativeView) override;
void InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect&, const gfx::Rect&) override;
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 9bcbc4a9a..5544b08df 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -45,6 +45,8 @@
#include "ui/base/webui/jstemplate_builder.h"
#if QT_CONFIG(webengine_printing_and_pdf)
+#include "components/pdf/renderer/internal_plugin_renderer_helpers.h"
+#include "components/pdf/renderer/pdf_internal_plugin_delegate.h"
#include "renderer/print_web_view_helper_delegate_qt.h"
#endif
@@ -58,6 +60,7 @@
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "common/extensions/extensions_client_qt.h"
+#include "extensions/common/constants.h"
#include "extensions/extensions_renderer_client_qt.h"
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
@@ -309,6 +312,66 @@ std::unique_ptr<blink::WebPrescientNetworking> ContentRendererClientQt::CreatePr
return std::make_unique<network_hints::WebPrescientNetworkingImpl>(render_frame);
}
+namespace {
+bool IsPdfExtensionOrigin(const url::Origin &origin)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ return origin.scheme() == extensions::kExtensionScheme &&
+ origin.host() == extension_misc::kPdfExtensionId;
+#else
+ return false;
+#endif
+}
+
+#if BUILDFLAG(ENABLE_PLUGINS)
+void AppendParams(const std::vector<content::WebPluginMimeType::Param> &additional_params,
+ blink::WebVector<blink::WebString> *existing_names,
+ blink::WebVector<blink::WebString> *existing_values)
+{
+ DCHECK(existing_names->size() == existing_values->size());
+ size_t existing_size = existing_names->size();
+ size_t total_size = existing_size + additional_params.size();
+
+ blink::WebVector<blink::WebString> names(total_size);
+ blink::WebVector<blink::WebString> values(total_size);
+
+ for (size_t i = 0; i < existing_size; ++i) {
+ names[i] = (*existing_names)[i];
+ values[i] = (*existing_values)[i];
+ }
+
+ for (size_t i = 0; i < additional_params.size(); ++i) {
+ names[existing_size + i] = blink::WebString::FromUTF16(additional_params[i].name);
+ values[existing_size + i] = blink::WebString::FromUTF16(additional_params[i].value);
+ }
+
+ existing_names->Swap(names);
+ existing_values->Swap(values);
+}
+#endif // BUILDFLAG(ENABLE_PLUGINS)
+
+#if QT_CONFIG(webengine_printing_and_pdf)
+// based on chrome/renderer/pdf/chrome_pdf_internal_plugin_delegate.cc:
+class PdfInternalPluginDelegateQt final
+ : public pdf::PdfInternalPluginDelegate
+{
+public:
+ PdfInternalPluginDelegateQt() = default;
+ PdfInternalPluginDelegateQt(const PdfInternalPluginDelegateQt &) = delete;
+ PdfInternalPluginDelegateQt& operator=(const PdfInternalPluginDelegateQt &) = delete;
+ ~PdfInternalPluginDelegateQt() override = default;
+
+ // `pdf::PdfInternalPluginDelegate`:
+ bool IsAllowedOrigin(const url::Origin &origin) const override;
+};
+
+bool PdfInternalPluginDelegateQt::IsAllowedOrigin(const url::Origin &origin) const
+{
+ return IsPdfExtensionOrigin(origin);
+}
+#endif
+} // namespace
+
bool ContentRendererClientQt::IsPluginHandledExternally(content::RenderFrame *render_frame,
const blink::WebElement &plugin_element,
const GURL &original_url,
@@ -323,6 +386,8 @@ bool ContentRendererClientQt::IsPluginHandledExternally(content::RenderFrame *re
original_url, original_mime_type, &found, &plugin_info, &mime_type);
if (!found)
return false;
+ if (IsPdfExtensionOrigin(render_frame->GetWebFrame()->GetSecurityOrigin()))
+ return true;
return extensions::MimeHandlerViewContainerManager::Get(
content::RenderFrame::FromWebFrame(
plugin_element.GetDocument().GetFrame()),
@@ -349,10 +414,24 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
static_cast<content::RenderFrameImpl *>(render_frame)->GetPepperHost()->GetPluginInfo(
params.url, params.mime_type.Utf8(), &found, &info, &mime_type);
- if (!found)
+ if (!found) {
*plugin = LoadablePluginPlaceholderQt::CreateLoadableMissingPlugin(render_frame, params)->plugin();
- else
- *plugin = render_frame->CreatePlugin(info, params);
+ return true;
+ }
+ if (info.name == u"Chromium PDF Viewer") {
+ blink::WebPluginParams new_params(params);
+ for (const auto& mime_type : info.mime_types) {
+ if (mime_type.mime_type == params.mime_type.Utf8()) {
+ AppendParams(mime_type.additional_params, &new_params.attribute_names,
+ &new_params.attribute_values);
+ break;
+ }
+ }
+
+ *plugin = pdf::CreateInternalPlugin(std::move(new_params), render_frame, std::make_unique<PdfInternalPluginDelegateQt>());
+ return true;
+ }
+ *plugin = render_frame->CreatePlugin(info, params);
#endif // BUILDFLAG(ENABLE_PLUGINS)
return true;
}
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 1f17d0398..7dc96967f 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -61,6 +61,8 @@
#include "qtwebengine/browser/qtwebenginepage.mojom.h"
#if QT_CONFIG(webengine_printing_and_pdf)
+#include "components/pdf/browser/pdf_web_contents_helper.h"
+#include "printing/pdf_web_contents_helper_client_qt.h"
#include "printing/print_view_manager_qt.h"
#endif
@@ -487,6 +489,11 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
webContents(), AutofillClientQt::FromWebContents(webContents()),
/* app_locale = */ "", autofill::AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER);
+#if QT_CONFIG(webengine_printing_and_pdf)
+ pdf::PDFWebContentsHelper::CreateForWebContentsWithClient(
+ webContents(), std::make_unique<PDFWebContentsHelperClientQt>());
+#endif
+
// Create an instance of WebEngineVisitedLinksManager to catch the first
// content::NOTIFICATION_RENDERER_PROCESS_CREATED event. This event will
// force to initialize visited links in VisitedLinkSlave.