electron/patches/chromium/printing.patch
electron-roller[bot] 5d5e672f17
chore: bump chromium to 141.0.7361.0 (main) (#48054)
* chore: bump chromium in DEPS to 141.0.7352.0

* chore: update patches

* 6830573: Revert 'Migrate WrappableWithNamedPropertyInterceptor to gin::Wrappable' | https://chromium-review.googlesource.com/c/chromium/src/+/6830573

* chore: bump chromium in DEPS to 141.0.7354.0

* chore: bump chromium in DEPS to 141.0.7356.0

* chore: bump chromium in DEPS to 141.0.7357.0

* chore: bump chromium in DEPS to 141.0.7359.0

* chore: bump chromium in DEPS to 141.0.7361.0

* 6838518: [Mac] Correctly deallocate sandbox error buffers and prevent crash resulting from nullptr assignment | https://chromium-review.googlesource.com/c/chromium/src/+/6838518

* 6850973: Reland "Use base::ByteCount in base::SysInfo." | https://chromium-review.googlesource.com/c/chromium/src/+/6850973

* 6506565: [FPF-CI] Create initial NoiseHash in the browser. | https://chromium-review.googlesource.com/c/chromium/src/+/6506565

* chore: update patches

* fixup! 6850973: Reland "Use base::ByteCount in base::SysInfo." | https://chromium-review.googlesource.com/c/chromium/src/+/6850973

* fixup! 6506565: [FPF-CI] Create initial NoiseHash in the browser. | https://chromium-review.googlesource.com/c/chromium/src/+/6506565

* fix: unsafe buffer warning in fix_properly_honor_printing_page_ranges.patch

* fix: FTBFS in src_remove_dependency_on_wrapper-descriptor-based_cppheap.patch

This change should be upstreamed.

Fixes this error:

../../third_party/electron_node/src/env.cc:606:3: error: no matching function for call to 'Wrap'
  606 |   v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../v8/include/v8-object.h:1076:14: note: candidate function template not viable: cannot convert argument of incomplete type 'void *' to 'v8::Object::Wrappable *' for 3rd argument
 1076 | void Object::Wrap(v8::Isolate* isolate, const v8::Local<v8::Object>& wrapper,
      |              ^
 1077 |                   v8::Object::Wrappable* wrappable) {
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../v8/include/v8-object.h:1084:14: note: candidate function template not viable: no known conversion from 'Local<Object>' to 'const PersistentBase<Object>' for 2nd argument
 1084 | void Object::Wrap(v8::Isolate* isolate, const PersistentBase<Object>& wrapper,
      |              ^                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../v8/include/v8-object.h:1093:14: note: candidate function template not viable: no known conversion from 'Local<Object>' to 'const BasicTracedReference<Object>' for 2nd argument
 1093 | void Object::Wrap(v8::Isolate* isolate,
      |              ^
 1094 |                   const BasicTracedReference<Object>& wrapper,
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

* [v8-init] Access crash key only from main thread | https://chromium-review.googlesource.com/c/chromium/src/+/6827167

* chore: e patches all

* chore: remove chore_restore_some_deprecated_wrapper_utility_in_gin.patch from patches

this remove line got re-added when rebasing roller/chromium/main

* chore: e patches all

* fix: include base/time/time.h when using base::Time

* chore: update patches

* Make --host-rules an alias for --host-resolver-rules.

Refs https://chromium-review.googlesource.com/c/chromium/src/+/4867872

* ci: update BUILD_TOOLS_SHA

Refs https://github.com/electron/build-tools/pull/746

* [Fontations] Remove Fontations suffix from font names

Refs https://chromium-review.googlesource.com/c/chromium/src/+/6835930

* temp: debug macOS addon build failure

* Revert "temp: debug macOS addon build failure"

This reverts commit 40bc8abab65dc83e17c4ab97cb6e7522a193fb44.

* test: run tests with Xcode 16.4

* ci: fix tccdb update for macOS 15

* spec: disable opening external application for loadURL

on macOS opening unknown external application will bring
up dialog to choose apps from application store which will
break our other test suites that want to capture screen
for pixel matching.

The loadURL spec that tests bad-scheme://foo is sufficient
that we hit the permission handler for openExternal since
at that point we already know the runtime gave up on handling
the scheme.

* chore: rebase patches

* chore: disable codesiging tests

* ci: update ScreenCaptureApprovals.plist for /bin/bash

* ci: try updating tcc permissions

* ci: update TCC permissions

Refs https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive

* chore: test with 1st quadrant of the window

* chore: adjust for macOS 15 menubar height

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2025-08-29 12:31:47 +09:00

940 lines
39 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Fri, 7 Jun 2019 13:59:37 -0700
Subject: printing.patch
Add changeset that was previously applied to sources in chromium_src. The
majority of changes originally come from these PRs:
* https://github.com/electron/electron/pull/1835
* https://github.com/electron/electron/pull/8596
This patch also fixes callback for manual user cancellation and success.
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc
index 6f35d5ab358627ff8b1cbf09f5643f0f484e027a..5e736b846880a7d4a1e1611a0f70feca102bfbbc 100644
--- a/chrome/browser/printing/print_job.cc
+++ b/chrome/browser/printing/print_job.cc
@@ -97,6 +97,7 @@ bool PrintWithReducedRasterization(PrefService* prefs) {
return base::FeatureList::IsEnabled(features::kPrintWithReducedRasterization);
}
+#if 0
PrefService* GetPrefsForWebContents(content::WebContents* web_contents) {
// TODO(thestig): Figure out why crbug.com/1083911 occurred, which is likely
// because `web_contents` was null. As a result, this section has many more
@@ -111,6 +112,7 @@ content::WebContents* GetWebContents(content::GlobalRenderFrameHostId rfh_id) {
auto* rfh = content::RenderFrameHost::FromID(rfh_id);
return rfh ? content::WebContents::FromRenderFrameHost(rfh) : nullptr;
}
+#endif
#endif // BUILDFLAG(IS_WIN)
@@ -151,10 +153,8 @@ void PrintJob::Initialize(std::unique_ptr<PrinterQuery> query,
#if BUILDFLAG(IS_WIN)
pdf_page_mapping_ = PageNumber::GetPages(settings->ranges(), page_count);
- PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
- if (prefs && prefs->IsManagedPreference(prefs::kPdfUseSkiaRendererEnabled)) {
- use_skia_ = prefs->GetBoolean(prefs::kPdfUseSkiaRendererEnabled);
- }
+ // TODO(codebytere): should we enable this later?
+ use_skia_ = false;
#endif
auto new_doc = base::MakeRefCounted<PrintedDocument>(std::move(settings),
@@ -404,8 +404,10 @@ void PrintJob::StartPdfToEmfConversion(
const PrintSettings& settings = document()->settings();
+#if 0
PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
- bool print_with_reduced_rasterization = PrintWithReducedRasterization(prefs);
+#endif
+ bool print_with_reduced_rasterization = PrintWithReducedRasterization(nullptr);
using RenderMode = PdfRenderSettings::Mode;
RenderMode mode = print_with_reduced_rasterization
@@ -497,8 +499,10 @@ void PrintJob::StartPdfToPostScriptConversion(
if (ps_level2) {
mode = PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2;
} else {
+#if 0
PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
- mode = PrintWithPostScriptType42Fonts(prefs)
+#endif
+ mode = PrintWithPostScriptType42Fonts(nullptr)
? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS
: PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
}
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 57d09902647c4f257728589e494f71793121f015..c6b544eb72b11baca99770b6b98566b4ab7adc5d 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -80,6 +80,20 @@ namespace printing {
namespace {
+std::string PrintReasonFromPrintStatus(PrintViewManager::PrintStatus status) {
+ if (status == PrintViewManager::PrintStatus::kInvalid) {
+ return "Invalid printer settings";
+ } else if (status == PrintViewManager::PrintStatus::kCanceled) {
+ return "Print job canceled";
+ } else if (status == PrintViewManager::PrintStatus::kFailed) {
+ return "Print job failed";
+ }
+ return "";
+}
+
+using PrintSettingsCallback =
+ base::OnceCallback<void(std::unique_ptr<PrinterQuery>)>;
+
void OnDidGetDefaultPrintSettings(
scoped_refptr<PrintQueriesQueue> queue,
bool want_pdf_settings,
@@ -88,9 +102,9 @@ void OnDidGetDefaultPrintSettings(
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (printer_query->last_status() != mojom::ResultCode::kSuccess) {
- if (!want_pdf_settings) {
+#if 0 // Electron does not use Chromium error dialogs
ShowPrintErrorDialogForInvalidPrinterError();
- }
+#endif
std::move(callback).Run(nullptr);
return;
}
@@ -100,9 +114,9 @@ void OnDidGetDefaultPrintSettings(
params->document_cookie = printer_query->cookie();
if (!PrintMsgPrintParamsIsValid(*params)) {
- if (!want_pdf_settings) {
+#if 0 // Electron does not use Chromium error dialogs
ShowPrintErrorDialogForInvalidPrinterError();
- }
+#endif
std::move(callback).Run(nullptr);
return;
}
@@ -114,14 +128,14 @@ void OnDidGetDefaultPrintSettings(
void OnDidScriptedPrint(
scoped_refptr<PrintQueriesQueue> queue,
std::unique_ptr<PrinterQuery> printer_query,
- mojom::PrintManagerHost::ScriptedPrintCallback callback) {
+ mojom::PrintManagerHost::ScriptedPrintCallback callback,
+ base::OnceCallback<void()> cancel_job) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (printer_query->last_status() != mojom::ResultCode::kSuccess ||
!printer_query->settings().dpi()) {
- // Notify user of the error, unless it was explicitly canceled.
- if (printer_query->last_status() != mojom::ResultCode::kCanceled) {
- ShowPrintErrorDialogForGenericError();
+ if (printer_query->last_status() == mojom::ResultCode::kCanceled) {
+ std::move(cancel_job).Run();
}
std::move(callback).Run(nullptr);
return;
@@ -175,9 +189,11 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
: PrintManager(web_contents),
queue_(g_browser_process->print_job_manager()->queue()) {
DCHECK(queue_);
+#if 0
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
printing_enabled_.Init(prefs::kPrintingEnabled, profile->GetPrefs());
+#endif
}
PrintViewManagerBase::~PrintViewManagerBase() {
@@ -185,12 +201,16 @@ PrintViewManagerBase::~PrintViewManagerBase() {
DisconnectFromCurrentPrintJob();
}
-bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
+bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
+ base::Value::Dict settings,
+ CompletionCallback callback) {
if (!StartPrintCommon(rfh)) {
return false;
}
- GetPrintRenderFrame(rfh)->PrintRequestedPages();
+ callback_ = std::move(callback);
+
+ GetPrintRenderFrame(rfh)->PrintRequestedPages(std::move(settings));
for (auto& observer : GetTestObservers()) {
observer.OnPrintNow(rfh);
@@ -272,7 +292,7 @@ void PrintViewManagerBase::PrintDocument(
const gfx::Size& page_size,
const gfx::Rect& content_area,
const gfx::Point& offsets) {
-#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
+#if 0
if (content_analysis_before_printing_document_) {
std::move(content_analysis_before_printing_document_)
.Run(print_data, page_size, content_area, offsets);
@@ -319,12 +339,13 @@ void PrintViewManagerBase::OnDidUpdatePrintableArea(
}
PRINTER_LOG(EVENT) << "Paper printable area updated for vendor id "
<< print_settings->requested_media().vendor_id;
- CompleteUpdatePrintSettings(std::move(job_settings),
+ CompleteUpdatePrintSettings(nullptr /* printer_query */, std::move(job_settings),
std::move(print_settings), std::move(callback));
}
#endif
void PrintViewManagerBase::CompleteUpdatePrintSettings(
+ std::unique_ptr<PrinterQuery> printer_query,
base::Value::Dict job_settings,
std::unique_ptr<PrintSettings> print_settings,
UpdatePrintSettingsCallback callback) {
@@ -332,7 +353,8 @@ void PrintViewManagerBase::CompleteUpdatePrintSettings(
settings->pages = GetPageRangesFromJobSettings(job_settings);
settings->params = mojom::PrintParams::New();
RenderParamsFromPrintSettings(*print_settings, settings->params.get());
- settings->params->document_cookie = PrintSettings::NewCookie();
+ settings->params->document_cookie = printer_query ? printer_query->cookie()
+ : PrintSettings::NewCookie();
if (!PrintMsgPrintParamsIsValid(*settings->params)) {
mojom::PrinterType printer_type = static_cast<mojom::PrinterType>(
*job_settings.FindInt(kSettingPrinterType));
@@ -344,6 +366,10 @@ void PrintViewManagerBase::CompleteUpdatePrintSettings(
return;
}
+ if (printer_query && printer_query->cookie() && printer_query->settings().dpi()) {
+ queue_->QueuePrinterQuery(std::move(printer_query));
+ }
+
set_cookie(settings->params->document_cookie);
std::move(callback).Run(std::move(settings));
}
@@ -385,7 +411,9 @@ void PrintViewManagerBase::OnPrintSettingsDone(
UnregisterSystemPrintClient();
}
#endif
+#if 0 // Electron does not use Chromium error dialogs
ShowPrintErrorDialogForGenericError();
+#endif
std::move(callback).Run(base::Value("Update settings failed"));
return;
}
@@ -414,7 +442,7 @@ void PrintViewManagerBase::StartLocalPrintJob(
PrinterHandler::PrintCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
+#if 0
// Populating `content_analysis_before_printing_document_` if needed should be
// done first in this function's workflow, this way other code can check if
// content analysis is going to happen and delay starting `print_job_` to
@@ -640,7 +668,7 @@ void PrintViewManagerBase::GetDefaultPrintSettings(
#if BUILDFLAG(ENABLE_OOP_PRINTING)
if (ShouldPrintJobOop() &&
-#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
+#if 0
!analyzing_content_ &&
#endif
!query_with_ui_client_id().has_value()) {
@@ -668,7 +696,7 @@ void PrintViewManagerBase::GetDefaultPrintSettings(
// Sometimes it is desired to get the PDF settings as opposed to the settings
// of the default system print driver.
-#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
+#if 0
bool want_pdf_settings = analyzing_content_;
#else
bool want_pdf_settings = false;
@@ -712,10 +740,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
// `job_settings` does not yet contain the rasterized PDF dpi, so if the user
// has the print preference set, fetch it for use in
// `PrintSettingsFromJobSettings()`.
- content::BrowserContext* context =
- web_contents() ? web_contents()->GetBrowserContext() : nullptr;
- PrefService* prefs =
- context ? Profile::FromBrowserContext(context)->GetPrefs() : nullptr;
+ PrefService* prefs = nullptr;
if (prefs && prefs->HasPrefPath(prefs::kPrintRasterizePdfDpi)) {
int value = prefs->GetInteger(prefs::kPrintRasterizePdfDpi);
if (value > 0)
@@ -740,8 +765,22 @@ void PrintViewManagerBase::UpdatePrintSettings(
}
}
-#if BUILDFLAG(IS_WIN)
- // TODO(crbug.com/40260379): Remove this if the printable areas can be made
+ std::unique_ptr<PrinterQuery> query =
+ queue_->CreatePrinterQuery(GetCurrentTargetFrame()->GetGlobalId());
+ auto* query_ptr = query.get();
+ // We need to clone this before calling SetSettings because some environments
+ // evaluate job_settings.Clone() first, and some std::move(job_settings) first,
+ // for the former things work correctly but for the latter the cloned value is null.
+ auto job_settings_copy = job_settings.Clone();
+ query_ptr->SetSettings(
+ std::move(job_settings_copy),
+ base::BindOnce(&PrintViewManagerBase::CompleteUpdatePrintSettings,
+ weak_ptr_factory_.GetWeakPtr(), std::move(query),
+ std::move(job_settings), std::move(print_settings),
+ std::move(callback)));
+
+#if 0 // See https://chromium-review.googlesource.com/412367
+ // TODO(crbug.com/1424368): Remove this if the printable areas can be made
// fully available from `PrintBackend::GetPrinterSemanticCapsAndDefaults()`
// for in-browser queries.
if (printer_type == mojom::PrinterType::kLocal) {
@@ -762,8 +801,6 @@ void PrintViewManagerBase::UpdatePrintSettings(
}
#endif
- CompleteUpdatePrintSettings(std::move(job_settings),
- std::move(print_settings), std::move(callback));
}
void PrintViewManagerBase::SetAccessibilityTree(
@@ -779,7 +816,7 @@ void PrintViewManagerBase::SetAccessibilityTree(
void PrintViewManagerBase::IsPrintingEnabled(
IsPrintingEnabledCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- std::move(callback).Run(GetPrintingEnabledBooleanPref());
+ std::move(callback).Run(true);
}
void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
@@ -805,7 +842,7 @@ void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
return;
}
#endif
-#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
+#if 0
std::optional<enterprise_connectors::ContentAnalysisDelegate::Data>
scanning_data = enterprise_data_protection::GetPrintAnalysisData(
web_contents(), enterprise_data_protection::PrintScanningContext::
@@ -835,11 +872,9 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie,
// destroyed. In such cases the error notification to the user will
// have already been displayed, and a second message should not be
// shown.
- if (print_job_ && print_job_->document() &&
- print_job_->document()->cookie() == cookie) {
+#if 0 // Electron does not use Chromium error dialogs
ShowPrintErrorDialogForGenericError();
- }
-
+#endif
ReleasePrinterQuery();
}
@@ -851,15 +886,24 @@ void PrintViewManagerBase::RemoveTestObserver(TestObserver& observer) {
test_observers_.RemoveObserver(&observer);
}
+void PrintViewManagerBase::ShowInvalidPrinterSettingsError() {
+ if (!callback_.is_null()) {
+ printing_status_ = PrintStatus::kInvalid;
+ TerminatePrintJob(true);
+ }
+}
+
void PrintViewManagerBase::RenderFrameHostStateChanged(
content::RenderFrameHost* render_frame_host,
content::RenderFrameHost::LifecycleState /*old_state*/,
content::RenderFrameHost::LifecycleState new_state) {
+#if 0
if (new_state == content::RenderFrameHost::LifecycleState::kActive &&
render_frame_host->GetProcess()->IsPdf() &&
!render_frame_host->GetMainFrame()->GetParentOrOuterDocument()) {
GetPrintRenderFrame(render_frame_host)->ConnectToPdfRenderer();
}
+#endif
}
void PrintViewManagerBase::RenderFrameDeleted(
@@ -901,13 +945,14 @@ void PrintViewManagerBase::SystemDialogCancelled() {
// System dialog was cancelled. Clean up the print job and notify the
// BackgroundPrintingManager.
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ printing_status_ = PrintStatus::kCanceled;
ReleasePrinterQuery();
TerminatePrintJob(true);
}
#endif
bool PrintViewManagerBase::GetPrintingEnabledBooleanPref() const {
- return printing_enabled_.GetValue();
+ return true;
}
void PrintViewManagerBase::OnDocDone(int job_id, PrintedDocument* document) {
@@ -921,18 +966,26 @@ void PrintViewManagerBase::OnJobDone() {
// Printing is done, we don't need it anymore.
// print_job_->is_job_pending() may still be true, depending on the order
// of object registration.
- printing_succeeded_ = true;
+ printing_status_ = PrintStatus::kSucceeded;
+ ReleasePrintJob();
+}
+
+void PrintViewManagerBase::UserInitCanceled() {
+ printing_status_ = PrintStatus::kCanceled;
ReleasePrintJob();
}
void PrintViewManagerBase::OnCanceling() {
+ printing_status_ = PrintStatus::kCanceled;
canceling_job_ = true;
}
void PrintViewManagerBase::OnFailed() {
if (!canceling_job_)
+ printing_status_ = PrintStatus::kFailed;
+#if 0 // Electron does not use Chromium error dialogs
ShowPrintErrorDialogForGenericError();
-
+#endif
TerminatePrintJob(true);
}
@@ -942,7 +995,7 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
// Is the document already complete?
if (print_job_->document() && print_job_->document()->IsComplete()) {
- printing_succeeded_ = true;
+ printing_status_ = PrintStatus::kSucceeded;
return true;
}
@@ -995,7 +1048,10 @@ bool PrintViewManagerBase::SetupNewPrintJob(
// Disconnect the current `print_job_`.
auto weak_this = weak_ptr_factory_.GetWeakPtr();
- DisconnectFromCurrentPrintJob();
+ if (callback_.is_null()) {
+ // Disconnect the current |print_job_| only when calling window.print()
+ DisconnectFromCurrentPrintJob();
+ }
if (!weak_this)
return false;
@@ -1015,7 +1071,7 @@ bool PrintViewManagerBase::SetupNewPrintJob(
#endif
print_job_->AddObserver(*this);
- printing_succeeded_ = false;
+ printing_status_ = PrintStatus::kUnknown;
return true;
}
@@ -1073,7 +1129,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
// Ensure that any residual registration of printing client is released.
// This might be necessary in some abnormal cases, such as the associated
// render process having terminated.
-#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
+#if 0
if (!analyzing_content_) {
UnregisterSystemPrintClient();
}
@@ -1083,6 +1139,11 @@ void PrintViewManagerBase::ReleasePrintJob() {
}
#endif
+ if (!callback_.is_null()) {
+ bool success = printing_status_ == PrintStatus::kSucceeded;
+ std::move(callback_).Run(success, PrintReasonFromPrintStatus(printing_status_));
+ }
+
if (!print_job_)
return;
@@ -1090,7 +1151,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
// printing_rfh_ should only ever point to a RenderFrameHost with a live
// RenderFrame.
DCHECK(rfh->IsRenderFrameLive());
- GetPrintRenderFrame(rfh)->PrintingDone(printing_succeeded_);
+ GetPrintRenderFrame(rfh)->PrintingDone(printing_status_ == PrintStatus::kSucceeded);
}
print_job_->RemoveObserver(*this);
@@ -1132,7 +1193,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
}
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
- if (print_job_)
+ if (print_job_ && print_job_->document())
return true;
if (!cookie) {
@@ -1155,7 +1216,7 @@ bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
return false;
}
-#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
+#if 0
// Don't start printing if enterprise checks are being performed to check if
// printing is allowed, or if content analysis is going to take place right
// before starting `print_job_`.
@@ -1286,6 +1347,8 @@ void PrintViewManagerBase::CompleteScriptedPrint(
auto callback_wrapper = base::BindOnce(
&PrintViewManagerBase::ScriptedPrintReply, weak_ptr_factory_.GetWeakPtr(),
std::move(callback), render_process_host->GetDeprecatedID());
+ auto cancel_job_wrapper = base::BindOnce(
+ &PrintViewManagerBase::UserInitCanceled, weak_ptr_factory_.GetWeakPtr());
std::unique_ptr<PrinterQuery> printer_query =
queue()->PopPrinterQuery(params->cookie);
if (!printer_query)
@@ -1296,10 +1359,10 @@ void PrintViewManagerBase::CompleteScriptedPrint(
params->expected_pages_count, params->has_selection, params->margin_type,
params->is_scripted, !render_process_host->IsPdf(),
base::BindOnce(&OnDidScriptedPrint, queue_, std::move(printer_query),
- std::move(callback_wrapper)));
+ std::move(callback_wrapper), std::move(cancel_job_wrapper)));
}
-#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
+#if 0
void PrintViewManagerBase::CompletePrintDocumentAfterContentAnalysis(
scoped_refptr<base::RefCountedMemory> print_data,
const gfx::Size& page_size,
diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h
index 824d6d8a9242302c2ab0c0c517d0cc329e607100..d3b25c90c90fe860990789aa96c872b45132720b 100644
--- a/chrome/browser/printing/print_view_manager_base.h
+++ b/chrome/browser/printing/print_view_manager_base.h
@@ -46,6 +46,8 @@ namespace printing {
class PrintQueriesQueue;
class PrinterQuery;
+using CompletionCallback = base::OnceCallback<void(bool, const std::string&)>;
+
// Base class for managing the print commands for a WebContents.
class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
public:
@@ -76,7 +78,9 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
// 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,
+ base::Value::Dict settings = {},
+ CompletionCallback callback = {});
// Like PrintNow(), but for the node under the context menu, instead of the
// entire frame.
@@ -130,8 +134,10 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
void IsPrintingEnabled(IsPrintingEnabledCallback callback) override;
void ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
ScriptedPrintCallback callback) override;
+ void ShowInvalidPrinterSettingsError() override;
void PrintingFailed(int32_t cookie,
mojom::PrintFailureReason reason) override;
+ void UserInitCanceled();
// Adds and removes observers for `PrintViewManagerBase` events. The order in
// which notifications are sent to observers is undefined. Observers must be
@@ -139,6 +145,14 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
void AddTestObserver(TestObserver& observer);
void RemoveTestObserver(TestObserver& observer);
+ enum class PrintStatus {
+ kSucceeded,
+ kCanceled,
+ kFailed,
+ kInvalid,
+ kUnknown
+ };
+
protected:
#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
using PrintDocumentCallback =
@@ -218,7 +232,7 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
mojom::ScriptedPrintParamsPtr params,
ScriptedPrintCallback callback);
-#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
+#if 0
// Helper method bound to `content_analysis_before_printing_document_` when
// content analysis should happen right before the document is to be printed.
// This method is virtual for testing purposes.
@@ -282,6 +296,7 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
bool success);
#endif
void CompleteUpdatePrintSettings(
+ std::unique_ptr<PrinterQuery> printer_query,
base::Value::Dict job_settings,
std::unique_ptr<PrintSettings> print_settings,
UpdatePrintSettingsCallback callback);
@@ -376,8 +391,11 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
// The current RFH that is printing with a system printing dialog.
raw_ptr<content::RenderFrameHost> printing_rfh_ = nullptr;
+ // Respond with success of the print job.
+ CompletionCallback callback_;
+
// Indication of success of the print job.
- bool printing_succeeded_ = false;
+ PrintStatus printing_status_ = PrintStatus::kUnknown;
// Indication that the job is getting canceled.
bool canceling_job_ = false;
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc
index 4b1775f4a882fbabfe65df7784baebe6d8bee788..5a3e71dc3894fa96ac7a6b93b3552a90f36fe7a2 100644
--- a/chrome/browser/printing/printer_query.cc
+++ b/chrome/browser/printing/printer_query.cc
@@ -356,17 +356,19 @@ void PrinterQuery::UpdatePrintSettings(base::Value::Dict new_settings,
#endif // BUILDFLAG(IS_LINUX) && BUILDFLAG(USE_CUPS)
}
- mojom::ResultCode result;
{
#if BUILDFLAG(IS_WIN)
// Blocking is needed here because Windows printer drivers are oftentimes
// not thread-safe and have to be accessed on the UI thread.
base::ScopedAllowBlocking allow_blocking;
#endif
- result = printing_context_->UpdatePrintSettings(std::move(new_settings));
+ // Reset settings from previous print job
+ printing_context_->ResetSettings();
+ mojom::ResultCode result_code = printing_context_->UseDefaultSettings();
+ if (result_code == mojom::ResultCode::kSuccess)
+ result_code = printing_context_->UpdatePrintSettings(std::move(new_settings));
+ InvokeSettingsCallback(std::move(callback), result_code);
}
-
- InvokeSettingsCallback(std::move(callback), result);
}
#if BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/printing/printer_query_oop.cc b/chrome/browser/printing/printer_query_oop.cc
index 68465045179c9bbe747679509453d8a802176568..eac20bd0ab74891ad9f38d43ee5b6ca51b5cff48 100644
--- a/chrome/browser/printing/printer_query_oop.cc
+++ b/chrome/browser/printing/printer_query_oop.cc
@@ -128,7 +128,7 @@ void PrinterQueryOop::OnDidAskUserForSettings(
std::unique_ptr<PrintSettings> new_settings,
mojom::ResultCode result) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (result == mojom::ResultCode::kSuccess) {
+ if (result == mojom::ResultCode::kSuccess && query_with_ui_client_id_) {
// Want the same PrintBackend service as the query so that we use the same
// device context.
print_document_client_id_ =
diff --git a/components/printing/browser/print_manager.cc b/components/printing/browser/print_manager.cc
index 21c81377d32ae8d4185598a7eba88ed1d2063ef0..0767f4e9369e926b1cea99178c1a1975941f1765 100644
--- a/components/printing/browser/print_manager.cc
+++ b/components/printing/browser/print_manager.cc
@@ -47,6 +47,8 @@ void PrintManager::IsPrintingEnabled(IsPrintingEnabledCallback callback) {
std::move(callback).Run(true);
}
+void PrintManager::ShowInvalidPrinterSettingsError() {}
+
void PrintManager::PrintingFailed(int32_t cookie,
mojom::PrintFailureReason reason) {
// Note: Not redundant with cookie checks in the same method in other parts of
diff --git a/components/printing/browser/print_manager.h b/components/printing/browser/print_manager.h
index ca71560874a0189068dd11fbc039f5673bf6bd96..a8551d95e64da2afbc1685b2df8f1fc377c7117b 100644
--- a/components/printing/browser/print_manager.h
+++ b/components/printing/browser/print_manager.h
@@ -48,6 +48,7 @@ class PrintManager : public content::WebContentsObserver,
DidPrintDocumentCallback callback) override;
void IsPrintingEnabled(IsPrintingEnabledCallback callback) override;
void DidShowPrintDialog() override;
+ void ShowInvalidPrinterSettingsError() override;
void PrintingFailed(int32_t cookie,
mojom::PrintFailureReason reason) override;
diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom
index ac2f719be566020d9f41364560c12e6d6d0fe3d8..16d758a6936f66148a196761cfb875f68c1818d7 100644
--- a/components/printing/common/print.mojom
+++ b/components/printing/common/print.mojom
@@ -299,7 +299,7 @@ enum PrintFailureReason {
interface PrintRenderFrame {
// Tells the RenderFrame to switch the CSS to print media type, render every
// requested page, and then switch back the CSS to display media type.
- PrintRequestedPages();
+ PrintRequestedPages(mojo_base.mojom.DictionaryValue settings);
// Requests the frame to be printed with specified parameters. This is used
// to programmatically produce PDF by request from the browser (e.g. over
@@ -388,6 +388,9 @@ interface PrintManagerHost {
[Sync]
ScriptedPrint(ScriptedPrintParams params) => (PrintPagesParams? settings);
+ // Tells the browser that there are invalid printer settings.
+ ShowInvalidPrinterSettingsError();
+
// Tells the browser printing failed.
PrintingFailed(int32 cookie, PrintFailureReason reason);
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index d7555d8c33ca05525454eb6583b4b37a4bcae558..ebddc2487818388675cc14c789b8b67e62cb2cc4 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -53,6 +53,7 @@
#include "printing/mojom/print.mojom.h"
#include "printing/page_number.h"
#include "printing/print_job_constants.h"
+#include "printing/print_settings.h"
#include "printing/units.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
@@ -1246,14 +1247,14 @@ void PrintRenderFrameHelper::ScriptedPrint(bool user_initiated) {
}
print_in_progress_ = true;
-
auto weak_this = weak_ptr_factory_.GetWeakPtr();
web_frame->DispatchBeforePrintEvent(/*print_client=*/nullptr);
if (!weak_this) {
return;
}
- Print(web_frame, blink::WebNode(), PrintRequestType::kScripted);
+ Print(web_frame, blink::WebNode(), PrintRequestType::kScripted,
+ base::Value::Dict());
if (!weak_this) {
return;
}
@@ -1284,12 +1285,14 @@ void PrintRenderFrameHelper::BindPrintRenderFrameReceiver(
receivers_.Add(this, std::move(receiver));
}
-void PrintRenderFrameHelper::PrintRequestedPages() {
- PrintRequestedPagesInternal(/*already_notified_frame=*/false);
+void PrintRenderFrameHelper::PrintRequestedPages(base::Value::Dict settings) {
+ PrintRequestedPagesInternal(/*already_notified_frame=*/false,
+ std::move(settings));
}
void PrintRenderFrameHelper::PrintRequestedPagesInternal(
- bool already_notified_frame) {
+ bool already_notified_frame,
+ base::Value::Dict settings) {
ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
if (ipc_nesting_level_ > kAllowedIpcDepthForPrint) {
return;
@@ -1306,9 +1309,10 @@ void PrintRenderFrameHelper::PrintRequestedPagesInternal(
is_loading_ = frame->WillPrintSoon();
if (is_loading_) {
- on_stop_loading_closure_ = base::BindOnce(
- &PrintRenderFrameHelper::PrintRequestedPagesInternal,
- weak_ptr_factory_.GetWeakPtr(), /*already_notified_frame=*/true);
+ on_stop_loading_closure_ =
+ base::BindOnce(&PrintRenderFrameHelper::PrintRequestedPagesInternal,
+ weak_ptr_factory_.GetWeakPtr(),
+ /*already_notified_frame=*/true, std::move(settings));
SetupOnStopLoadingTimeout();
return;
}
@@ -1318,7 +1322,7 @@ void PrintRenderFrameHelper::PrintRequestedPagesInternal(
// plugin node and print that instead.
auto plugin = delegate_->GetPdfElement(frame);
- Print(frame, plugin, PrintRequestType::kRegular);
+ Print(frame, plugin, PrintRequestType::kRegular, std::move(settings));
if (render_frame_gone_) {
return;
@@ -1474,6 +1478,8 @@ void PrintRenderFrameHelper::PrintPreview(base::Value::Dict settings) {
if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
return;
+ blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
+ print_preview_context_.InitWithFrame(frame);
print_preview_context_.OnPrintPreview();
#if BUILDFLAG(IS_CHROMEOS)
@@ -2086,17 +2092,25 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
const blink::WebNode& node,
- PrintRequestType print_request_type) {
+ PrintRequestType print_request_type,
+ base::Value::Dict settings) {
// If still not finished with earlier print request simply ignore.
if (prep_frame_view_)
return;
+ bool silent = settings.FindBool("silent").value_or(false);
FrameReference frame_ref(frame);
- if (!InitPrintSettings(frame, node)) {
+ // If we're silently printing a PDF, we bypass settings logic
+ // that sets modifiability to false so ensure it's set here.
+ if (silent && IsPrintingPdfFrame(frame, node)) {
+ settings.Set(kSettingPreviewModifiable, false);
+ }
+
+ if (!InitPrintSettings(frame, node, std::move(settings))) {
// Browser triggered this code path. It already knows about the failure.
notify_browser_of_print_failure_ = false;
-
+ GetPrintManagerHost()->ShowInvalidPrinterSettingsError();
DidFinishPrinting(PrintingResult::kFailPrintInit);
return;
}
@@ -2117,8 +2131,15 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
print_pages_params_->params->print_scaling_option;
auto self = weak_ptr_factory_.GetWeakPtr();
- mojom::PrintPagesParamsPtr print_settings = GetPrintSettingsFromUser(
+ mojom::PrintPagesParamsPtr print_settings;
+
+ if (silent) {
+ print_settings = mojom::PrintPagesParams::New();
+ print_settings->params = print_pages_params_->params->Clone();
+ } else {
+ print_settings = GetPrintSettingsFromUser(
frame_ref.GetFrame(), node, expected_page_count, print_request_type);
+ }
// Check if `this` is still valid.
if (!self)
return;
@@ -2385,29 +2406,43 @@ void PrintRenderFrameHelper::IPCProcessed() {
}
bool PrintRenderFrameHelper::InitPrintSettings(blink::WebLocalFrame* frame,
- const blink::WebNode& node) {
+ const blink::WebNode& node,
+ base::Value::Dict new_settings) {
// Reset to default values.
ignore_css_margins_ = false;
- mojom::PrintPagesParams settings;
- GetPrintManagerHost()->GetDefaultPrintSettings(&settings.params);
+ mojom::PrintPagesParamsPtr settings;
+ if (new_settings.empty()) {
+ settings = mojom::PrintPagesParams::New();
+ settings->params = mojom::PrintParams::New();
+ GetPrintManagerHost()->GetDefaultPrintSettings(&settings->params);
+ } else {
+ GetPrintManagerHost()->UpdatePrintSettings(
+ std::move(new_settings), &settings);
+ }
// Check if the printer returned any settings, if the settings are null,
// assume there are no printer drivers configured. So safely terminate.
- if (!settings.params) {
+ if (!settings || !settings->params) {
// Caller will reset `print_pages_params_`.
return false;
}
bool center_on_paper = !IsPrintingPdfFrame(frame, node);
- settings.params->print_scaling_option =
- center_on_paper ? mojom::PrintScalingOption::kCenterShrinkToFitPaper
- : mojom::PrintScalingOption::kSourceSize;
- RecordDebugEvent(settings.params->printed_doc_type ==
+ bool silent = new_settings.FindBool("silent").value_or(false);
+ if (silent) {
+ settings->params->print_scaling_option = mojom::PrintScalingOption::kFitToPrintableArea;
+ } else {
+ settings->params->print_scaling_option =
+ center_on_paper ? mojom::PrintScalingOption::kCenterShrinkToFitPaper
+ : mojom::PrintScalingOption::kSourceSize;
+ }
+
+ RecordDebugEvent(settings->params->printed_doc_type ==
mojom::SkiaDocumentType::kMSKP
? DebugEvent::kSetPrintSettings5
: DebugEvent::kSetPrintSettings6);
- SetPrintPagesParams(settings);
+ SetPrintPagesParams(*settings);
return true;
}
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
index 97cb6458bc9eec767db89b56abfc5f4b4136ff7b..d9a0b343158b8464b5c9aa8e0e655c0b6fb28b00 100644
--- a/components/printing/renderer/print_render_frame_helper.h
+++ b/components/printing/renderer/print_render_frame_helper.h
@@ -258,7 +258,7 @@ class PrintRenderFrameHelper
mojo::PendingAssociatedReceiver<mojom::PrintRenderFrame> receiver);
// printing::mojom::PrintRenderFrame:
- void PrintRequestedPages() override;
+ void PrintRequestedPages(base::Value::Dict settings) override;
void PrintWithParams(mojom::PrintPagesParamsPtr params,
PrintWithParamsCallback callback) override;
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
@@ -325,7 +325,8 @@ class PrintRenderFrameHelper
// WARNING: |this| may be gone after this method returns.
void Print(blink::WebLocalFrame* frame,
const blink::WebNode& node,
- PrintRequestType print_request_type);
+ PrintRequestType print_request_type,
+ base::Value::Dict settings = {});
// Notification when printing is done - signal tear-down/free resources.
void DidFinishPrinting(PrintingResult result);
@@ -335,7 +336,8 @@ class PrintRenderFrameHelper
// Initialize print page settings with default settings.
// Used only for native printing workflow.
bool InitPrintSettings(blink::WebLocalFrame* frame,
- const blink::WebNode& node);
+ const blink::WebNode& node,
+ base::Value::Dict new_settings);
// Calculate number of pages in source document.
uint32_t CalculateNumberOfPages(blink::WebLocalFrame* frame,
@@ -637,7 +639,8 @@ class PrintRenderFrameHelper
};
void SetupOnStopLoadingTimeout();
- void PrintRequestedPagesInternal(bool already_notified_frame);
+ void PrintRequestedPagesInternal(bool already_notified_frame,
+ base::Value::Dict settings);
ScriptingThrottler scripting_throttler_;
diff --git a/printing/printing_context.cc b/printing/printing_context.cc
index 746a056e1c7980803323739c51cedb930c62de25..34a9e45a3407612d6960a7cad798cf30989f065e 100644
--- a/printing/printing_context.cc
+++ b/printing/printing_context.cc
@@ -157,7 +157,6 @@ void PrintingContext::UsePdfSettings() {
mojom::ResultCode PrintingContext::UpdatePrintSettings(
base::Value::Dict job_settings) {
- ResetSettings();
{
std::unique_ptr<PrintSettings> settings =
PrintSettingsFromJobSettings(job_settings);
diff --git a/printing/printing_context.h b/printing/printing_context.h
index 3a98838e27621e34ab050a0f5dce7110f0d88641..3cce0abe2a2893f1ad5ee747008b66c74e2c2434 100644
--- a/printing/printing_context.h
+++ b/printing/printing_context.h
@@ -208,6 +208,9 @@ class COMPONENT_EXPORT(PRINTING) PrintingContext {
bool PrintingAborted() const { return abort_printing_; }
+ // Reinitializes the settings for object reuse.
+ void ResetSettings();
+
int job_id() const { return job_id_; }
#if BUILDFLAG(ENABLE_OOP_PRINTING)
@@ -227,9 +230,6 @@ class COMPONENT_EXPORT(PRINTING) PrintingContext {
Delegate* delegate,
OutOfProcessBehavior out_of_process_behavior);
- // Reinitializes the settings for object reuse.
- void ResetSettings();
-
// Does bookkeeping when an error occurs.
virtual mojom::ResultCode OnError();
diff --git a/printing/printing_context_linux.cc b/printing/printing_context_linux.cc
index 1bf52330b555e14cf32c356321bef36442fab3d5..ee7ab77226a2aaf8f4250188a15af63dde70bce0 100644
--- a/printing/printing_context_linux.cc
+++ b/printing/printing_context_linux.cc
@@ -55,9 +55,8 @@ void PrintingContextLinux::AskUserForSettings(int max_pages,
bool is_scripted,
PrintSettingsCallback callback) {
if (!print_dialog_) {
- // Can only get here if the renderer is sending bad messages.
- // http://crbug.com/341777
- NOTREACHED();
+ print_dialog_ = ui::LinuxUi::instance()->CreatePrintDialog(this);
+ print_dialog_->UseDefaultSettings();
}
print_dialog_->ShowDialog(delegate_->GetParentView(), has_selection,