summaryrefslogtreecommitdiff
path: root/chromium/components/printing/browser
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/printing/browser
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/printing/browser')
-rw-r--r--chromium/components/printing/browser/BUILD.gn1
-rw-r--r--chromium/components/printing/browser/OWNERS4
-rw-r--r--chromium/components/printing/browser/print_composite_client.cc165
-rw-r--r--chromium/components/printing/browser/print_composite_client.h61
-rw-r--r--chromium/components/printing/browser/print_manager_utils.cc5
-rw-r--r--chromium/components/printing/browser/service_sandbox_type.h28
6 files changed, 157 insertions, 107 deletions
diff --git a/chromium/components/printing/browser/BUILD.gn b/chromium/components/printing/browser/BUILD.gn
index e25da9dfe5d..1b3c83d06c8 100644
--- a/chromium/components/printing/browser/BUILD.gn
+++ b/chromium/components/printing/browser/BUILD.gn
@@ -40,6 +40,7 @@ static_library("browser") {
"print_manager_utils.h",
"printer_capabilities.cc",
"printer_capabilities.h",
+ "service_sandbox_type.h",
]
public_deps = [
diff --git a/chromium/components/printing/browser/OWNERS b/chromium/components/printing/browser/OWNERS
index b1b8445d4ef..ba1476bc785 100644
--- a/chromium/components/printing/browser/OWNERS
+++ b/chromium/components/printing/browser/OWNERS
@@ -1 +1,5 @@
# COMPONENT: Internals>Printing
+
+# Service sandbox specialization must be reviewed by SECURITY_OWNERS
+per-file service_sandbox_type.h=set noparent
+per-file service_sandbox_type.h=file://ipc/SECURITY_OWNERS \ No newline at end of file
diff --git a/chromium/components/printing/browser/print_composite_client.cc b/chromium/components/printing/browser/print_composite_client.cc
index ff32a589713..9915fd124dc 100644
--- a/chromium/components/printing/browser/print_composite_client.cc
+++ b/chromium/components/printing/browser/print_composite_client.cc
@@ -9,9 +9,9 @@
#include "base/bind.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/stl_util.h"
-#include "base/task/post_task.h"
#include "build/build_config.h"
#include "components/discardable_memory/service/discardable_shared_memory_manager.h"
+#include "components/printing/browser/service_sandbox_type.h"
#include "components/printing/common/print_messages.h"
#include "components/services/print_compositor/public/cpp/print_service_mojo_types.h"
#include "components/strings/grit/components_strings.h"
@@ -20,6 +20,7 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/service_process_host.h"
+#include "printing/common/metafile_utils.h"
#include "printing/printing_utils.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
@@ -79,40 +80,41 @@ PrintCompositeClient::~PrintCompositeClient() {}
bool PrintCompositeClient::OnMessageReceived(
const IPC::Message& message,
content::RenderFrameHost* render_frame_host) {
+#if BUILDFLAG(ENABLE_TAGGED_PDF)
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(PrintCompositeClient, message,
render_frame_host)
- IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintFrameContent,
- OnDidPrintFrameContent)
-#if BUILDFLAG(ENABLE_TAGGED_PDF)
IPC_MESSAGE_HANDLER(PrintHostMsg_AccessibilityTree, OnAccessibilityTree)
-#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
+#else
+ return false;
+#endif
}
void PrintCompositeClient::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
- uint64_t frame_guid = GenerateFrameGuid(render_frame_host);
- auto iter = pending_subframe_cookies_.find(frame_guid);
- if (iter != pending_subframe_cookies_.end()) {
- // When a subframe we are expecting is deleted, we should notify print
+ if (document_cookie_ == 0)
+ return;
+
+ auto iter = pending_subframes_.find(render_frame_host);
+ if (iter != pending_subframes_.end()) {
+ // When a subframe we are expecting is deleted, we should notify the print
// compositor service.
- for (int doc_cookie : iter->second) {
- auto* compositor = GetCompositeRequest(doc_cookie);
- compositor->NotifyUnavailableSubframe(frame_guid);
- }
- pending_subframe_cookies_.erase(iter);
+ auto* compositor = GetCompositeRequest(document_cookie_);
+ compositor->NotifyUnavailableSubframe(GenerateFrameGuid(render_frame_host));
+ pending_subframes_.erase(iter);
}
print_render_frames_.erase(render_frame_host);
}
void PrintCompositeClient::OnDidPrintFrameContent(
- content::RenderFrameHost* render_frame_host,
+ int render_process_id,
+ int render_frame_id,
int document_cookie,
- const PrintHostMsg_DidPrintContent_Params& params) {
+ mojom::DidPrintContentParamsPtr params) {
auto* outer_contents = web_contents()->GetOuterWebContents();
if (outer_contents) {
// When the printed content belongs to an extension or app page, the print
@@ -123,26 +125,31 @@ void PrintCompositeClient::OnDidPrintFrameContent(
// contents nested in multiple layers.
auto* outer_client = PrintCompositeClient::FromWebContents(outer_contents);
DCHECK(outer_client);
- outer_client->OnDidPrintFrameContent(render_frame_host, document_cookie,
- params);
+ outer_client->OnDidPrintFrameContent(render_process_id, render_frame_id,
+ document_cookie, std::move(params));
return;
}
+ if (document_cookie_ != document_cookie)
+ return;
+
+ auto* render_frame_host =
+ content::RenderFrameHost::FromID(render_process_id, render_frame_id);
+ if (!render_frame_host)
+ return;
+
// Content in |params| is sent from untrusted source; only minimal processing
// is done here. Most of it will be directly forwarded to print compositor
// service.
auto* compositor = GetCompositeRequest(document_cookie);
- auto region = params.metafile_data_region.Duplicate();
- uint64_t frame_guid = GenerateFrameGuid(render_frame_host);
+ auto region = params->metafile_data_region.Duplicate();
compositor->AddSubframeContent(
- frame_guid, std::move(region),
- ConvertContentInfoMap(render_frame_host, params.subframe_content_info));
+ GenerateFrameGuid(render_frame_host), std::move(region),
+ ConvertContentInfoMap(render_frame_host, params->subframe_content_info));
// Update our internal states about this frame.
- pending_subframe_cookies_[frame_guid].erase(document_cookie);
- if (pending_subframe_cookies_[frame_guid].empty())
- pending_subframe_cookies_.erase(frame_guid);
- printed_subframes_[document_cookie].insert(frame_guid);
+ pending_subframes_.erase(render_frame_host);
+ printed_subframes_.insert(render_frame_host);
}
#if BUILDFLAG(ENABLE_TAGGED_PDF)
@@ -159,38 +166,36 @@ void PrintCompositeClient::PrintCrossProcessSubframe(
int document_cookie,
content::RenderFrameHost* subframe_host) {
auto params = mojom::PrintFrameContentParams::New(rect, document_cookie);
- uint64_t frame_guid = GenerateFrameGuid(subframe_host);
if (!subframe_host->IsRenderFrameLive()) {
// When the subframe is dead, no need to send message,
// just notify the service.
auto* compositor = GetCompositeRequest(document_cookie);
- compositor->NotifyUnavailableSubframe(frame_guid);
+ compositor->NotifyUnavailableSubframe(GenerateFrameGuid(subframe_host));
return;
}
- auto subframe_iter = printed_subframes_.find(document_cookie);
- if (subframe_iter != printed_subframes_.end() &&
- base::Contains(subframe_iter->second, frame_guid)) {
- // If this frame is already printed, no need to print again.
- return;
- }
-
- auto cookie_iter = pending_subframe_cookies_.find(frame_guid);
- if (cookie_iter != pending_subframe_cookies_.end() &&
- base::Contains(cookie_iter->second, document_cookie)) {
- // If this frame is being printed, no need to print again.
+ // If this frame is already printed, no need to print again.
+ if (base::Contains(pending_subframes_, subframe_host) ||
+ base::Contains(printed_subframes_, subframe_host)) {
return;
}
// Send the request to the destination frame.
- GetPrintRenderFrame(subframe_host)->PrintFrameContent(std::move(params));
- pending_subframe_cookies_[frame_guid].insert(document_cookie);
+ int render_process_id = subframe_host->GetProcess()->GetID();
+ int render_frame_id = subframe_host->GetRoutingID();
+ GetPrintRenderFrame(subframe_host)
+ ->PrintFrameContent(
+ std::move(params),
+ base::BindOnce(&PrintCompositeClient::OnDidPrintFrameContent,
+ weak_ptr_factory_.GetWeakPtr(), render_process_id,
+ render_frame_id));
+ pending_subframes_.insert(subframe_host);
}
void PrintCompositeClient::DoCompositePageToPdf(
int document_cookie,
content::RenderFrameHost* render_frame_host,
- const PrintHostMsg_DidPrintContent_Params& content,
+ const mojom::DidPrintContentParams& content,
mojom::PrintCompositor::CompositePageToPdfCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -209,8 +214,8 @@ void PrintCompositeClient::DoPrepareForDocumentToPdf(
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!GetIsDocumentConcurrentlyComposited(document_cookie));
- is_doc_concurrently_composited_set_.insert(document_cookie);
- auto* compositor = GetCompositeRequest(document_cookie);
+ auto* compositor = CreateCompositeRequest(document_cookie);
+ is_doc_concurrently_composited_ = true;
compositor->PrepareForDocumentToPdf(
base::BindOnce(&PrintCompositeClient::OnDidPrepareForDocumentToPdf,
std::move(callback)));
@@ -238,12 +243,12 @@ void PrintCompositeClient::DoCompleteDocumentToPdf(
void PrintCompositeClient::DoCompositeDocumentToPdf(
int document_cookie,
content::RenderFrameHost* render_frame_host,
- const PrintHostMsg_DidPrintContent_Params& content,
+ const mojom::DidPrintContentParams& content,
mojom::PrintCompositor::CompositeDocumentToPdfCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!GetIsDocumentConcurrentlyComposited(document_cookie));
- auto* compositor = GetCompositeRequest(document_cookie);
+ auto* compositor = CreateCompositeRequest(document_cookie);
auto region = content.metafile_data_region.Duplicate();
// Since this class owns compositor, compositor will be gone when this class
@@ -271,9 +276,6 @@ void PrintCompositeClient::OnDidCompositeDocumentToPdf(
mojom::PrintCompositor::Status status,
base::ReadOnlySharedMemoryRegion region) {
RemoveCompositeRequest(document_cookie);
- // Clear all stored printed subframes.
- printed_subframes_.erase(document_cookie);
-
std::move(callback).Run(status, std::move(region));
}
@@ -290,54 +292,61 @@ void PrintCompositeClient::OnDidCompleteDocumentToPdf(
mojom::PrintCompositor::Status status,
base::ReadOnlySharedMemoryRegion region) {
RemoveCompositeRequest(document_cookie);
- // Clear all stored printed subframes.
- printed_subframes_.erase(document_cookie);
- // No longer concurrently compositing this document.
- is_doc_concurrently_composited_set_.erase(document_cookie);
std::move(callback).Run(status, std::move(region));
}
bool PrintCompositeClient::GetIsDocumentConcurrentlyComposited(
int cookie) const {
- return base::Contains(is_doc_concurrently_composited_set_, cookie);
+ return is_doc_concurrently_composited_ && document_cookie_ == cookie;
}
-mojom::PrintCompositor* PrintCompositeClient::GetCompositeRequest(int cookie) {
- auto iter = compositor_map_.find(cookie);
- if (iter != compositor_map_.end()) {
- DCHECK(iter->second.is_bound());
- return iter->second.get();
+mojom::PrintCompositor* PrintCompositeClient::CreateCompositeRequest(
+ int cookie) {
+ if (document_cookie_ != 0) {
+ DCHECK_NE(document_cookie_, cookie);
+ RemoveCompositeRequest(document_cookie_);
}
+ document_cookie_ = cookie;
- iter = compositor_map_.emplace(cookie, CreateCompositeRequest()).first;
- return iter->second.get();
-}
-
-void PrintCompositeClient::RemoveCompositeRequest(int cookie) {
- size_t erased = compositor_map_.erase(cookie);
- DCHECK_EQ(erased, 1u);
-}
-
-mojo::Remote<mojom::PrintCompositor>
-PrintCompositeClient::CreateCompositeRequest() {
- auto compositor = content::ServiceProcessHost::Launch<mojom::PrintCompositor>(
+ compositor_ = content::ServiceProcessHost::Launch<mojom::PrintCompositor>(
content::ServiceProcessHost::Options()
.WithDisplayName(IDS_PRINT_COMPOSITOR_SERVICE_DISPLAY_NAME)
- .WithSandboxType(service_manager::SandboxType::kPrintCompositor)
.Pass());
mojo::PendingRemote<discardable_memory::mojom::DiscardableSharedMemoryManager>
discardable_memory_manager;
- base::PostTask(
- FROM_HERE, {content::BrowserThread::IO},
+ content::GetIOThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(
&BindDiscardableSharedMemoryManagerOnIOThread,
discardable_memory_manager.InitWithNewPipeAndPassReceiver()));
- compositor->SetDiscardableSharedMemoryManager(
+ compositor_->SetDiscardableSharedMemoryManager(
std::move(discardable_memory_manager));
- compositor->SetWebContentsURL(web_contents()->GetLastCommittedURL());
- compositor->SetUserAgent(user_agent_);
- return compositor;
+ compositor_->SetWebContentsURL(web_contents()->GetLastCommittedURL());
+ compositor_->SetUserAgent(user_agent_);
+
+ return compositor_.get();
+}
+
+void PrintCompositeClient::RemoveCompositeRequest(int cookie) {
+ DCHECK_EQ(document_cookie_, cookie);
+ compositor_.reset();
+ document_cookie_ = 0;
+
+ // Clear all stored printed and pending subframes.
+ pending_subframes_.clear();
+ printed_subframes_.clear();
+
+ // No longer concurrently compositing this document.
+ is_doc_concurrently_composited_ = false;
+}
+
+mojom::PrintCompositor* PrintCompositeClient::GetCompositeRequest(
+ int cookie) const {
+ DCHECK_NE(0, document_cookie_);
+ DCHECK_EQ(document_cookie_, cookie);
+ DCHECK(compositor_.is_bound());
+ return compositor_.get();
}
const mojo::AssociatedRemote<mojom::PrintRenderFrame>&
diff --git a/chromium/components/printing/browser/print_composite_client.h b/chromium/components/printing/browser/print_composite_client.h
index 95d8376b01a..356af70f5df 100644
--- a/chromium/components/printing/browser/print_composite_client.h
+++ b/chromium/components/printing/browser/print_composite_client.h
@@ -9,6 +9,7 @@
#include <memory>
#include "base/containers/flat_set.h"
+#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "components/printing/common/print.mojom.h"
#include "components/services/print_compositor/public/mojom/print_compositor.mojom.h"
@@ -19,8 +20,6 @@
#include "printing/buildflags/buildflags.h"
#include "ui/accessibility/ax_tree_update_forward.h"
-struct PrintHostMsg_DidPrintContent_Params;
-
namespace printing {
// Class to manage print requests and their communication with print compositor
@@ -40,10 +39,6 @@ class PrintCompositeClient
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
// IPC message handler.
- void OnDidPrintFrameContent(
- content::RenderFrameHost* render_frame_host,
- int document_cookie,
- const PrintHostMsg_DidPrintContent_Params& params);
#if BUILDFLAG(ENABLE_TAGGED_PDF)
void OnAccessibilityTree(int document_cookie,
const ui::AXTreeUpdate& accessibility_tree);
@@ -62,7 +57,7 @@ class PrintCompositeClient
void DoCompositePageToPdf(
int cookie,
content::RenderFrameHost* render_frame_host,
- const PrintHostMsg_DidPrintContent_Params& content,
+ const mojom::DidPrintContentParams& content,
mojom::PrintCompositor::CompositePageToPdfCallback callback);
// Notifies compositor to collect individual pages into a document
@@ -84,7 +79,7 @@ class PrintCompositeClient
void DoCompositeDocumentToPdf(
int cookie,
content::RenderFrameHost* render_frame_host,
- const PrintHostMsg_DidPrintContent_Params& content,
+ const mojom::DidPrintContentParams& content,
mojom::PrintCompositor::CompositeDocumentToPdfCallback callback);
// Get the concurrent composition status for a document. Identifies if the
@@ -118,37 +113,47 @@ class PrintCompositeClient
mojom::PrintCompositor::Status status,
base::ReadOnlySharedMemoryRegion region);
- // Get the request or create a new one if none exists.
- // Since printed pages always share content with its document, they share the
- // same composite request.
- mojom::PrintCompositor* GetCompositeRequest(int cookie);
+ void OnDidPrintFrameContent(int render_process_id,
+ int render_frame_id,
+ int document_cookie,
+ mojom::DidPrintContentParamsPtr params);
- // Remove an existing request from |compositor_map_|.
+ // Creates a new composite request for a given document |cookie|. Since
+ // printed pages always share content with its document, they share the same
+ // composite request. Launches the compositor in a separate process.
+ // If a composite request already exists, it is removed.
+ // Returns the created composite request.
+ mojom::PrintCompositor* CreateCompositeRequest(int cookie);
+
+ // Remove the existing composite request.
void RemoveCompositeRequest(int cookie);
- mojo::Remote<mojom::PrintCompositor> CreateCompositeRequest();
+ // Get the composite request of a document. |cookie| must be valid and equal
+ // to |document_cookie_|.
+ mojom::PrintCompositor* GetCompositeRequest(int cookie) const;
// Helper method to fetch the PrintRenderFrame remote interface pointer
// associated with a given subframe.
const mojo::AssociatedRemote<mojom::PrintRenderFrame>& GetPrintRenderFrame(
content::RenderFrameHost* rfh);
- // Stores the mapping between document cookies and their corresponding
- // requests.
- std::map<int, mojo::Remote<mojom::PrintCompositor>> compositor_map_;
+ // Stores the message pipe endpoint for making remote calls to the compositor.
+ mojo::Remote<mojom::PrintCompositor> compositor_;
+
+ // Stores the unique sequential cookie of the document being composited.
+ // Holds 0 if no document is being composited.
+ int document_cookie_ = 0;
- // Stores the mapping between render frame's global unique id and document
- // cookies that requested such frame.
- std::map<uint64_t, base::flat_set<int>> pending_subframe_cookies_;
+ // Stores whether the document is concurrently compositing using individual
+ // pages, so that no separate composite request with full-document blob is
+ // required.
+ bool is_doc_concurrently_composited_ = false;
- // Stores the mapping between document cookie and all the printed subframes
- // for that document.
- std::map<int, base::flat_set<uint64_t>> printed_subframes_;
+ // Stores the pending subframes for the composited document.
+ base::flat_set<content::RenderFrameHost*> pending_subframes_;
- // Stores the set of cookies for documents that are doing concurrently
- // composition using individual pages, so that no separate composite request
- // with full-document blob is required.
- base::flat_set<int> is_doc_concurrently_composited_set_;
+ // Stores the printed subframes for the composited document.
+ base::flat_set<content::RenderFrameHost*> printed_subframes_;
std::string user_agent_;
@@ -159,6 +164,8 @@ class PrintCompositeClient
mojo::AssociatedRemote<mojom::PrintRenderFrame>>
print_render_frames_;
+ base::WeakPtrFactory<PrintCompositeClient> weak_ptr_factory_{this};
+
WEB_CONTENTS_USER_DATA_KEY_DECL();
DISALLOW_COPY_AND_ASSIGN(PrintCompositeClient);
diff --git a/chromium/components/printing/browser/print_manager_utils.cc b/chromium/components/printing/browser/print_manager_utils.cc
index 0d7c4f74679..3988fb6a309 100644
--- a/chromium/components/printing/browser/print_manager_utils.cc
+++ b/chromium/components/printing/browser/print_manager_utils.cc
@@ -7,6 +7,7 @@
#include "components/printing/browser/print_composite_client.h"
#include "components/printing/common/print_messages.h"
#include "content/public/browser/site_isolation_policy.h"
+#include "printing/mojom/print.mojom.h"
#include "printing/print_settings.h"
namespace printing {
@@ -68,8 +69,8 @@ void RenderParamsFromPrintSettings(const PrintSettings& settings,
params->title = settings.title();
params->url = settings.url();
params->printed_doc_type = IsOopifEnabled() && settings.is_modifiable()
- ? SkiaDocumentType::MSKP
- : SkiaDocumentType::PDF;
+ ? mojom::SkiaDocumentType::kMSKP
+ : mojom::SkiaDocumentType::kPDF;
params->pages_per_sheet = settings.pages_per_sheet();
}
diff --git a/chromium/components/printing/browser/service_sandbox_type.h b/chromium/components/printing/browser/service_sandbox_type.h
new file mode 100644
index 00000000000..bc7bb1f146c
--- /dev/null
+++ b/chromium/components/printing/browser/service_sandbox_type.h
@@ -0,0 +1,28 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PRINTING_BROWSER_SERVICE_SANDBOX_TYPE_H_
+#define COMPONENTS_PRINTING_BROWSER_SERVICE_SANDBOX_TYPE_H_
+
+#include "content/public/browser/sandbox_type.h"
+#include "content/public/browser/service_process_host.h"
+
+// This file maps service classes to sandbox types. Services which
+// require a non-utility sandbox can be added here. See
+// ServiceProcessHost::Launch() for how these templates are consumed.
+
+// printing::mojom::PrintCompositor
+namespace printing {
+namespace mojom {
+class PrintCompositor;
+}
+} // namespace printing
+
+template <>
+inline content::SandboxType
+content::GetServiceSandboxType<printing::mojom::PrintCompositor>() {
+ return content::SandboxType::kPrintCompositor;
+}
+
+#endif // COMPONENTS_PRINTING_BROWSER_SERVICE_SANDBOX_TYPE_H_