From 82322968a374fe5a87a2adf6b07651242f75778d Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 9 Nov 2018 09:12:34 +0530 Subject: [PATCH] refactor: printing implementation (#15143) * refactor: basic printing * move build files to chromium_src/BUILD.gn * remove dependency on chrome prerender sources * spec: move printing specs behind feature flag * build: register pdf compositor service --- BUILD.gn | 64 +- atom/browser/api/atom_api_web_contents.cc | 106 +- atom/browser/api/atom_api_web_contents.h | 23 +- atom/browser/atom_browser_client.cc | 10 +- .../atom_print_preview_message_handler.cc | 134 --- .../atom_print_preview_message_handler.h | 52 - atom/browser/browser_process_impl.cc | 13 +- atom/browser/browser_process_impl.h | 3 + atom/browser/common_web_contents_delegate.cc | 6 +- .../printing/print_preview_message_handler.cc | 197 ++++ .../printing/print_preview_message_handler.h | 74 ++ atom/common/api/features.cc | 6 + .../print_render_frame_helper_delegate.cc | 37 + .../print_render_frame_helper_delegate.h | 31 + atom/renderer/renderer_client_base.cc | 4 +- atom/utility/atom_content_utility_client.cc | 8 + chromium_src/BUILD.gn | 39 + electron_strings.grdp | 5 + lib/browser/api/web-contents.js | 24 +- ...tron_content_browser_manifest_overlay.json | 3 +- patches/common/chromium/printing.patch | 919 ++++-------------- spec/api-browser-window-spec.js | 37 - spec/api-web-contents-spec.js | 58 ++ 23 files changed, 780 insertions(+), 1073 deletions(-) delete mode 100644 atom/browser/atom_print_preview_message_handler.cc delete mode 100644 atom/browser/atom_print_preview_message_handler.h create mode 100644 atom/browser/printing/print_preview_message_handler.cc create mode 100644 atom/browser/printing/print_preview_message_handler.h create mode 100644 atom/renderer/printing/print_render_frame_helper_delegate.cc create mode 100644 atom/renderer/printing/print_render_frame_helper_delegate.h diff --git a/BUILD.gn b/BUILD.gn index 6a1ccf144273..9002d25188c3 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -209,7 +209,6 @@ static_library("electron_lib") { "//base:base_static", "//base:i18n", "//chrome/app/resources:platform_locale_settings", - "//chrome/common", "//components/certificate_transparency", "//components/net_log", "//components/network_session_configurator/common", @@ -433,62 +432,12 @@ static_library("electron_lib") { } if (enable_basic_printing) { - deps += [ - "//chrome/common:mojo_bindings", - "//chrome/services/printing:lib", - "//components/printing/browser", - "//components/printing/common", - "//components/printing/renderer", - "//components/services/pdf_compositor/public/cpp:utils", - "//components/services/pdf_compositor/public/interfaces", - "//printing", - ] - sources += [ - "//chrome/browser/printing/print_job.cc", - "//chrome/browser/printing/print_job.h", - "//chrome/browser/printing/print_job_manager.cc", - "//chrome/browser/printing/print_job_manager.h", - "//chrome/browser/printing/print_job_worker.cc", - "//chrome/browser/printing/print_job_worker.h", - "//chrome/browser/printing/print_preview_message_handler.cc", - "//chrome/browser/printing/print_preview_message_handler.h", - "//chrome/browser/printing/print_view_manager_base.cc", - "//chrome/browser/printing/print_view_manager_base.h", - "//chrome/browser/printing/print_view_manager_basic.cc", - "//chrome/browser/printing/print_view_manager_basic.h", - "//chrome/browser/printing/print_view_manager_common.cc", - "//chrome/browser/printing/print_view_manager_common.h", - "//chrome/browser/printing/printer_manager_dialog.h", - "//chrome/browser/printing/printer_manager_dialog_linux.cc", - "//chrome/browser/printing/printer_manager_dialog_mac.mm", - "//chrome/browser/printing/printer_manager_dialog_win.cc", - "//chrome/browser/printing/printer_query.cc", - "//chrome/browser/printing/printer_query.h", - "//chrome/browser/printing/printing_message_filter.cc", - "//chrome/browser/printing/printing_message_filter.h", - "//chrome/renderer/prerender/prerender_dispatcher.cc", - "//chrome/renderer/prerender/prerender_dispatcher.h", - "//chrome/renderer/prerender/prerender_extra_data.cc", - "//chrome/renderer/prerender/prerender_extra_data.h", - "//chrome/renderer/prerender/prerender_helper.cc", - "//chrome/renderer/prerender/prerender_helper.h", - "//chrome/renderer/prerender/prerenderer_client.cc", - "//chrome/renderer/prerender/prerenderer_client.h", - "//chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc", - "//chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h", - "//electron/atom/browser/atom_print_preview_message_handler.cc", - "//electron/atom/browser/atom_print_preview_message_handler.h", + "atom/browser/printing/print_preview_message_handler.cc", + "atom/browser/printing/print_preview_message_handler.h", + "atom/renderer/printing/print_render_frame_helper_delegate.cc", + "atom/renderer/printing/print_render_frame_helper_delegate.h", ] - - if (is_win) { - sources += [ - "//chrome/browser/printing/pdf_to_emf_converter.cc", - "//chrome/browser/printing/pdf_to_emf_converter.h", - "//chrome/utility/printing_handler.cc", - "//chrome/utility/printing_handler.h", - ] - } } if (enable_pepper_flash) { @@ -939,7 +888,10 @@ service_manifest("electron_content_packaged_services_manifest_overlay") { packaged_services = [ "//services/proxy_resolver:proxy_resolver_manifest" ] if (enable_basic_printing) { - packaged_services += [ "//chrome/services/printing:manifest" ] + packaged_services += [ + "//chrome/services/printing:manifest", + "//components/services/pdf_compositor:pdf_compositor_manifest", + ] } } diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 4f1fe3046f35..24d8c0569aff 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -80,7 +80,6 @@ #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/url_request/url_request_context.h" -#include "printing/buildflags/buildflags.h" #include "third_party/blink/public/platform/web_input_event.h" #include "third_party/blink/public/web/web_find_options.h" #include "ui/display/screen.h" @@ -102,39 +101,15 @@ #endif #if BUILDFLAG(ENABLE_PRINTING) -#include "atom/browser/atom_print_preview_message_handler.h" #include "chrome/browser/printing/print_view_manager_basic.h" +#include "components/printing/common/print_messages.h" #endif #include "atom/common/node_includes.h" -namespace { - -struct PrintSettings { - bool silent; - bool print_background; - base::string16 device_name; -}; - -} // namespace - namespace mate { -template <> -struct Converter { - static bool FromV8(v8::Isolate* isolate, - v8::Local val, - PrintSettings* out) { - mate::Dictionary dict; - if (!ConvertFromV8(isolate, val, &dict)) - return false; - dict.Get("silent", &(out->silent)); - dict.Get("printBackground", &(out->print_background)); - dict.Get("deviceName", &(out->device_name)); - return true; - } -}; - +#if BUILDFLAG(ENABLE_PRINTING) template <> struct Converter { static v8::Local ToV8(v8::Isolate* isolate, @@ -148,6 +123,7 @@ struct Converter { return dict.GetHandle(); } }; +#endif template <> struct Converter { @@ -1482,50 +1458,58 @@ bool WebContents::IsCurrentlyAudible() { return web_contents()->IsCurrentlyAudible(); } -void WebContents::Print(mate::Arguments* args) { #if BUILDFLAG(ENABLE_PRINTING) - PrintSettings settings = {false, false, base::string16()}; - if (args->Length() >= 1 && !args->GetNext(&settings)) { - args->ThrowError(); +void WebContents::Print(mate::Arguments* args) { + bool silent, print_background = false; + base::string16 device_name; + mate::Dictionary options = mate::Dictionary::CreateEmpty(args->isolate()); + base::DictionaryValue settings; + if (args->Length() >= 1 && !args->GetNext(&options)) { + args->ThrowError("Invalid print settings specified"); return; } - auto* print_view_manager_basic_ptr = - printing::PrintViewManagerBasic::FromWebContents(web_contents()); - if (args->Length() == 2) { - base::Callback callback; - if (!args->GetNext(&callback)) { - args->ThrowError(); - return; - } - print_view_manager_basic_ptr->SetCallback(callback); + printing::CompletionCallback callback; + if (args->Length() == 2 && !args->GetNext(&callback)) { + args->ThrowError("Invalid optional callback provided"); + return; } - print_view_manager_basic_ptr->PrintNow( - web_contents()->GetMainFrame(), settings.silent, - settings.print_background, settings.device_name); -#else - LOG(ERROR) << "Printing is disabled"; -#endif + options.Get("silent", &silent); + options.Get("printBackground", &print_background); + if (options.Get("deviceName", &device_name) && !device_name.empty()) { + settings.SetString(printing::kSettingDeviceName, device_name); + } + auto* print_view_manager = + printing::PrintViewManagerBasic::FromWebContents(web_contents()); + auto* focused_frame = web_contents()->GetFocusedFrame(); + auto* rfh = focused_frame && focused_frame->HasSelection() + ? focused_frame + : web_contents()->GetMainFrame(); + print_view_manager->PrintNow( + rfh, + std::make_unique(rfh->GetRoutingID(), silent, + print_background, settings), + std::move(callback)); } std::vector WebContents::GetPrinterList() { std::vector printers; - -#if BUILDFLAG(ENABLE_PRINTING) auto print_backend = printing::PrintBackend::CreateInstance(nullptr); - base::ThreadRestrictions::ScopedAllowIO allow_io; - print_backend->EnumeratePrinters(&printers); -#endif - + { + // TODO(deepak1556): Deprecate this api in favor of an + // async version and post a non blocing task call. + base::ThreadRestrictions::ScopedAllowIO allow_io; + print_backend->EnumeratePrinters(&printers); + } return printers; } -void WebContents::PrintToPDF(const base::DictionaryValue& setting, - const PrintToPDFCallback& callback) { -#if BUILDFLAG(ENABLE_PRINTING) - AtomPrintPreviewMessageHandler::FromWebContents(web_contents()) - ->PrintToPDF(setting, callback); -#endif +void WebContents::PrintToPDF( + const base::DictionaryValue& settings, + const PrintPreviewMessageHandler::PrintToPDFCallback& callback) { + PrintPreviewMessageHandler::FromWebContents(web_contents()) + ->PrintToPDF(settings, callback); } +#endif void WebContents::AddWorkSpace(mate::Arguments* args, const base::FilePath& path) { @@ -2144,9 +2128,11 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("unregisterServiceWorker", &WebContents::UnregisterServiceWorker) .SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker) - .SetMethod("print", &WebContents::Print) - .SetMethod("getPrinters", &WebContents::GetPrinterList) +#if BUILDFLAG(ENABLE_PRINTING) + .SetMethod("_print", &WebContents::Print) + .SetMethod("_getPrinters", &WebContents::GetPrinterList) .SetMethod("_printToPDF", &WebContents::PrintToPDF) +#endif .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetMethod("showDefinitionForSelection", diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 984fc747d778..837ca5bbba87 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -22,9 +22,14 @@ #include "content/public/common/favicon_url.h" #include "electron/buildflags/buildflags.h" #include "native_mate/handle.h" -#include "printing/backend/print_backend.h" +#include "printing/buildflags/buildflags.h" #include "ui/gfx/image/image.h" +#if BUILDFLAG(ENABLE_PRINTING) +#include "atom/browser/printing/print_preview_message_handler.h" +#include "printing/backend/print_backend.h" +#endif + namespace blink { struct WebDeviceEmulationParams; } @@ -75,10 +80,6 @@ class WebContents : public mate::TrackableObject, OFF_SCREEN, // Used for offscreen rendering }; - // For node.js callback function type: function(error, buffer) - using PrintToPDFCallback = - base::Callback, v8::Local)>; - // Create a new WebContents and return the V8 wrapper of it. static mate::Handle Create(v8::Isolate* isolate, const mate::Dictionary& options); @@ -162,15 +163,18 @@ class WebContents : public mate::TrackableObject, void SetAudioMuted(bool muted); bool IsAudioMuted(); bool IsCurrentlyAudible(); - void Print(mate::Arguments* args); - std::vector GetPrinterList(); void SetEmbedder(const WebContents* embedder); void SetDevToolsWebContents(const WebContents* devtools); v8::Local GetNativeView() const; +#if BUILDFLAG(ENABLE_PRINTING) + void Print(mate::Arguments* args); + std::vector GetPrinterList(); // Print current page as PDF. - void PrintToPDF(const base::DictionaryValue& setting, - const PrintToPDFCallback& callback); + void PrintToPDF( + const base::DictionaryValue& settings, + const PrintPreviewMessageHandler::PrintToPDFCallback& callback); +#endif // DevTools workspace api. void AddWorkSpace(mate::Arguments* args, const base::FilePath& path); @@ -498,7 +502,6 @@ class WebContents : public mate::TrackableObject, std::unique_ptr dialog_manager_; std::unique_ptr guest_delegate_; - std::unique_ptr frame_subscriber_; // The host webcontents that may contain this webcontents. diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 30774955141b..319414fde4bd 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -45,7 +45,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/printing/printing_message_filter.h" #include "components/net_log/chrome_net_log.h" #include "content/public/browser/browser_ppapi_host.h" #include "content/public/browser/client_certificate_delegate.h" @@ -96,7 +95,9 @@ #endif // BUILDFLAG(ENABLE_TTS) #if BUILDFLAG(ENABLE_PRINTING) +#include "chrome/browser/printing/printing_message_filter.h" #include "chrome/services/printing/public/mojom/constants.mojom.h" +#include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h" #endif // BUILDFLAG(ENABLE_PRINTING) using content::BrowserThread; @@ -256,7 +257,8 @@ void AtomBrowserClient::RenderProcessWillLaunch( return; #if BUILDFLAG(ENABLE_PRINTING) - host->AddFilter(new printing::PrintingMessageFilter(process_id)); + host->AddFilter(new printing::PrintingMessageFilter( + process_id, host->GetBrowserContext())); #endif #if BUILDFLAG(ENABLE_TTS) @@ -592,6 +594,10 @@ void AtomBrowserClient::RegisterOutOfProcessServices( IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME); #if BUILDFLAG(ENABLE_PRINTING) + (*services)[printing::mojom::kServiceName] = + base::BindRepeating(&l10n_util::GetStringUTF16, + IDS_UTILITY_PROCESS_PDF_COMPOSITOR_SERVICE_NAME); + (*services)[printing::mojom::kChromePrintingServiceName] = base::BindRepeating(&l10n_util::GetStringUTF16, IDS_UTILITY_PROCESS_PRINTING_SERVICE_NAME); diff --git a/atom/browser/atom_print_preview_message_handler.cc b/atom/browser/atom_print_preview_message_handler.cc deleted file mode 100644 index b97df98814b5..000000000000 --- a/atom/browser/atom_print_preview_message_handler.cc +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2012 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. - -#include "atom/browser/atom_print_preview_message_handler.h" - -#include - -#include -#include -#include - -#include "base/bind.h" -#include "base/memory/ref_counted.h" -#include "base/memory/ref_counted_memory.h" -#include "base/memory/shared_memory.h" -#include "base/memory/shared_memory_handle.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/printing/print_job_manager.h" -#include "chrome/browser/printing/print_preview_dialog_controller.h" -#include "chrome/browser/printing/print_view_manager.h" -#include "chrome/browser/printing/printer_query.h" -#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h" -#include "components/printing/browser/print_composite_client.h" -#include "components/printing/browser/print_manager_utils.h" -#include "components/printing/common/print_messages.h" -#include "components/services/pdf_compositor/public/cpp/pdf_service_mojo_types.h" -#include "components/services/pdf_compositor/public/cpp/pdf_service_mojo_utils.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "printing/page_size_margins.h" -#include "printing/print_job_constants.h" -#include "printing/print_settings.h" - -#include "atom/common/node_includes.h" - -using content::BrowserThread; -using content::WebContents; - -DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::AtomPrintPreviewMessageHandler); - -namespace atom { - -namespace { - -char* CopyPDFDataOnIOThread( - const PrintHostMsg_DidPreviewDocument_Params& params) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - const PrintHostMsg_DidPrintContent_Params& content = params.content; - std::unique_ptr shared_buf( - new base::SharedMemory(content.metafile_data_handle, true)); - if (!shared_buf->Map(content.data_size)) - return nullptr; - char* pdf_data = new char[content.data_size]; - memcpy(pdf_data, shared_buf->memory(), content.data_size); - return pdf_data; -} - -void FreeNodeBufferData(char* data, void* hint) { - delete[] data; -} - -} // namespace - -AtomPrintPreviewMessageHandler::AtomPrintPreviewMessageHandler( - WebContents* web_contents) - : printing::PrintPreviewMessageHandler(web_contents), - weak_ptr_factory_(this) { - DCHECK(web_contents); -} - -AtomPrintPreviewMessageHandler::~AtomPrintPreviewMessageHandler() {} - -void AtomPrintPreviewMessageHandler::OnMetafileReadyForPrinting( - content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPreviewDocument_Params& params, - const PrintHostMsg_PreviewIds& ids) { - printing::PrintPreviewMessageHandler::OnMetafileReadyForPrinting( - render_frame_host, params, ids); - - BrowserThread::PostTaskAndReplyWithResult( - BrowserThread::IO, FROM_HERE, base::Bind(&CopyPDFDataOnIOThread, params), - base::Bind(&AtomPrintPreviewMessageHandler::RunPrintToPDFCallback, - base::Unretained(this), ids.request_id, - params.content.data_size)); -} - -void AtomPrintPreviewMessageHandler::OnPrintPreviewFailed( - int document_cookie, - const PrintHostMsg_PreviewIds& ids) { - printing::PrintPreviewMessageHandler::OnPrintPreviewFailed(document_cookie, - ids); - - RunPrintToPDFCallback(ids.request_id, 0, nullptr); -} - -void AtomPrintPreviewMessageHandler::PrintToPDF( - const base::DictionaryValue& options, - const PrintToPDFCallback& callback) { - int request_id; - options.GetInteger(printing::kPreviewRequestID, &request_id); - print_to_pdf_callback_map_[request_id] = callback; - - content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); - rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options)); -} - -void AtomPrintPreviewMessageHandler::RunPrintToPDFCallback(int request_id, - uint32_t data_size, - char* data) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - v8::Locker locker(isolate); - v8::HandleScope handle_scope(isolate); - if (data) { - v8::Local buffer = - node::Buffer::New(isolate, data, static_cast(data_size), - &FreeNodeBufferData, nullptr) - .ToLocalChecked(); - print_to_pdf_callback_map_[request_id].Run(v8::Null(isolate), buffer); - } else { - v8::Local error_message = - v8::String::NewFromUtf8(isolate, "Failed to generate PDF"); - print_to_pdf_callback_map_[request_id].Run( - v8::Exception::Error(error_message), v8::Null(isolate)); - } - print_to_pdf_callback_map_.erase(request_id); -} - -} // namespace atom diff --git a/atom/browser/atom_print_preview_message_handler.h b/atom/browser/atom_print_preview_message_handler.h deleted file mode 100644 index 49c1bf318ea8..000000000000 --- a/atom/browser/atom_print_preview_message_handler.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2012 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 ATOM_BROWSER_ATOM_PRINT_PREVIEW_MESSAGE_HANDLER_H_ -#define ATOM_BROWSER_ATOM_PRINT_PREVIEW_MESSAGE_HANDLER_H_ - -#include - -#include "base/memory/weak_ptr.h" -#include "chrome/browser/printing/print_preview_message_handler.h" -#include "content/public/browser/web_contents_user_data.h" -#include "v8/include/v8.h" - -namespace atom { - -// Manages the print preview handling for a WebContents. -class AtomPrintPreviewMessageHandler - : public printing::PrintPreviewMessageHandler, - public content::WebContentsUserData { - public: - ~AtomPrintPreviewMessageHandler() override; - - using PrintToPDFCallback = - base::Callback, v8::Local)>; - - void PrintToPDF(const base::DictionaryValue& options, - const PrintToPDFCallback& callback); - - private: - explicit AtomPrintPreviewMessageHandler(content::WebContents* web_contents); - friend class content::WebContentsUserData; - typedef std::map PrintToPDFCallbackMap; - - void OnMetafileReadyForPrinting( - content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPreviewDocument_Params& params, - const PrintHostMsg_PreviewIds& ids) override; - void OnPrintPreviewFailed(int document_cookie, - const PrintHostMsg_PreviewIds& ids) override; - void RunPrintToPDFCallback(int request_id, uint32_t data_size, char* data); - - PrintToPDFCallbackMap print_to_pdf_callback_map_; - - base::WeakPtrFactory weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(AtomPrintPreviewMessageHandler); -}; - -} // namespace atom - -#endif // ATOM_BROWSER_ATOM_PRINT_PREVIEW_MESSAGE_HANDLER_H_ diff --git a/atom/browser/browser_process_impl.cc b/atom/browser/browser_process_impl.cc index 061b4faed7e0..842f32bf6a4d 100644 --- a/atom/browser/browser_process_impl.cc +++ b/atom/browser/browser_process_impl.cc @@ -4,14 +4,13 @@ #include "atom/browser/browser_process_impl.h" -#include "chrome/browser/printing/print_job_manager.h" -#include "printing/buildflags/buildflags.h" #include "ui/base/l10n/l10n_util.h" -BrowserProcessImpl::BrowserProcessImpl() : print_job_manager_(nullptr) { #if BUILDFLAG(ENABLE_PRINTING) - print_job_manager_.reset(new printing::PrintJobManager()); +#include "chrome/browser/printing/print_job_manager.h" #endif + +BrowserProcessImpl::BrowserProcessImpl() { g_browser_process = this; } @@ -216,5 +215,11 @@ const std::string& BrowserProcessImpl::GetApplicationLocale() { } printing::PrintJobManager* BrowserProcessImpl::print_job_manager() { +#if BUILDFLAG(ENABLE_PRINTING) + if (!print_job_manager_) + print_job_manager_.reset(new printing::PrintJobManager()); return print_job_manager_.get(); +#else + return nullptr; +#endif } diff --git a/atom/browser/browser_process_impl.h b/atom/browser/browser_process_impl.h index e91788ffc325..266922b0f33d 100644 --- a/atom/browser/browser_process_impl.h +++ b/atom/browser/browser_process_impl.h @@ -15,6 +15,7 @@ #include "base/macros.h" #include "chrome/browser/browser_process.h" +#include "printing/buildflags/buildflags.h" #include "services/network/public/cpp/shared_url_loader_factory.h" namespace printing { @@ -98,7 +99,9 @@ class BrowserProcessImpl : public BrowserProcess { printing::PrintJobManager* print_job_manager() override; private: +#if BUILDFLAG(ENABLE_PRINTING) std::unique_ptr print_job_manager_; +#endif std::string locale_; DISALLOW_COPY_AND_ASSIGN(BrowserProcessImpl); diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index 03eca1585041..4eeb009f91a4 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -44,8 +44,9 @@ #endif #if BUILDFLAG(ENABLE_PRINTING) -#include "atom/browser/atom_print_preview_message_handler.h" +#include "atom/browser/printing/print_preview_message_handler.h" #include "chrome/browser/printing/print_view_manager_basic.h" +#include "components/printing/browser/print_manager_utils.h" #endif using content::BrowserThread; @@ -178,8 +179,9 @@ void CommonWebContentsDelegate::InitWithWebContents( web_contents->SetDelegate(this); #if BUILDFLAG(ENABLE_PRINTING) + PrintPreviewMessageHandler::CreateForWebContents(web_contents); printing::PrintViewManagerBasic::CreateForWebContents(web_contents); - AtomPrintPreviewMessageHandler::CreateForWebContents(web_contents); + printing::CreateCompositeClientIfNeeded(web_contents); #endif // Determien whether the WebContents is offscreen. diff --git a/atom/browser/printing/print_preview_message_handler.cc b/atom/browser/printing/print_preview_message_handler.cc new file mode 100644 index 000000000000..0c4b74ce3f97 --- /dev/null +++ b/atom/browser/printing/print_preview_message_handler.cc @@ -0,0 +1,197 @@ +// Copyright (c) 2018 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/printing/print_preview_message_handler.h" + +#include +#include + +#include "base/bind.h" +#include "base/memory/read_only_shared_memory_region.h" +#include "base/memory/ref_counted.h" +#include "base/memory/ref_counted_memory.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/printing/print_job_manager.h" +#include "chrome/browser/printing/printer_query.h" +#include "components/printing/browser/print_composite_client.h" +#include "components/printing/browser/print_manager_utils.h" +#include "components/printing/common/print_messages.h" +#include "components/services/pdf_compositor/public/cpp/pdf_service_mojo_types.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" + +#include "atom/common/node_includes.h" + +using content::BrowserThread; + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::PrintPreviewMessageHandler); + +namespace atom { + +namespace { + +void StopWorker(int document_cookie) { + if (document_cookie <= 0) + return; + scoped_refptr queue = + g_browser_process->print_job_manager()->queue(); + scoped_refptr printer_query = + queue->PopPrinterQuery(document_cookie); + if (printer_query.get()) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&printing::PrinterQuery::StopWorker, printer_query)); + } +} + +scoped_refptr GetDataFromHandle( + base::SharedMemoryHandle handle, + uint32_t data_size) { + auto shared_buf = std::make_unique(handle, true); + if (!shared_buf->Map(data_size)) { + return nullptr; + } + + return base::MakeRefCounted( + std::move(shared_buf), data_size); +} + +} // namespace + +PrintPreviewMessageHandler::PrintPreviewMessageHandler( + content::WebContents* web_contents) + : content::WebContentsObserver(web_contents), weak_ptr_factory_(this) { + DCHECK(web_contents); +} + +PrintPreviewMessageHandler::~PrintPreviewMessageHandler() = default; + +bool PrintPreviewMessageHandler::OnMessageReceived( + const IPC::Message& message, + content::RenderFrameHost* render_frame_host) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(PrintPreviewMessageHandler, message, + render_frame_host) + IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting, + OnMetafileReadyForPrinting) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + if (handled) + return true; + + handled = true; + IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message) + IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed, OnPrintPreviewFailed) + IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewCancelled, + OnPrintPreviewCancelled) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void PrintPreviewMessageHandler::OnMetafileReadyForPrinting( + content::RenderFrameHost* render_frame_host, + const PrintHostMsg_DidPreviewDocument_Params& params, + const PrintHostMsg_PreviewIds& ids) { + // Always try to stop the worker. + StopWorker(params.document_cookie); + + const PrintHostMsg_DidPrintContent_Params& content = params.content; + if (!content.metafile_data_handle.IsValid() || + params.expected_pages_count <= 0) { + RunPrintToPDFCallback(ids.request_id, nullptr); + return; + } + + if (printing::IsOopifEnabled()) { + auto* client = + printing::PrintCompositeClient::FromWebContents(web_contents()); + DCHECK(client); + client->DoCompositeDocumentToPdf( + params.document_cookie, render_frame_host, content.metafile_data_handle, + content.data_size, content.subframe_content_info, + base::BindOnce(&PrintPreviewMessageHandler::OnCompositePdfDocumentDone, + weak_ptr_factory_.GetWeakPtr(), + params.expected_pages_count, ids)); + } else { + RunPrintToPDFCallback( + ids.request_id, + GetDataFromHandle(content.metafile_data_handle, content.data_size)); + } +} + +void PrintPreviewMessageHandler::OnCompositePdfDocumentDone( + int page_number, + const PrintHostMsg_PreviewIds& ids, + printing::mojom::PdfCompositor::Status status, + base::ReadOnlySharedMemoryRegion region) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (status != printing::mojom::PdfCompositor::Status::SUCCESS) { + DLOG(ERROR) << "Compositing pdf failed with error " << status; + RunPrintToPDFCallback(ids.request_id, nullptr); + return; + } + + RunPrintToPDFCallback( + ids.request_id, + base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region)); +} + +void PrintPreviewMessageHandler::OnPrintPreviewFailed( + int document_cookie, + const PrintHostMsg_PreviewIds& ids) { + StopWorker(document_cookie); + + RunPrintToPDFCallback(ids.request_id, nullptr); +} + +void PrintPreviewMessageHandler::OnPrintPreviewCancelled( + int document_cookie, + const PrintHostMsg_PreviewIds& ids) { + StopWorker(document_cookie); + + RunPrintToPDFCallback(ids.request_id, nullptr); +} + +void PrintPreviewMessageHandler::PrintToPDF( + const base::DictionaryValue& options, + const PrintToPDFCallback& callback) { + int request_id; + options.GetInteger(printing::kPreviewRequestID, &request_id); + print_to_pdf_callback_map_[request_id] = callback; + + auto* focused_frame = web_contents()->GetFocusedFrame(); + auto* rfh = focused_frame && focused_frame->HasSelection() + ? focused_frame + : web_contents()->GetMainFrame(); + rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options)); +} + +void PrintPreviewMessageHandler::RunPrintToPDFCallback( + int request_id, + scoped_refptr data_bytes) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + if (data_bytes && data_bytes->size()) { + v8::Local buffer = + node::Buffer::Copy(isolate, + reinterpret_cast(data_bytes->front()), + data_bytes->size()) + .ToLocalChecked(); + print_to_pdf_callback_map_[request_id].Run(v8::Null(isolate), buffer); + } else { + v8::Local error_message = + v8::String::NewFromUtf8(isolate, "Failed to generate PDF"); + print_to_pdf_callback_map_[request_id].Run( + v8::Exception::Error(error_message), v8::Null(isolate)); + } + print_to_pdf_callback_map_.erase(request_id); +} + +} // namespace atom diff --git a/atom/browser/printing/print_preview_message_handler.h b/atom/browser/printing/print_preview_message_handler.h new file mode 100644 index 000000000000..9470e9ea45fe --- /dev/null +++ b/atom/browser/printing/print_preview_message_handler.h @@ -0,0 +1,74 @@ +// Copyright (c) 2018 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_ +#define ATOM_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_ + +#include + +#include "base/memory/ref_counted_memory.h" +#include "base/memory/weak_ptr.h" +#include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" +#include "v8/include/v8.h" + +struct PrintHostMsg_DidPreviewDocument_Params; +struct PrintHostMsg_PreviewIds; + +namespace content { +class RenderFrameHost; +} + +namespace atom { + +// Manages the print preview handling for a WebContents. +class PrintPreviewMessageHandler + : public content::WebContentsObserver, + public content::WebContentsUserData { + public: + using PrintToPDFCallback = + base::Callback, v8::Local)>; + + ~PrintPreviewMessageHandler() override; + + void PrintToPDF(const base::DictionaryValue& options, + const PrintToPDFCallback& callback); + + protected: + // content::WebContentsObserver implementation. + bool OnMessageReceived(const IPC::Message& message, + content::RenderFrameHost* render_frame_host) override; + + private: + friend class content::WebContentsUserData; + + explicit PrintPreviewMessageHandler(content::WebContents* web_contents); + + void OnMetafileReadyForPrinting( + content::RenderFrameHost* render_frame_host, + const PrintHostMsg_DidPreviewDocument_Params& params, + const PrintHostMsg_PreviewIds& ids); + void OnCompositePdfDocumentDone(int page_number, + const PrintHostMsg_PreviewIds& ids, + printing::mojom::PdfCompositor::Status status, + base::ReadOnlySharedMemoryRegion region); + void OnPrintPreviewFailed(int document_cookie, + const PrintHostMsg_PreviewIds& ids); + void OnPrintPreviewCancelled(int document_cookie, + const PrintHostMsg_PreviewIds& ids); + void RunPrintToPDFCallback(int request_id, + scoped_refptr data_bytes); + + using PrintToPDFCallbackMap = std::map; + PrintToPDFCallbackMap print_to_pdf_callback_map_; + + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PrintPreviewMessageHandler); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_ diff --git a/atom/common/api/features.cc b/atom/common/api/features.cc index d9d041f994f8..fb1ce4d0926d 100644 --- a/atom/common/api/features.cc +++ b/atom/common/api/features.cc @@ -4,6 +4,7 @@ #include "electron/buildflags/buildflags.h" #include "native_mate/dictionary.h" +#include "printing/buildflags/buildflags.h" // clang-format off #include "atom/common/node_includes.h" // NOLINT(build/include_alpha) // clang-format on @@ -34,6 +35,10 @@ bool IsTtsEnabled() { return BUILDFLAG(ENABLE_TTS); } +bool IsPrintingEnabled() { + return BUILDFLAG(ENABLE_PRINTING); +} + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, @@ -46,6 +51,7 @@ void Initialize(v8::Local exports, &IsFakeLocationProviderEnabled); dict.SetMethod("isViewApiEnabled", &IsViewApiEnabled); dict.SetMethod("isTtsEnabled", &IsTtsEnabled); + dict.SetMethod("isPrintingEnabled", &IsPrintingEnabled); } } // namespace diff --git a/atom/renderer/printing/print_render_frame_helper_delegate.cc b/atom/renderer/printing/print_render_frame_helper_delegate.cc new file mode 100644 index 000000000000..0a3bf8321bbf --- /dev/null +++ b/atom/renderer/printing/print_render_frame_helper_delegate.cc @@ -0,0 +1,37 @@ +// Copyright (c) 2018 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/renderer/printing/print_render_frame_helper_delegate.h" + +#include "content/public/renderer/render_frame.h" +#include "third_party/blink/public/web/web_element.h" +#include "third_party/blink/public/web/web_local_frame.h" + +namespace atom { + +PrintRenderFrameHelperDelegate::PrintRenderFrameHelperDelegate() = default; + +PrintRenderFrameHelperDelegate::~PrintRenderFrameHelperDelegate() = default; + +bool PrintRenderFrameHelperDelegate::CancelPrerender( + content::RenderFrame* render_frame) { + return false; +} + +// Return the PDF object element if |frame| is the out of process PDF extension. +blink::WebElement PrintRenderFrameHelperDelegate::GetPdfElement( + blink::WebLocalFrame* frame) { + return blink::WebElement(); +} + +bool PrintRenderFrameHelperDelegate::IsPrintPreviewEnabled() { + return false; +} + +bool PrintRenderFrameHelperDelegate::OverridePrint( + blink::WebLocalFrame* frame) { + return false; +} + +} // namespace atom diff --git a/atom/renderer/printing/print_render_frame_helper_delegate.h b/atom/renderer/printing/print_render_frame_helper_delegate.h new file mode 100644 index 000000000000..1888ab1564dd --- /dev/null +++ b/atom/renderer/printing/print_render_frame_helper_delegate.h @@ -0,0 +1,31 @@ +// Copyright (c) 2018 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_RENDERER_PRINTING_PRINT_RENDER_FRAME_HELPER_DELEGATE_H_ +#define ATOM_RENDERER_PRINTING_PRINT_RENDER_FRAME_HELPER_DELEGATE_H_ + +#include "base/macros.h" +#include "components/printing/renderer/print_render_frame_helper.h" + +namespace atom { + +class PrintRenderFrameHelperDelegate + : public printing::PrintRenderFrameHelper::Delegate { + public: + PrintRenderFrameHelperDelegate(); + ~PrintRenderFrameHelperDelegate() override; + + private: + // printing::PrintRenderFrameHelper::Delegate: + bool CancelPrerender(content::RenderFrame* render_frame) override; + blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override; + bool IsPrintPreviewEnabled() override; + bool OverridePrint(blink::WebLocalFrame* frame) override; + + DISALLOW_COPY_AND_ASSIGN(PrintRenderFrameHelperDelegate); +}; + +} // namespace atom + +#endif // ATOM_RENDERER_PRINTING_PRINT_RENDER_FRAME_HELPER_DELEGATE_H_ diff --git a/atom/renderer/renderer_client_base.cc b/atom/renderer/renderer_client_base.cc index eb35f78349d1..1e581703fd30 100644 --- a/atom/renderer/renderer_client_base.cc +++ b/atom/renderer/renderer_client_base.cc @@ -55,7 +55,7 @@ #endif // BUILDFLAG(ENABLE_TTS) #if BUILDFLAG(ENABLE_PRINTING) -#include "chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h" +#include "atom/renderer/printing/print_render_frame_helper_delegate.h" #include "components/printing/renderer/print_render_frame_helper.h" #endif // BUILDFLAG(ENABLE_PRINTING) @@ -192,7 +192,7 @@ void RendererClientBase::RenderFrameCreated( new ContentSettingsObserver(render_frame); #if BUILDFLAG(ENABLE_PRINTING) new printing::PrintRenderFrameHelper( - render_frame, std::make_unique()); + render_frame, std::make_unique()); #endif #if BUILDFLAG(ENABLE_PDF_VIEWER) diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc index fe54d0f41549..ed9781a90461 100644 --- a/atom/utility/atom_content_utility_client.cc +++ b/atom/utility/atom_content_utility_client.cc @@ -4,6 +4,7 @@ #include "atom/utility/atom_content_utility_client.h" +#include #include #include "base/command_line.h" @@ -17,6 +18,8 @@ #if BUILDFLAG(ENABLE_PRINTING) #include "chrome/services/printing/printing_service.h" #include "chrome/services/printing/public/mojom/constants.mojom.h" +#include "components/services/pdf_compositor/public/cpp/pdf_compositor_service_factory.h" +#include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h" #if defined(OS_WIN) #include "chrome/services/printing/pdf_to_emf_converter_factory.h" @@ -92,6 +95,11 @@ void AtomContentUtilityClient::RegisterServices(StaticServiceMap* services) { proxy_resolver_info); #if BUILDFLAG(ENABLE_PRINTING) + service_manager::EmbeddedServiceInfo pdf_compositor_info; + pdf_compositor_info.factory = + base::BindRepeating(&printing::CreatePdfCompositorService, std::string()); + services->emplace(printing::mojom::kServiceName, pdf_compositor_info); + service_manager::EmbeddedServiceInfo printing_info; printing_info.factory = base::BindRepeating(&printing::PrintingService::CreateService); diff --git a/chromium_src/BUILD.gn b/chromium_src/BUILD.gn index ea69a4490d94..93929067777c 100644 --- a/chromium_src/BUILD.gn +++ b/chromium_src/BUILD.gn @@ -4,6 +4,7 @@ import("//build/config/ui.gni") import("//electron/buildflags/buildflags.gni") +import("//printing/buildflags/buildflags.gni") import("//third_party/widevine/cdm/widevine.gni") # Builds some of the chrome sources that Electron depends on. @@ -139,4 +140,42 @@ static_library("chrome") { ] deps += [ "//components/cdm/renderer" ] } + + if (enable_basic_printing) { + sources += [ + "//chrome/browser/printing/print_job.cc", + "//chrome/browser/printing/print_job.h", + "//chrome/browser/printing/print_job_manager.cc", + "//chrome/browser/printing/print_job_manager.h", + "//chrome/browser/printing/print_job_worker.cc", + "//chrome/browser/printing/print_job_worker.h", + "//chrome/browser/printing/print_view_manager_base.cc", + "//chrome/browser/printing/print_view_manager_base.h", + "//chrome/browser/printing/print_view_manager_basic.cc", + "//chrome/browser/printing/print_view_manager_basic.h", + "//chrome/browser/printing/printer_query.cc", + "//chrome/browser/printing/printer_query.h", + "//chrome/browser/printing/printing_message_filter.cc", + "//chrome/browser/printing/printing_message_filter.h", + ] + deps += [ + "//chrome/services/printing:lib", + "//components/printing/browser", + "//components/printing/common", + "//components/printing/renderer", + "//components/services/pdf_compositor", + "//components/services/pdf_compositor/public/cpp:factory", + "//components/services/pdf_compositor/public/interfaces", + "//printing", + ] + + if (is_win) { + sources += [ + "//chrome/browser/printing/pdf_to_emf_converter.cc", + "//chrome/browser/printing/pdf_to_emf_converter.h", + "//chrome/utility/printing_handler.cc", + "//chrome/utility/printing_handler.h", + ] + } + } } diff --git a/electron_strings.grdp b/electron_strings.grdp index b1216ac63544..3bde892dc2a3 100644 --- a/electron_strings.grdp +++ b/electron_strings.grdp @@ -5,6 +5,11 @@ V8 Proxy Resolver + + + PDF Compositor Service + + Printing Service diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index 51ff1685ccd9..1fdb177cb4f8 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -1,5 +1,6 @@ 'use strict' +const features = process.atomBinding('features') const { EventEmitter } = require('events') const electron = require('electron') const path = require('path') @@ -70,6 +71,7 @@ const defaultPrintingSetting = { marginsType: 0, isFirstRequest: false, requestID: getNextId(), + previewUIID: 0, previewModifiable: true, printToPDF: true, printWithCloudPrint: false, @@ -251,7 +253,27 @@ WebContents.prototype.printToPDF = function (options, callback) { // Chromium expects this in a 0-100 range number, not as float printingSetting.scaleFactor *= 100 - this._printToPDF(printingSetting, callback) + if (features.isPrintingEnabled()) { + this._printToPDF(printingSetting, callback) + } else { + console.error('Error: Printing feature is disabled.') + } +} + +WebContents.prototype.print = function (...args) { + if (features.isPrintingEnabled()) { + this._print(args) + } else { + console.error('Error: Printing feature is disabled.') + } +} + +WebContents.prototype.getPrinters = function () { + if (features.isPrintingEnabled()) { + return this._getPrinters() + } else { + console.error('Error: Printing feature is disabled.') + } } WebContents.prototype.getZoomLevel = function (callback) { diff --git a/manifests/electron_content_browser_manifest_overlay.json b/manifests/electron_content_browser_manifest_overlay.json index 7b3f7bed9a16..261ffa87c476 100644 --- a/manifests/electron_content_browser_manifest_overlay.json +++ b/manifests/electron_content_browser_manifest_overlay.json @@ -6,7 +6,8 @@ "requires": { "device": [ "device:geolocation_control" ], "proxy_resolver": [ "factory" ], - "chrome_printing": [ "converter" ] + "chrome_printing": [ "converter" ], + "pdf_compositor": [ "compositor"] } } } diff --git a/patches/common/chromium/printing.patch b/patches/common/chromium/printing.patch index 4d59eb7e6494..74e62d5c8f6a 100644 --- a/patches/common/chromium/printing.patch +++ b/patches/common/chromium/printing.patch @@ -9,10 +9,10 @@ majority of changes originally come from these PRs: * https://github.com/electron/electron/pull/8596 diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc -index 1065e808e621c087bde9320abe019f05292f977c..13715870097b4f47ae164c12deb2bf783049ca6a 100644 +index 1065e808e621c087bde9320abe019f05292f977c..6cf33877d21a6bf06532f7f9d79804c744f1ad83 100644 --- a/chrome/browser/printing/print_job_worker.cc +++ b/chrome/browser/printing/print_job_worker.cc -@@ -20,12 +20,13 @@ +@@ -20,7 +20,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/printing/print_job.h" @@ -21,247 +21,30 @@ index 1065e808e621c087bde9320abe019f05292f977c..13715870097b4f47ae164c12deb2bf78 #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_frame_host.h" - #include "content/public/browser/web_contents.h" - #include "printing/print_job_constants.h" -+#include "printing/print_settings_conversion.h" - #include "printing/printed_document.h" - #include "printing/printing_utils.h" - #include "ui/base/l10n/l10n_util.h" -@@ -174,7 +175,8 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings, - bool has_selection, - MarginType margin_type, - bool is_scripted, -- bool is_modifiable) { -+ bool is_modifiable, -+ const base::string16& device_name) { - DCHECK(task_runner_->RunsTasksInCurrentSequence()); - DCHECK_EQ(page_number_, PageNumber::npos()); - -@@ -200,6 +202,12 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings, - base::BindOnce(&PrintJobWorker::GetSettingsWithUI, - base::Unretained(this), document_page_count, - has_selection, is_scripted))); -+ } else if (!device_name.empty()) { -+ BrowserThread::PostTask( -+ BrowserThread::UI, FROM_HERE, -+ base::BindOnce(&WorkerHoldRefCallback, base::WrapRefCounted(query_), -+ base::BindOnce(&PrintJobWorker::InitWithDeviceName, -+ base::Unretained(this), device_name))); - } else { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, -@@ -316,6 +324,14 @@ void PrintJobWorker::UseDefaultSettings() { - GetSettingsDone(result); - } - -+void PrintJobWorker::InitWithDeviceName(const base::string16& device_name) { -+ const auto& settings = printing_context_->settings(); -+ std::unique_ptr dic(new base::DictionaryValue); -+ printing::PrintSettingsToJobSettings(settings, dic.get()); -+ dic->SetString(kSettingDeviceName, device_name); -+ UpdatePrintSettings(std::move(dic)); -+} -+ - void PrintJobWorker::StartPrinting(PrintedDocument* new_document) { - DCHECK(task_runner_->RunsTasksInCurrentSequence()); - -diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h -index 182f7563e0c7d6486a5d2843d86f66524c02cb10..eed2230627d6b35486081f628a2ee97895bf16cf 100644 ---- a/chrome/browser/printing/print_job_worker.h -+++ b/chrome/browser/printing/print_job_worker.h -@@ -54,7 +54,8 @@ class PrintJobWorker { - bool has_selection, - MarginType margin_type, - bool is_scripted, -- bool is_modifiable); -+ bool is_modifiable, -+ const base::string16& device_name); - - // Set the new print settings from a dictionary value. - void SetSettings(std::unique_ptr new_settings); -@@ -155,6 +156,9 @@ class PrintJobWorker { - // systems. - void UseDefaultSettings(); - -+ // set the printer name -+ void InitWithDeviceName(const base::string16& device_name); -+ - // Printing context delegate. - const std::unique_ptr printing_context_delegate_; - -diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc -index e1613a9b52ad65afc8290498e8d9877ec58a0a10..db62078f2c084bb20681f7ef5ccccbceafd4f0b1 100644 ---- a/chrome/browser/printing/print_preview_message_handler.cc -+++ b/chrome/browser/printing/print_preview_message_handler.cc -@@ -57,7 +57,7 @@ void StopWorker(int document_cookie) { - base::BindOnce(&PrinterQuery::StopWorker, printer_query)); - } - } -- -+#if 0 - scoped_refptr GetDataFromHandle( - base::SharedMemoryHandle handle, - uint32_t data_size) { -@@ -70,6 +70,7 @@ scoped_refptr GetDataFromHandle( - return base::MakeRefCounted( - std::move(shared_buf), data_size); - } -+#endif - - } // namespace - -@@ -81,7 +82,7 @@ PrintPreviewMessageHandler::PrintPreviewMessageHandler( - - PrintPreviewMessageHandler::~PrintPreviewMessageHandler() { - } -- -+#if 0 - WebContents* PrintPreviewMessageHandler::GetPrintPreviewDialog() { - PrintPreviewDialogController* dialog_controller = - PrintPreviewDialogController::GetInstance(); -@@ -159,6 +160,7 @@ void PrintPreviewMessageHandler::OnDidPreviewPage( - GetDataFromHandle(content.metafile_data_handle, content.data_size)); - } - } -+#endif - - void PrintPreviewMessageHandler::OnMetafileReadyForPrinting( - content::RenderFrameHost* render_frame_host, -@@ -171,7 +173,8 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting( - NOTREACHED(); - return; - } -- -+} -+#if 0 - PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id); - if (!print_preview_ui) - return; -@@ -193,12 +196,13 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting( - GetDataFromHandle(content.metafile_data_handle, content.data_size)); - } - } -- -+#endif - void PrintPreviewMessageHandler::OnPrintPreviewFailed( - int document_cookie, - const PrintHostMsg_PreviewIds& ids) { - StopWorker(document_cookie); -- -+} -+#if 0 - PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id); - if (!print_preview_ui) - return; -@@ -318,15 +322,19 @@ void PrintPreviewMessageHandler::OnCompositePdfDocumentDone( - base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region)); - } - -+#endif -+ - bool PrintPreviewMessageHandler::OnMessageReceived( - const IPC::Message& message, - content::RenderFrameHost* render_frame_host) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(PrintPreviewMessageHandler, message, - render_frame_host) -+#if 0 - IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview, - OnRequestPrintPreview) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage) -+#endif - IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting, - OnMetafileReadyForPrinting) - IPC_MESSAGE_UNHANDLED(handled = false) -@@ -336,10 +344,13 @@ bool PrintPreviewMessageHandler::OnMessageReceived( - - handled = true; - IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message) -+#if 0 - IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount, - OnDidGetPreviewPageCount) -+#endif - IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed, - OnPrintPreviewFailed) -+#if 0 - IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDefaultPageLayout, - OnDidGetDefaultPageLayout) - IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewCancelled, -@@ -348,6 +359,7 @@ bool PrintPreviewMessageHandler::OnMessageReceived( - OnInvalidPrinterSettings) - IPC_MESSAGE_HANDLER(PrintHostMsg_SetOptionsFromDocument, - OnSetOptionsFromDocument) -+#endif - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h -index 6356792f29e82182c12118825949fe869cc80f9b..5592de3c097fd5d13fb0183fd3627cbb229d57b2 100644 ---- a/chrome/browser/printing/print_preview_message_handler.h -+++ b/chrome/browser/printing/print_preview_message_handler.h -@@ -37,8 +37,7 @@ struct PageSizeMargins; - - // Manages the print preview handling for a WebContents. - class PrintPreviewMessageHandler -- : public content::WebContentsObserver, -- public content::WebContentsUserData { -+ : public content::WebContentsObserver { - public: - ~PrintPreviewMessageHandler() override; - -@@ -46,10 +45,11 @@ class PrintPreviewMessageHandler - bool OnMessageReceived(const IPC::Message& message, - content::RenderFrameHost* render_frame_host) override; - -- private: -+ protected: - explicit PrintPreviewMessageHandler(content::WebContents* web_contents); - friend class content::WebContentsUserData; - -+#if 0 - // Gets the print preview dialog associated with the WebContents being - // observed. - content::WebContents* GetPrintPreviewDialog(); -@@ -72,12 +72,14 @@ class PrintPreviewMessageHandler - void OnDidPreviewPage(content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPreviewPage_Params& params, - const PrintHostMsg_PreviewIds& ids); -- void OnMetafileReadyForPrinting( -+#endif -+ virtual void OnMetafileReadyForPrinting( - content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPreviewDocument_Params& params, - const PrintHostMsg_PreviewIds& ids); -- void OnPrintPreviewFailed(int document_cookie, -- const PrintHostMsg_PreviewIds& ids); -+ virtual void OnPrintPreviewFailed(int document_cookie, -+ const PrintHostMsg_PreviewIds& ids); -+#if 0 - void OnPrintPreviewCancelled(int document_cookie, - const PrintHostMsg_PreviewIds& ids); - void OnInvalidPrinterSettings(int document_cookie, -@@ -104,6 +106,7 @@ class PrintPreviewMessageHandler - const PrintHostMsg_PreviewIds& ids, - mojom::PdfCompositor::Status status, - base::ReadOnlySharedMemoryRegion region); -+#endif - - base::WeakPtrFactory weak_ptr_factory_; - diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc -index 9b0c15b3c5016707788476295d53ab9d8a80e338..388994072186d1ba7b831f004983d5e087adf891 100644 +index 9b0c15b3c5016707788476295d53ab9d8a80e338..8b6580220fb0645a2335d625df8f0ceb211db88c 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc -@@ -30,7 +30,7 @@ - #include "chrome/browser/ui/simple_message_box.h" - #include "chrome/browser/ui/webui/print_preview/printer_handler.h" +@@ -27,10 +27,7 @@ + #include "chrome/browser/printing/print_view_manager_common.h" + #include "chrome/browser/printing/printer_query.h" + #include "chrome/browser/profiles/profile.h" +-#include "chrome/browser/ui/simple_message_box.h" +-#include "chrome/browser/ui/webui/print_preview/printer_handler.h" #include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -+#include "electron/grit/electron_resources.h" #include "components/prefs/pref_service.h" #include "components/printing/browser/print_composite_client.h" #include "components/printing/browser/print_manager_utils.h" -@@ -67,6 +67,8 @@ using PrintSettingsCallback = +@@ -45,6 +42,7 @@ + #include "content/public/browser/render_process_host.h" + #include "content/public/browser/render_view_host.h" + #include "content/public/browser/web_contents.h" ++#include "electron/grit/electron_resources.h" + #include "mojo/public/cpp/system/buffer.h" + #include "printing/buildflags/buildflags.h" + #include "printing/pdf_metafile_skia.h" +@@ -67,6 +65,8 @@ using PrintSettingsCallback = base::OnceCallback)>; void ShowWarningMessageBox(const base::string16& message) { @@ -270,7 +53,7 @@ index 9b0c15b3c5016707788476295d53ab9d8a80e338..388994072186d1ba7b831f004983d5e0 // Runs always on the UI thread. static bool is_dialog_shown = false; if (is_dialog_shown) -@@ -75,6 +77,7 @@ void ShowWarningMessageBox(const base::string16& message) { +@@ -75,6 +75,7 @@ void ShowWarningMessageBox(const base::string16& message) { base::AutoReset auto_reset(&is_dialog_shown, true); chrome::ShowWarningMessageBox(nullptr, base::string16(), message); @@ -278,7 +61,7 @@ index 9b0c15b3c5016707788476295d53ab9d8a80e338..388994072186d1ba7b831f004983d5e0 } #if BUILDFLAG(ENABLE_PRINT_PREVIEW) -@@ -112,12 +115,14 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents) +@@ -112,12 +113,14 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents) queue_(g_browser_process->print_job_manager()->queue()), weak_ptr_factory_(this) { DCHECK(queue_); @@ -293,253 +76,131 @@ index 9b0c15b3c5016707788476295d53ab9d8a80e338..388994072186d1ba7b831f004983d5e0 } PrintViewManagerBase::~PrintViewManagerBase() { -@@ -125,12 +130,16 @@ PrintViewManagerBase::~PrintViewManagerBase() { +@@ -125,12 +128,14 @@ PrintViewManagerBase::~PrintViewManagerBase() { DisconnectFromCurrentPrintJob(); } -bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) { +bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh, -+ bool silent, -+ bool print_background, -+ const base::string16& device_name) { ++ std::unique_ptr message, ++ CompletionCallback callback) { DisconnectFromCurrentPrintJob(); SetPrintingRFH(rfh); - int32_t id = rfh->GetRoutingID(); +- int32_t id = rfh->GetRoutingID(); - return PrintNowInternal(rfh, std::make_unique(id)); -+ return PrintNowInternal(rfh, std::make_unique( -+ id, silent, print_background, device_name)); ++ callback_ = std::move(callback); ++ return PrintNowInternal(rfh, std::move(message)); } #if BUILDFLAG(ENABLE_PRINT_PREVIEW) -@@ -249,7 +258,7 @@ void PrintViewManagerBase::UpdatePrintingEnabled() { +@@ -247,9 +252,9 @@ void PrintViewManagerBase::StartLocalPrintJob( + void PrintViewManagerBase::UpdatePrintingEnabled() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // The Unretained() is safe because ForEachFrame() is synchronous. - web_contents()->ForEachFrame(base::BindRepeating( - &PrintViewManagerBase::SendPrintingEnabled, base::Unretained(this), +- web_contents()->ForEachFrame(base::BindRepeating( +- &PrintViewManagerBase::SendPrintingEnabled, base::Unretained(this), - printing_enabled_.GetValue())); -+ true)); ++ web_contents()->ForEachFrame( ++ base::BindRepeating(&PrintViewManagerBase::SendPrintingEnabled, ++ base::Unretained(this), true)); } void PrintViewManagerBase::NavigationStopped() { -@@ -341,8 +350,10 @@ void PrintViewManagerBase::OnDidPrintDocument( - void PrintViewManagerBase::OnPrintingFailed(int cookie) { +@@ -316,7 +321,7 @@ void PrintViewManagerBase::OnDidPrintDocument( + } + + auto* client = PrintCompositeClient::FromWebContents(web_contents()); +- if (IsOopifEnabled() && !PrintingPdfContent(render_frame_host)) { ++ if (IsOopifEnabled()) { + client->DoCompositeDocumentToPdf( + params.document_cookie, render_frame_host, content.metafile_data_handle, + content.data_size, content.subframe_content_info, +@@ -342,7 +347,7 @@ void PrintViewManagerBase::OnPrintingFailed(int cookie) { PrintManager::OnPrintingFailed(cookie); -+#if 0 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) - ShowPrintErrorDialog(); -+#endif +- ShowPrintErrorDialog(); ++ // ShowPrintErrorDialog(); #endif ReleasePrinterQuery(); -@@ -592,6 +603,10 @@ void PrintViewManagerBase::ReleasePrintJob() { +@@ -592,6 +597,9 @@ void PrintViewManagerBase::ReleasePrintJob() { content::RenderFrameHost* rfh = printing_rfh_; printing_rfh_ = nullptr; -+ if (!callback.is_null()) { -+ callback.Run(printing_succeeded_ && print_job_); -+ } ++ if (!callback_.is_null()) ++ std::move(callback_).Run(printing_succeeded_); + if (!print_job_) return; diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h -index fe0e0b5b065cdcc4edd04665271db14b1bf935e3..6670fc8abd2dabe601581cf43e51bb59f5ce577f 100644 +index fe0e0b5b065cdcc4edd04665271db14b1bf935e3..be2b3ceb0bd582d499372374349bdd685a1994b6 100644 --- a/chrome/browser/printing/print_view_manager_base.h +++ b/chrome/browser/printing/print_view_manager_base.h -@@ -7,6 +7,7 @@ +@@ -38,6 +38,8 @@ class PrintJob; + class PrintQueriesQueue; + class PrinterQuery; - #include - -+#include "base/callback.h" - #include "base/macros.h" - #include "base/memory/read_only_shared_memory_region.h" - #include "base/memory/scoped_refptr.h" -@@ -47,7 +48,10 @@ class PrintViewManagerBase : public content::NotificationObserver, ++using CompletionCallback = base::OnceCallback; ++ + // Base class for managing the print commands for a WebContents. + class PrintViewManagerBase : public content::NotificationObserver, + public PrintManager { +@@ -47,7 +49,9 @@ class PrintViewManagerBase : public content::NotificationObserver, // Prints the current document immediately. Since the rendering is // asynchronous, the actual printing will not be completed on the return of // this function. Returns false if printing is impossible at the moment. - virtual bool PrintNow(content::RenderFrameHost* rfh); + virtual bool PrintNow(content::RenderFrameHost* rfh, -+ bool silent, -+ bool print_background, -+ const base::string16& device_name); ++ std::unique_ptr message, ++ CompletionCallback callback); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) // Prints the document in |print_data| with settings specified in -@@ -72,6 +76,8 @@ class PrintViewManagerBase : public content::NotificationObserver, +@@ -195,6 +199,9 @@ class PrintViewManagerBase : public content::NotificationObserver, + // The current RFH that is printing with a system printing dialog. + content::RenderFrameHost* printing_rfh_; - base::string16 RenderSourceName(); - -+ void SetCallback(const base::Callback& cb) { callback = cb; }; ++ // Responded with success of the print job. ++ CompletionCallback callback_; + - protected: - explicit PrintViewManagerBase(content::WebContents* web_contents); + // Indication of success of the print job. + bool printing_succeeded_; -@@ -208,6 +214,8 @@ class PrintViewManagerBase : public content::NotificationObserver, - - scoped_refptr queue_; - -+ base::Callback callback; -+ - base::WeakPtrFactory weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBase); -diff --git a/chrome/browser/printing/print_view_manager_common.cc b/chrome/browser/printing/print_view_manager_common.cc -index 3d36b0b972b681c861c4e5273b3371eeabda1bce..3400f4a3470bda3ebf002417837592a12be4d55a 100644 ---- a/chrome/browser/printing/print_view_manager_common.cc -+++ b/chrome/browser/printing/print_view_manager_common.cc -@@ -11,12 +11,12 @@ - #include "printing/buildflags/buildflags.h" - #include "url/gurl.h" - --#if BUILDFLAG(ENABLE_EXTENSIONS) -+#if 0 - #include "components/guest_view/browser/guest_view_manager.h" - #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" - #endif // BUILDFLAG(ENABLE_EXTENSIONS) - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) -+#if 0 - #include "chrome/browser/printing/print_view_manager.h" - #else - #include "chrome/browser/printing/print_view_manager_basic.h" -@@ -25,7 +25,7 @@ - namespace printing { - - namespace { --#if BUILDFLAG(ENABLE_EXTENSIONS) -+#if 0 - // Stores |guest_contents| in |result| and returns true if |guest_contents| is a - // full page MimeHandlerViewGuest plugin. Otherwise, returns false. - bool StoreFullPagePlugin(content::WebContents** result, -@@ -43,7 +43,7 @@ bool StoreFullPagePlugin(content::WebContents** result, - // If we have a single full-page embedded mime handler view guest, print the - // guest's WebContents instead. - content::WebContents* GetWebContentsToUse(content::WebContents* contents) { --#if BUILDFLAG(ENABLE_EXTENSIONS) -+#if 0 - guest_view::GuestViewManager* guest_view_manager = - guest_view::GuestViewManager::FromBrowserContext( - contents->GetBrowserContext()); -@@ -69,7 +69,8 @@ content::RenderFrameHost* GetRenderFrameHostToUse( - void StartPrint(content::WebContents* contents, - bool print_preview_disabled, - bool has_selection) { --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) -+ -+#if 0 - using PrintViewManagerImpl = PrintViewManager; - #else - using PrintViewManagerImpl = PrintViewManagerBasic; -@@ -85,18 +86,20 @@ void StartPrint(content::WebContents* contents, - GetRenderFrameHostToUse(contents, contents_to_use); - if (!rfh_to_use) - return; -- -+#if 0 - #if BUILDFLAG(ENABLE_PRINT_PREVIEW) - if (!print_preview_disabled) { - print_view_manager->PrintPreviewNow(rfh_to_use, has_selection); - return; - } - #endif // ENABLE_PRINT_PREVIEW -+#endif - -- print_view_manager->PrintNow(rfh_to_use); -+ print_view_manager->PrintNow(rfh_to_use, false, true, base::string16()); - } - - void StartBasicPrint(content::WebContents* contents) { -+#if 0 - #if BUILDFLAG(ENABLE_PRINT_PREVIEW) - content::WebContents* contents_to_use = GetWebContentsToUse(contents); - PrintViewManager* print_view_manager = -@@ -111,6 +114,7 @@ void StartBasicPrint(content::WebContents* contents) { - - print_view_manager->BasicPrint(rfh_to_use); - #endif // ENABLE_PRINT_PREVIEW -+#endif - } - - content::RenderFrameHost* GetFrameToPrint(content::WebContents* contents) { -diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc -index cc236873136797d90f3f5132726b34e7a3d7a989..159ec3a04502a4462bafbe31e39f58c6104c7e11 100644 ---- a/chrome/browser/printing/printer_query.cc -+++ b/chrome/browser/printing/printer_query.cc -@@ -94,7 +94,31 @@ void PrinterQuery::GetSettings(GetSettingsAskParam ask_user_for_settings, - base::BindOnce(&PrintJobWorker::GetSettings, - base::Unretained(worker_.get()), - is_print_dialog_box_shown_, expected_page_count, -- has_selection, margin_type, is_scripted, is_modifiable)); -+ has_selection, margin_type, is_scripted, is_modifiable, -+ base::string16())); -+} -+ -+void PrinterQuery::GetSettings(GetSettingsAskParam ask_user_for_settings, -+ int expected_page_count, -+ bool has_selection, -+ MarginType margin_type, -+ bool is_scripted, -+ bool is_modifiable, -+ const base::string16& device_name, -+ base::OnceClosure callback) { -+ DCHECK(RunsTasksInCurrentSequence()); -+ DCHECK(!is_print_dialog_box_shown_); -+ -+ StartWorker(std::move(callback)); -+ -+ is_print_dialog_box_shown_ = false; -+ worker_->PostTask( -+ FROM_HERE, -+ base::BindOnce(&PrintJobWorker::GetSettings, -+ base::Unretained(worker_.get()), -+ is_print_dialog_box_shown_, expected_page_count, -+ has_selection, margin_type, is_scripted, is_modifiable, -+ device_name)); - } - - void PrinterQuery::SetSettings( -diff --git a/chrome/browser/printing/printer_query.h b/chrome/browser/printing/printer_query.h -index 64db84f9f8532e2e53c07206f6d1505cc162df58..0e12adfe7957b071a71e377861a2ea0cf1a57b5e 100644 ---- a/chrome/browser/printing/printer_query.h -+++ b/chrome/browser/printing/printer_query.h -@@ -59,6 +59,15 @@ class PrinterQuery : public base::RefCountedThreadSafe { - bool is_modifiable, - base::OnceClosure callback); - -+ void GetSettings(GetSettingsAskParam ask_user_for_settings, -+ int expected_page_count, -+ bool has_selection, -+ MarginType margin_type, -+ bool is_scripted, -+ bool is_modifiable, -+ const base::string16& device_name, -+ base::OnceClosure callback); -+ - // Updates the current settings with |new_settings| dictionary values. - virtual void SetSettings(std::unique_ptr new_settings, - base::OnceClosure callback); diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc -index 54866fdcdb64f4ffd2414c8637ffa2f8fb10c024..40d6bd62706c1b47aff9ce32df713a47d203538f 100644 +index 54866fdcdb64f4ffd2414c8637ffa2f8fb10c024..e1208906a6145b30c72a484a3b29f47279d75a0e 100644 --- a/chrome/browser/printing/printing_message_filter.cc +++ b/chrome/browser/printing/printing_message_filter.cc -@@ -94,12 +94,12 @@ PrintViewManager* GetPrintViewManager(int render_process_id, +@@ -20,6 +20,7 @@ + #include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h" + #include "components/printing/browser/print_manager_utils.h" + #include "components/printing/common/print_messages.h" ++#include "content/public/browser/browser_context.h" + #include "content/public/browser/render_frame_host.h" + #include "content/public/browser/web_contents.h" + #include "content/public/common/child_process_host.h" +@@ -94,20 +95,23 @@ PrintViewManager* GetPrintViewManager(int render_process_id, } // namespace -PrintingMessageFilter::PrintingMessageFilter(int render_process_id, - Profile* profile) -+PrintingMessageFilter::PrintingMessageFilter(int render_process_id) ++PrintingMessageFilter::PrintingMessageFilter( ++ int render_process_id, ++ content::BrowserContext* browser_context) : BrowserMessageFilter(PrintMsgStart), render_process_id_(render_process_id), queue_(g_browser_process->print_job_manager()->queue()) { DCHECK(queue_.get()); -+#if 0 printing_shutdown_notifier_ = PrintingMessageFilterShutdownNotifierFactory::GetInstance() - ->Get(profile) -@@ -108,6 +108,7 @@ PrintingMessageFilter::PrintingMessageFilter(int render_process_id, +- ->Get(profile) ++ ->Get(browser_context) + ->Subscribe(base::Bind(&PrintingMessageFilter::ShutdownOnUIThread, + base::Unretained(this))); ++#if 0 is_printing_enabled_.Init(prefs::kPrintingEnabled, profile->GetPrefs()); is_printing_enabled_.MoveToThread( BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); @@ -547,142 +208,78 @@ index 54866fdcdb64f4ffd2414c8637ffa2f8fb10c024..40d6bd62706c1b47aff9ce32df713a47 } PrintingMessageFilter::~PrintingMessageFilter() { -@@ -116,7 +117,9 @@ PrintingMessageFilter::~PrintingMessageFilter() { - - void PrintingMessageFilter::ShutdownOnUIThread() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); -+#if 0 - is_printing_enabled_.Destroy(); -+#endif - printing_shutdown_notifier_.reset(); - } - -@@ -145,6 +148,8 @@ bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message) { - #endif - IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings, - OnGetDefaultPrintSettings) -+ IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_InitSettingWithDeviceName, -+ OnInitSettingWithDeviceName) - IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint) - IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings, - OnUpdatePrintSettings) -@@ -188,7 +193,7 @@ void PrintingMessageFilter::OnTempFileForPrintingWritten(int render_frame_id, +@@ -188,11 +192,13 @@ void PrintingMessageFilter::OnTempFileForPrintingWritten(int render_frame_id, void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) { DCHECK_CURRENTLY_ON(BrowserThread::IO); scoped_refptr printer_query; -- if (!is_printing_enabled_.GetValue()) { -+ if (false) { ++#if 0 + if (!is_printing_enabled_.GetValue()) { // Reply with NULL query. OnGetDefaultPrintSettingsReply(printer_query, reply_msg); return; -@@ -208,6 +213,26 @@ void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) { - printer_query, reply_msg)); - } - -+void PrintingMessageFilter::OnInitSettingWithDeviceName( -+ const base::string16& device_name, -+ IPC::Message* reply_msg) { -+ DCHECK_CURRENTLY_ON(BrowserThread::IO); -+ scoped_refptr printer_query; -+ printer_query = queue_->PopPrinterQuery(0); -+ if (!printer_query.get()) { -+ printer_query = -+ queue_->CreatePrinterQuery(render_process_id_, reply_msg->routing_id()); -+ } -+ -+ // Loads default settings. This is asynchronous, only the IPC message sender -+ // will hang until the settings are retrieved. -+ printer_query->GetSettings( -+ PrinterQuery::GetSettingsAskParam::DEFAULTS, 0, false, DEFAULT_MARGINS, -+ true, true, device_name, -+ base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply, this, -+ printer_query, reply_msg)); -+} -+ - void PrintingMessageFilter::OnGetDefaultPrintSettingsReply( - scoped_refptr printer_query, - IPC::Message* reply_msg) { -@@ -301,7 +326,7 @@ void PrintingMessageFilter::OnUpdatePrintSettings( + } ++#endif + printer_query = queue_->PopPrinterQuery(0); + if (!printer_query.get()) { + printer_query = +@@ -301,11 +307,13 @@ void PrintingMessageFilter::OnUpdatePrintSettings( std::unique_ptr new_settings(job_settings.DeepCopy()); scoped_refptr printer_query; -- if (!is_printing_enabled_.GetValue()) { -+ if (false) { ++#if 0 + if (!is_printing_enabled_.GetValue()) { // Reply with NULL query. OnUpdatePrintSettingsReply(printer_query, reply_msg); return; -@@ -361,10 +386,13 @@ void PrintingMessageFilter::OnUpdatePrintSettingsReply( } - } - -+ ++#endif + printer_query = queue_->PopPrinterQuery(document_cookie); + if (!printer_query.get()) { + printer_query = queue_->CreatePrinterQuery( +@@ -364,7 +372,7 @@ void PrintingMessageFilter::OnUpdatePrintSettingsReply( #if BUILDFLAG(ENABLE_PRINT_PREVIEW) void PrintingMessageFilter::OnCheckForCancel(const PrintHostMsg_PreviewIds& ids, bool* cancel) { -+#if 0 - PrintPreviewUI::GetCurrentPrintPreviewStatus(ids, cancel); -+#endif +- PrintPreviewUI::GetCurrentPrintPreviewStatus(ids, cancel); ++ // PrintPreviewUI::GetCurrentPrintPreviewStatus(ids, cancel); } #endif diff --git a/chrome/browser/printing/printing_message_filter.h b/chrome/browser/printing/printing_message_filter.h -index a881a853bfb0b46d0e074b7e86121429a5a761a3..46ebeede19557c718bf14b7feb81cf1acf3ca00a 100644 +index a881a853bfb0b46d0e074b7e86121429a5a761a3..87efeab40574ac72e4dea33f3ff68919bff93839 100644 --- a/chrome/browser/printing/printing_message_filter.h +++ b/chrome/browser/printing/printing_message_filter.h -@@ -38,7 +38,7 @@ class PrinterQuery; +@@ -27,6 +27,10 @@ class DictionaryValue; + #if defined(OS_ANDROID) + struct FileDescriptor; + #endif ++} // namespace base ++ ++namespace content { ++class BrowserContext; + } + + namespace printing { +@@ -38,7 +42,8 @@ class PrinterQuery; // renderer process on the IPC thread. class PrintingMessageFilter : public content::BrowserMessageFilter { public: - PrintingMessageFilter(int render_process_id, Profile* profile); -+ PrintingMessageFilter(int render_process_id); ++ PrintingMessageFilter(int render_process_id, ++ content::BrowserContext* browser_context); // content::BrowserMessageFilter methods. void OverrideThreadForMessage(const IPC::Message& message, -@@ -73,6 +73,11 @@ class PrintingMessageFilter : public content::BrowserMessageFilter { +@@ -73,6 +78,7 @@ class PrintingMessageFilter : public content::BrowserMessageFilter { // Get the default print setting. void OnGetDefaultPrintSettings(IPC::Message* reply_msg); -+ -+ // Set deviceName -+ void OnInitSettingWithDeviceName(const base::string16& device_name, -+ IPC::Message* reply_msg); + void OnGetDefaultPrintSettingsReply(scoped_refptr printer_query, IPC::Message* reply_msg); -diff --git a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc -index 38fd116aa096b00266b6015f3196c3f432d23a9e..62fcfaa00084332ba07ff123e5136df606bb8168 100644 ---- a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc -+++ b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc -@@ -19,7 +19,7 @@ - #include "third_party/blink/public/web/web_element.h" - #include "third_party/blink/public/web/web_local_frame.h" - --#if BUILDFLAG(ENABLE_EXTENSIONS) -+#if 0 - #include "chrome/common/extensions/extension_constants.h" - #include "extensions/common/constants.h" - #include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h" -@@ -45,7 +45,7 @@ bool ChromePrintRenderFrameHelperDelegate::CancelPrerender( - // Return the PDF object element if |frame| is the out of process PDF extension. - blink::WebElement ChromePrintRenderFrameHelperDelegate::GetPdfElement( - blink::WebLocalFrame* frame) { --#if BUILDFLAG(ENABLE_EXTENSIONS) -+#if 0 - GURL url = frame->GetDocument().Url(); - bool inside_print_preview = url.GetOrigin() == chrome::kChromeUIPrintURL; - bool inside_pdf_extension = -@@ -71,7 +71,7 @@ bool ChromePrintRenderFrameHelperDelegate::IsPrintPreviewEnabled() { - - bool ChromePrintRenderFrameHelperDelegate::OverridePrint( - blink::WebLocalFrame* frame) { --#if BUILDFLAG(ENABLE_EXTENSIONS) -+#if 0 - if (!frame->GetDocument().IsPluginDocument()) - return false; - diff --git a/components/printing/common/print_messages.h b/components/printing/common/print_messages.h -index d29bb6aedecd228e4bc02c84b86cce7151f33746..bb0bd7bfa494f813c30b47e84b78d2e0a951a321 100644 +index d29bb6aedecd228e4bc02c84b86cce7151f33746..b489694b2701bddcfa95e187f5fcbf65d9a8ae8c 100644 --- a/components/printing/common/print_messages.h +++ b/components/printing/common/print_messages.h @@ -367,7 +367,10 @@ IPC_MESSAGE_ROUTED0(PrintMsg_PrintNodeUnderContextMenu) @@ -693,47 +290,57 @@ index d29bb6aedecd228e4bc02c84b86cce7151f33746..bb0bd7bfa494f813c30b47e84b78d2e0 +IPC_MESSAGE_ROUTED3(PrintMsg_PrintPages, + bool /* silent print */, + bool /* print page's background */, -+ base::string16 /* device name*/) ++ base::DictionaryValue /* settings */) // Like PrintMsg_PrintPages, but using the print preview document's frame/node. IPC_MESSAGE_ROUTED0(PrintMsg_PrintForSystemDialog) -@@ -425,6 +428,11 @@ IPC_MESSAGE_ROUTED2(PrintHostMsg_DidPrintFrameContent, - IPC_SYNC_MESSAGE_ROUTED0_1(PrintHostMsg_GetDefaultPrintSettings, - PrintMsg_Print_Params /* default_settings */) - -+// you can set the printer -+IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_InitSettingWithDeviceName, -+ base::string16, /* device name */ -+ PrintMsg_Print_Params /* default_settings */) -+ - // The renderer wants to update the current print settings with new - // |job_settings|. - IPC_SYNC_MESSAGE_ROUTED2_2(PrintHostMsg_UpdatePrintSettings, diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc -index c7ea5cf76aa629b8feaf99ff6e289140de1d35bd..1c3177e679ff6a3bbaa10cf74b9d538af7e5a588 100644 +index c7ea5cf76aa629b8feaf99ff6e289140de1d35bd..aee6e02b86a4cf99e263f5a26025a681e3f41463 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc -@@ -1093,7 +1093,9 @@ void PrintRenderFrameHelper::OnDestruct() { +@@ -1045,7 +1045,9 @@ void PrintRenderFrameHelper::ScriptedPrint(bool user_initiated) { + web_frame->DispatchBeforePrintEvent(); + if (!weak_this) + return; +- Print(web_frame, blink::WebNode(), true /* is_scripted? */); ++ Print(web_frame, blink::WebNode(), true /* is_scripted? */, ++ false /* silent */, false /* print_background */, ++ base::DictionaryValue() /* new_settings */); + if (weak_this) + web_frame->DispatchAfterPrintEvent(); + } +@@ -1093,7 +1095,10 @@ void PrintRenderFrameHelper::OnDestruct() { delete this; } -void PrintRenderFrameHelper::OnPrintPages() { -+void PrintRenderFrameHelper::OnPrintPages(bool silent, -+ bool print_background, -+ const base::string16& device_name) { ++void PrintRenderFrameHelper::OnPrintPages( ++ bool silent, ++ bool print_background, ++ const base::DictionaryValue& settings) { if (ipc_nesting_level_ > 1) return; -@@ -1106,7 +1108,7 @@ void PrintRenderFrameHelper::OnPrintPages() { +@@ -1106,7 +1111,7 @@ void PrintRenderFrameHelper::OnPrintPages() { // If we are printing a PDF extension frame, find the plugin node and print // that instead. auto plugin = delegate_->GetPdfElement(frame); - Print(frame, plugin, false /* is_scripted? */); -+ Print(frame, plugin, false, silent, print_background, device_name); ++ Print(frame, plugin, false, silent, print_background, settings); if (weak_this) frame->DispatchAfterPrintEvent(); // WARNING: |this| may be gone at this point. Do not do any more work here and -@@ -1158,6 +1160,8 @@ void PrintRenderFrameHelper::OnPrintPreview( +@@ -1122,7 +1127,8 @@ void PrintRenderFrameHelper::OnPrintForSystemDialog() { + return; + } + auto weak_this = weak_ptr_factory_.GetWeakPtr(); +- Print(frame, print_preview_context_.source_node(), false); ++ Print(frame, print_preview_context_.source_node(), false, false, false, ++ base::DictionaryValue()); + if (weak_this) + frame->DispatchAfterPrintEvent(); + // WARNING: |this| may be gone at this point. Do not do any more work here and +@@ -1158,6 +1164,8 @@ void PrintRenderFrameHelper::OnPrintPreview( if (ipc_nesting_level_ > 1) return; @@ -742,7 +349,18 @@ index c7ea5cf76aa629b8feaf99ff6e289140de1d35bd..1c3177e679ff6a3bbaa10cf74b9d538a print_preview_context_.OnPrintPreview(); UMA_HISTOGRAM_ENUMERATION("PrintPreview.PreviewEvent", -@@ -1552,7 +1556,10 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) { +@@ -1541,7 +1549,9 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) { + + auto self = weak_ptr_factory_.GetWeakPtr(); + Print(duplicate_node.GetDocument().GetFrame(), duplicate_node, +- false /* is_scripted? */); ++ false /* is_scripted? */, false /* silent */, ++ false /* print_background */, ++ base::DictionaryValue() /* new_settings */); + // Check if |this| is still valid. + if (!self) + return; +@@ -1552,7 +1562,10 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) { void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame, const blink::WebNode& node, @@ -750,20 +368,20 @@ index c7ea5cf76aa629b8feaf99ff6e289140de1d35bd..1c3177e679ff6a3bbaa10cf74b9d538a + bool is_scripted, + bool silent, + bool print_background, -+ const base::string16& device_name) { ++ const base::DictionaryValue& settings) { // If still not finished with earlier print request simply ignore. if (prep_frame_view_) return; -@@ -1560,7 +1567,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame, +@@ -1560,7 +1573,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame, FrameReference frame_ref(frame); int expected_page_count = 0; - if (!CalculateNumberOfPages(frame, node, &expected_page_count)) { -+ if (!CalculateNumberOfPages(frame, node, &expected_page_count, device_name)) { ++ if (!CalculateNumberOfPages(frame, node, &expected_page_count, settings)) { DidFinishPrinting(FAIL_PRINT_INIT); return; // Failed to init print page settings. } -@@ -1580,8 +1587,9 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame, +@@ -1580,8 +1593,9 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame, PrintMsg_PrintPages_Params print_settings; auto self = weak_ptr_factory_.GetWeakPtr(); @@ -775,7 +393,7 @@ index c7ea5cf76aa629b8feaf99ff6e289140de1d35bd..1c3177e679ff6a3bbaa10cf74b9d538a // Check if |this| is still valid. if (!self) return; -@@ -1591,6 +1599,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame, +@@ -1591,6 +1605,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame, ? blink::kWebPrintScalingOptionSourceSize : scaling_option; SetPrintPagesParams(print_settings); @@ -783,63 +401,55 @@ index c7ea5cf76aa629b8feaf99ff6e289140de1d35bd..1c3177e679ff6a3bbaa10cf74b9d538a if (print_settings.params.dpi.IsEmpty() || !print_settings.params.document_cookie) { DidFinishPrinting(OK); // Release resources and fail silently on failure. -@@ -1600,7 +1609,6 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame, - - // Render Pages for printing. - if (!RenderPagesForPrint(frame_ref.GetFrame(), node)) { -- LOG(ERROR) << "RenderPagesForPrint failed"; - DidFinishPrinting(FAIL_PRINT); - } - scripting_throttler_.Reset(); -@@ -1778,10 +1786,17 @@ std::vector PrintRenderFrameHelper::GetPrintedPages( +@@ -1778,10 +1793,24 @@ std::vector PrintRenderFrameHelper::GetPrintedPages( return printed_pages; } -bool PrintRenderFrameHelper::InitPrintSettings(bool fit_to_paper_size) { +bool PrintRenderFrameHelper::InitPrintSettings( + bool fit_to_paper_size, -+ const base::string16& device_name) { ++ const base::DictionaryValue& new_settings) { PrintMsg_PrintPages_Params settings; -+ if (device_name.empty()) { - Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(), - &settings.params)); +- Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(), +- &settings.params)); ++ if (new_settings.empty()) { ++ Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(), ++ &settings.params)); + } else { -+ Send(new PrintHostMsg_InitSettingWithDeviceName(routing_id(), device_name, -+ &settings.params)); ++ // Send the cookie so that UpdatePrintSettings can reuse PrinterQuery when ++ // possible. ++ int cookie = ++ print_pages_params_ ? print_pages_params_->params.document_cookie : 0; ++ bool canceled = false; ++ Send(new PrintHostMsg_UpdatePrintSettings( ++ routing_id(), cookie, new_settings, &settings, &canceled)); ++ if (canceled) ++ return false; + } // Check if the printer returned any settings, if the settings is empty, we // can safely assume there are no printer drivers configured. So we safely // terminate. -@@ -1803,10 +1818,11 @@ bool PrintRenderFrameHelper::InitPrintSettings(bool fit_to_paper_size) { +@@ -1801,12 +1830,14 @@ bool PrintRenderFrameHelper::InitPrintSettings(bool fit_to_paper_size) { + return result; + } - bool PrintRenderFrameHelper::CalculateNumberOfPages(blink::WebLocalFrame* frame, - const blink::WebNode& node, +-bool PrintRenderFrameHelper::CalculateNumberOfPages(blink::WebLocalFrame* frame, +- const blink::WebNode& node, - int* number_of_pages) { -+ int* number_of_pages, -+ const base::string16& device_name) { ++bool PrintRenderFrameHelper::CalculateNumberOfPages( ++ blink::WebLocalFrame* frame, ++ const blink::WebNode& node, ++ int* number_of_pages, ++ const base::DictionaryValue& settings) { DCHECK(frame); bool fit_to_paper_size = !(PrintingNodeOrPdfFrame(frame, node)); - if (!InitPrintSettings(fit_to_paper_size)) { -+ if (!InitPrintSettings(fit_to_paper_size, device_name)) { ++ if (!InitPrintSettings(fit_to_paper_size, settings)) { notify_browser_of_print_failure_ = false; Send(new PrintHostMsg_ShowInvalidPrinterSettingsError(routing_id())); return false; -@@ -1885,11 +1901,13 @@ bool PrintRenderFrameHelper::UpdatePrintSettings( - return false; - } - -+#if 0 - if (!job_settings->GetInteger(kPreviewUIID, &settings.params.preview_ui_id)) { - NOTREACHED(); - print_preview_context_.set_error(PREVIEW_ERROR_BAD_SETTING); - return false; - } -+#endif - - // Validate expected print preview settings. - if (!job_settings->GetInteger(kPreviewRequestID, diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h -index 6e2d7e1467b7bc179b1a0fc30dd656de612708cb..0e6e8ea770f52e5ddfb9f3e2d5793ad8184e8359 100644 +index 6e2d7e1467b7bc179b1a0fc30dd656de612708cb..8b1516ce5e11d915efdf06cc75f334cd92ce7d99 100644 --- a/components/printing/renderer/print_render_frame_helper.h +++ b/components/printing/renderer/print_render_frame_helper.h @@ -186,7 +186,9 @@ class PrintRenderFrameHelper @@ -849,7 +459,7 @@ index 6e2d7e1467b7bc179b1a0fc30dd656de612708cb..0e6e8ea770f52e5ddfb9f3e2d5793ad8 - void OnPrintPages(); + void OnPrintPages(bool silent, + bool print_background, -+ const base::string16& device_name); ++ const base::DictionaryValue& settings); void OnPrintForSystemDialog(); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) void OnInitiatePrintPreview(bool has_selection); @@ -859,141 +469,26 @@ index 6e2d7e1467b7bc179b1a0fc30dd656de612708cb..0e6e8ea770f52e5ddfb9f3e2d5793ad8 const blink::WebNode& node, - bool is_scripted); + bool is_scripted, -+ bool silent = false, -+ bool print_background = false, -+ const base::string16& device_name = base::string16()); ++ bool silent, ++ bool print_background, ++ const base::DictionaryValue& settings); // Notification when printing is done - signal tear-down/free resources. void DidFinishPrinting(PrintingResult result); -@@ -247,12 +252,15 @@ class PrintRenderFrameHelper +@@ -247,12 +252,14 @@ class PrintRenderFrameHelper // Initialize print page settings with default settings. // Used only for native printing workflow. - bool InitPrintSettings(bool fit_to_paper_size); + bool InitPrintSettings(bool fit_to_paper_size, -+ const base::string16& device_name = base::string16()); ++ const base::DictionaryValue& settings); // Calculate number of pages in source document. -- bool CalculateNumberOfPages(blink::WebLocalFrame* frame, -- const blink::WebNode& node, + bool CalculateNumberOfPages(blink::WebLocalFrame* frame, + const blink::WebNode& node, - int* number_of_pages); -+ bool CalculateNumberOfPages( -+ blink::WebLocalFrame* frame, -+ const blink::WebNode& node, -+ int* number_of_pages, -+ const base::string16& device_name = base::string16()); ++ int* number_of_pages, ++ const base::DictionaryValue& settings); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) // Set options for print preset from source PDF document. -diff --git a/printing/print_settings_conversion.cc b/printing/print_settings_conversion.cc -index a4c9f49d65e0f6bccee7d49465cbba5a28785a22..b26eb4186880d869bd7466d1ad7f368aeefb175d 100644 ---- a/printing/print_settings_conversion.cc -+++ b/printing/print_settings_conversion.cc -@@ -42,6 +42,19 @@ void GetCustomMarginsFromJobSettings(const base::DictionaryValue& settings, - } - } - -+void SetCustomMarginsToJobSettings(const PageSizeMargins& page_size_margins, -+ base::DictionaryValue* settings) { -+ std::unique_ptr custom_margins( -+ new base::DictionaryValue()); -+ custom_margins->SetDouble(kSettingMarginTop, page_size_margins.margin_top); -+ custom_margins->SetDouble(kSettingMarginBottom, -+ page_size_margins.margin_bottom); -+ custom_margins->SetDouble(kSettingMarginLeft, page_size_margins.margin_left); -+ custom_margins->SetDouble(kSettingMarginRight, -+ page_size_margins.margin_right); -+ settings->Set(kSettingMarginsCustom, std::move(custom_margins)); -+} -+ - void SetMarginsToJobSettings(const std::string& json_path, - const PageMargins& margins, - base::DictionaryValue* job_settings) { -@@ -224,6 +237,72 @@ bool PrintSettingsFromJobSettings(const base::DictionaryValue& job_settings, - return true; - } - -+void PrintSettingsToJobSettings(const PrintSettings& settings, -+ base::DictionaryValue* job_settings) { -+ // header footer -+ job_settings->SetBoolean(kSettingHeaderFooterEnabled, -+ settings.display_header_footer()); -+ job_settings->SetString(kSettingHeaderFooterTitle, settings.title()); -+ job_settings->SetString(kSettingHeaderFooterURL, settings.url()); -+ -+ // bg -+ job_settings->SetBoolean(kSettingShouldPrintBackgrounds, -+ settings.should_print_backgrounds()); -+ job_settings->SetBoolean(kSettingShouldPrintSelectionOnly, -+ settings.selection_only()); -+ -+ // margin -+ auto margin_type = settings.margin_type(); -+ job_settings->SetInteger(kSettingMarginsType, settings.margin_type()); -+ if (margin_type == CUSTOM_MARGINS) { -+ const auto& margins_in_points = -+ settings.requested_custom_margins_in_points(); -+ -+ PageSizeMargins page_size_margins; -+ -+ page_size_margins.margin_top = margins_in_points.top; -+ page_size_margins.margin_bottom = margins_in_points.bottom; -+ page_size_margins.margin_left = margins_in_points.left; -+ page_size_margins.margin_right = margins_in_points.right; -+ SetCustomMarginsToJobSettings(page_size_margins, job_settings); -+ } -+ job_settings->SetInteger(kSettingPreviewPageCount, 1); -+ -+ // range -+ -+ if (!settings.ranges().empty()) { -+ auto page_range_array = std::make_unique(); -+ job_settings->Set(kSettingPageRange, std::move(page_range_array)); -+ for (size_t i = 0; i < settings.ranges().size(); ++i) { -+ std::unique_ptr dict(new base::DictionaryValue); -+ dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1); -+ dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1); -+ page_range_array->Append(std::move(dict)); -+ } -+ } -+ -+ job_settings->SetBoolean(kSettingCollate, settings.collate()); -+ job_settings->SetInteger(kSettingCopies, 1); -+ job_settings->SetInteger(kSettingColor, settings.color()); -+ job_settings->SetInteger(kSettingDuplexMode, settings.duplex_mode()); -+ job_settings->SetBoolean(kSettingLandscape, settings.landscape()); -+ job_settings->SetString(kSettingDeviceName, settings.device_name()); -+ job_settings->SetInteger(kSettingScaleFactor, 100); -+ job_settings->SetBoolean("rasterizePDF", false); -+ -+ job_settings->SetInteger("dpi", settings.dpi()); -+ job_settings->SetInteger("dpiHorizontal", 72); -+ job_settings->SetInteger("dpiVertical", 72); -+ -+ job_settings->SetBoolean(kSettingPrintToPDF, false); -+ job_settings->SetBoolean(kSettingCloudPrintDialog, false); -+ job_settings->SetBoolean(kSettingPrintWithPrivet, false); -+ job_settings->SetBoolean(kSettingPrintWithExtension, false); -+ -+ job_settings->SetBoolean(kSettingShowSystemDialog, false); -+ job_settings->SetInteger(kSettingPreviewPageCount, 1); -+} -+ - void PrintSettingsToJobSettingsDebug(const PrintSettings& settings, - base::DictionaryValue* job_settings) { - job_settings->SetBoolean(kSettingHeaderFooterEnabled, -diff --git a/printing/print_settings_conversion.h b/printing/print_settings_conversion.h -index 283c0ff81954bb9e777b1e0007a735ec0ad4901e..231873a456442856c43d643e41c1bb22f4203a5c 100644 ---- a/printing/print_settings_conversion.h -+++ b/printing/print_settings_conversion.h -@@ -21,6 +21,10 @@ PRINTING_EXPORT bool PrintSettingsFromJobSettings( - const base::DictionaryValue& job_settings, - PrintSettings* print_settings); - -+PRINTING_EXPORT void PrintSettingsToJobSettings( -+ const PrintSettings& settings, -+ base::DictionaryValue* job_settings); -+ - // Use for debug only, because output is not completely consistent with format - // of |PrintSettingsFromJobSettings| input. - void PrintSettingsToJobSettingsDebug(const PrintSettings& settings, diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 8505ded51ff6..52cfcaa0145e 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -1694,43 +1694,6 @@ describe('BrowserWindow module', () => { }) }) - it('can get printer list', (done) => { - w.destroy() - w = new BrowserWindow({ - show: false, - webPreferences: { - sandbox: true, - preload: preload - } - }) - w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E') - w.webContents.once('did-finish-load', () => { - const printers = w.webContents.getPrinters() - assert.strictEqual(Array.isArray(printers), true) - done() - }) - }) - - it('can print to PDF', (done) => { - w.destroy() - w = new BrowserWindow({ - show: false, - webPreferences: { - sandbox: true, - preload: preload - } - }) - w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E') - w.webContents.once('did-finish-load', () => { - w.webContents.printToPDF({}, function (error, data) { - assert.strictEqual(error, null) - assert.strictEqual(data instanceof Buffer, true) - assert.notStrictEqual(data.length, 0) - done() - }) - }) - }) - it('supports calling preventDefault on new-window events', (done) => { w.destroy() w = new BrowserWindow({ diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index 1a9913828fe5..0791d7aea7bb 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -10,6 +10,7 @@ const { emittedOnce } = require('./events-helpers') const chai = require('chai') const dirtyChai = require('dirty-chai') +const features = process.atomBinding('features') const { ipcRenderer, remote, clipboard } = require('electron') const { BrowserWindow, webContents, ipcMain, session } = remote const { expect } = chai @@ -943,4 +944,61 @@ describe('webContents module', () => { done() }) }) + + describe('getPrinterList()', () => { + before(function () { + if (!features.isPrintingEnabled()) { + return closeWindow(w).then(() => { + w = null + this.skip() + }) + } + }) + + it('can get printer list', (done) => { + w.destroy() + w = new BrowserWindow({ + show: false, + webPreferences: { + sandbox: true + } + }) + w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E') + w.webContents.once('did-finish-load', () => { + const printers = w.webContents.getPrinters() + assert.strictEqual(Array.isArray(printers), true) + done() + }) + }) + }) + + describe('printToPDF()', () => { + before(function () { + if (!features.isPrintingEnabled()) { + return closeWindow(w).then(() => { + w = null + this.skip() + }) + } + }) + + it('can print to PDF', (done) => { + w.destroy() + w = new BrowserWindow({ + show: false, + webPreferences: { + sandbox: true + } + }) + w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E') + w.webContents.once('did-finish-load', () => { + w.webContents.printToPDF({}, function (error, data) { + assert.strictEqual(error, null) + assert.strictEqual(data instanceof Buffer, true) + assert.notStrictEqual(data.length, 0) + done() + }) + }) + }) + }) })