diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/printing/browser | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-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')
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_ |