printing.patch 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Shelley Vohr <[email protected]>
  3. Date: Fri, 7 Jun 2019 13:59:37 -0700
  4. Subject: printing.patch
  5. Add changeset that was previously applied to sources in chromium_src. The
  6. majority of changes originally come from these PRs:
  7. * https://github.com/electron/electron/pull/1835
  8. * https://github.com/electron/electron/pull/8596
  9. This patch also fixes callback for manual user cancellation and success.
  10. diff --git a/BUILD.gn b/BUILD.gn
  11. index 4b37258f1bbba1d37e414ea7ec9a93cbd7a1efc4..4667f496f093cb7df71c5e5756fc61bb06053a8b 100644
  12. --- a/BUILD.gn
  13. +++ b/BUILD.gn
  14. @@ -973,7 +973,6 @@ if (is_win) {
  15. "//media:media_unittests",
  16. "//media/midi:midi_unittests",
  17. "//net:net_unittests",
  18. - "//printing:printing_unittests",
  19. "//sql:sql_unittests",
  20. "//third_party/breakpad:symupload($host_toolchain)",
  21. "//ui/base:ui_base_unittests",
  22. @@ -982,6 +981,10 @@ if (is_win) {
  23. "//ui/views:views_unittests",
  24. "//url:url_unittests",
  25. ]
  26. +
  27. + if (enable_printing) {
  28. + deps += [ "//printing:printing_unittests" ]
  29. + }
  30. }
  31. }
  32. diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc
  33. index 0d8a53178e8d509a573ffdaadf2c4cec670522ac..8e7f9b92beb317888a5a3acb3bc2fa29f283ff03 100644
  34. --- a/chrome/browser/printing/print_job.cc
  35. +++ b/chrome/browser/printing/print_job.cc
  36. @@ -96,6 +96,7 @@ bool PrintWithReducedRasterization(PrefService* prefs) {
  37. return base::FeatureList::IsEnabled(features::kPrintWithReducedRasterization);
  38. }
  39. +#if 0
  40. PrefService* GetPrefsForWebContents(content::WebContents* web_contents) {
  41. // TODO(thestig): Figure out why crbug.com/1083911 occurred, which is likely
  42. // because `web_contents` was null. As a result, this section has many more
  43. @@ -110,6 +111,7 @@ content::WebContents* GetWebContents(content::GlobalRenderFrameHostId rfh_id) {
  44. auto* rfh = content::RenderFrameHost::FromID(rfh_id);
  45. return rfh ? content::WebContents::FromRenderFrameHost(rfh) : nullptr;
  46. }
  47. +#endif
  48. #endif // BUILDFLAG(IS_WIN)
  49. @@ -150,10 +152,8 @@ void PrintJob::Initialize(std::unique_ptr<PrinterQuery> query,
  50. #if BUILDFLAG(IS_WIN)
  51. pdf_page_mapping_ = PageNumber::GetPages(settings->ranges(), page_count);
  52. - PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
  53. - if (prefs && prefs->IsManagedPreference(prefs::kPdfUseSkiaRendererEnabled)) {
  54. - use_skia_ = prefs->GetBoolean(prefs::kPdfUseSkiaRendererEnabled);
  55. - }
  56. + // TODO(codebytere): should we enable this later?
  57. + use_skia_ = false;
  58. #endif
  59. auto new_doc = base::MakeRefCounted<PrintedDocument>(std::move(settings),
  60. @@ -404,8 +404,10 @@ void PrintJob::StartPdfToEmfConversion(
  61. const PrintSettings& settings = document()->settings();
  62. +#if 0
  63. PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
  64. - bool print_with_reduced_rasterization = PrintWithReducedRasterization(prefs);
  65. +#endif
  66. + bool print_with_reduced_rasterization = PrintWithReducedRasterization(nullptr);
  67. using RenderMode = PdfRenderSettings::Mode;
  68. RenderMode mode = print_with_reduced_rasterization
  69. @@ -497,8 +499,10 @@ void PrintJob::StartPdfToPostScriptConversion(
  70. if (ps_level2) {
  71. mode = PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2;
  72. } else {
  73. +#if 0
  74. PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
  75. - mode = PrintWithPostScriptType42Fonts(prefs)
  76. +#endif
  77. + mode = PrintWithPostScriptType42Fonts(nullptr)
  78. ? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS
  79. : PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
  80. }
  81. diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
  82. index 301a4a47fb4dfb6007c2214b04ffdff744cc3043..427a045c310109475b83a229637f4d09b1e78450 100644
  83. --- a/chrome/browser/printing/print_view_manager_base.cc
  84. +++ b/chrome/browser/printing/print_view_manager_base.cc
  85. @@ -23,7 +23,9 @@
  86. #include "build/chromeos_buildflags.h"
  87. #include "chrome/browser/bad_message.h"
  88. #include "chrome/browser/browser_process.h"
  89. +#if 0 // Electron does not use Chrome error dialogs
  90. #include "chrome/browser/printing/print_error_dialog.h"
  91. +#endif
  92. #include "chrome/browser/printing/print_job.h"
  93. #include "chrome/browser/printing/print_job_manager.h"
  94. #include "chrome/browser/printing/print_view_manager_common.h"
  95. @@ -81,6 +83,20 @@ namespace printing {
  96. namespace {
  97. +std::string PrintReasonFromPrintStatus(PrintViewManager::PrintStatus status) {
  98. + if (status == PrintViewManager::PrintStatus::kInvalid) {
  99. + return "Invalid printer settings";
  100. + } else if (status == PrintViewManager::PrintStatus::kCanceled) {
  101. + return "Print job canceled";
  102. + } else if (status == PrintViewManager::PrintStatus::kFailed) {
  103. + return "Print job failed";
  104. + }
  105. + return "";
  106. +}
  107. +
  108. +using PrintSettingsCallback =
  109. + base::OnceCallback<void(std::unique_ptr<PrinterQuery>)>;
  110. +
  111. void OnDidGetDefaultPrintSettings(
  112. scoped_refptr<PrintQueriesQueue> queue,
  113. bool want_pdf_settings,
  114. @@ -89,9 +105,11 @@ void OnDidGetDefaultPrintSettings(
  115. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  116. if (printer_query->last_status() != mojom::ResultCode::kSuccess) {
  117. +#if 0 // Electron does not use Chrome error dialogs
  118. if (!want_pdf_settings) {
  119. ShowPrintErrorDialogForInvalidPrinterError();
  120. }
  121. +#endif
  122. std::move(callback).Run(nullptr);
  123. return;
  124. }
  125. @@ -101,9 +119,11 @@ void OnDidGetDefaultPrintSettings(
  126. params->document_cookie = printer_query->cookie();
  127. if (!PrintMsgPrintParamsIsValid(*params)) {
  128. +#if 0 // Electron does not use Chrome error dialogs
  129. if (!want_pdf_settings) {
  130. ShowPrintErrorDialogForInvalidPrinterError();
  131. }
  132. +#endif
  133. std::move(callback).Run(nullptr);
  134. return;
  135. }
  136. @@ -115,11 +135,15 @@ void OnDidGetDefaultPrintSettings(
  137. void OnDidScriptedPrint(
  138. scoped_refptr<PrintQueriesQueue> queue,
  139. std::unique_ptr<PrinterQuery> printer_query,
  140. - mojom::PrintManagerHost::ScriptedPrintCallback callback) {
  141. + mojom::PrintManagerHost::ScriptedPrintCallback callback,
  142. + base::OnceCallback<void()> cancel_job) {
  143. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  144. if (printer_query->last_status() != mojom::ResultCode::kSuccess ||
  145. !printer_query->settings().dpi()) {
  146. + if (printer_query->last_status() == mojom::ResultCode::kCanceled) {
  147. + std::move(cancel_job).Run();
  148. + }
  149. std::move(callback).Run(nullptr);
  150. return;
  151. }
  152. @@ -176,9 +200,11 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
  153. : PrintManager(web_contents),
  154. queue_(g_browser_process->print_job_manager()->queue()) {
  155. DCHECK(queue_);
  156. +#if 0 // Printing is always enabled.
  157. Profile* profile =
  158. Profile::FromBrowserContext(web_contents->GetBrowserContext());
  159. - printing_enabled_.Init(prefs::kPrintingEnabled, profile->GetPrefs());
  160. + printing_enabled_.Init(prefs::kPrintingEnabled, profile->GetPrefs());
  161. +#endif
  162. }
  163. PrintViewManagerBase::~PrintViewManagerBase() {
  164. @@ -202,12 +228,17 @@ void PrintViewManagerBase::DisableThirdPartyBlocking() {
  165. }
  166. #endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
  167. -bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
  168. +bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
  169. + bool silent,
  170. + base::Value::Dict settings,
  171. + CompletionCallback callback) {
  172. if (!StartPrintCommon(rfh)) {
  173. return false;
  174. }
  175. - GetPrintRenderFrame(rfh)->PrintRequestedPages();
  176. + callback_ = std::move(callback);
  177. +
  178. + GetPrintRenderFrame(rfh)->PrintRequestedPages(silent, std::move(settings));
  179. for (auto& observer : GetTestObservers()) {
  180. observer.OnPrintNow(rfh);
  181. @@ -336,12 +367,13 @@ void PrintViewManagerBase::OnDidUpdatePrintableArea(
  182. }
  183. PRINTER_LOG(EVENT) << "Paper printable area updated for vendor id "
  184. << print_settings->requested_media().vendor_id;
  185. - CompleteUpdatePrintSettings(std::move(job_settings),
  186. + CompleteUpdatePrintSettings(nullptr /* printer_query */, std::move(job_settings),
  187. std::move(print_settings), std::move(callback));
  188. }
  189. #endif
  190. void PrintViewManagerBase::CompleteUpdatePrintSettings(
  191. + std::unique_ptr<PrinterQuery> printer_query,
  192. base::Value::Dict job_settings,
  193. std::unique_ptr<PrintSettings> print_settings,
  194. UpdatePrintSettingsCallback callback) {
  195. @@ -349,7 +381,8 @@ void PrintViewManagerBase::CompleteUpdatePrintSettings(
  196. settings->pages = GetPageRangesFromJobSettings(job_settings);
  197. settings->params = mojom::PrintParams::New();
  198. RenderParamsFromPrintSettings(*print_settings, settings->params.get());
  199. - settings->params->document_cookie = PrintSettings::NewCookie();
  200. + settings->params->document_cookie = printer_query ? printer_query->cookie()
  201. + : PrintSettings::NewCookie();
  202. if (!PrintMsgPrintParamsIsValid(*settings->params)) {
  203. mojom::PrinterType printer_type = static_cast<mojom::PrinterType>(
  204. *job_settings.FindInt(kSettingPrinterType));
  205. @@ -361,6 +394,10 @@ void PrintViewManagerBase::CompleteUpdatePrintSettings(
  206. return;
  207. }
  208. + if (printer_query && printer_query->cookie() && printer_query->settings().dpi()) {
  209. + queue_->QueuePrinterQuery(std::move(printer_query));
  210. + }
  211. +
  212. set_cookie(settings->params->document_cookie);
  213. std::move(callback).Run(std::move(settings));
  214. }
  215. @@ -647,11 +684,12 @@ void PrintViewManagerBase::DidPrintDocument(
  216. void PrintViewManagerBase::GetDefaultPrintSettings(
  217. GetDefaultPrintSettingsCallback callback) {
  218. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  219. +#if 0 // Printing is always enabled.
  220. if (!printing_enabled_.GetValue()) {
  221. GetDefaultPrintSettingsReply(std::move(callback), nullptr);
  222. return;
  223. }
  224. -
  225. +#endif
  226. content::RenderFrameHost* render_frame_host = GetCurrentTargetFrame();
  227. if (base::FeatureList::IsEnabled(kCheckPrintRfhIsActive) &&
  228. !render_frame_host->IsActive()) {
  229. @@ -710,10 +748,12 @@ void PrintViewManagerBase::UpdatePrintSettings(
  230. base::Value::Dict job_settings,
  231. UpdatePrintSettingsCallback callback) {
  232. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  233. +#if 0 // Printing is always enabled.
  234. if (!printing_enabled_.GetValue()) {
  235. std::move(callback).Run(nullptr);
  236. return;
  237. }
  238. +#endif // Printing is always enabled.
  239. std::optional<int> printer_type_value =
  240. job_settings.FindInt(kSettingPrinterType);
  241. @@ -724,6 +764,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
  242. mojom::PrinterType printer_type =
  243. static_cast<mojom::PrinterType>(*printer_type_value);
  244. +#if 0 // Printing is always enabled.
  245. if (printer_type != mojom::PrinterType::kExtension &&
  246. printer_type != mojom::PrinterType::kPdf &&
  247. printer_type != mojom::PrinterType::kLocal) {
  248. @@ -743,6 +784,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
  249. if (value > 0)
  250. job_settings.Set(kSettingRasterizePdfDpi, value);
  251. }
  252. +#endif // Printing is always enabled.
  253. std::unique_ptr<PrintSettings> print_settings =
  254. PrintSettingsFromJobSettings(job_settings);
  255. @@ -762,7 +804,21 @@ void PrintViewManagerBase::UpdatePrintSettings(
  256. }
  257. }
  258. -#if BUILDFLAG(IS_WIN)
  259. + std::unique_ptr<PrinterQuery> query =
  260. + queue_->CreatePrinterQuery(GetCurrentTargetFrame()->GetGlobalId());
  261. + auto* query_ptr = query.get();
  262. + // We need to clone this before calling SetSettings because some environments
  263. + // evaluate job_settings.Clone() first, and some std::move(job_settings) first,
  264. + // for the former things work correctly but for the latter the cloned value is null.
  265. + auto job_settings_copy = job_settings.Clone();
  266. + query_ptr->SetSettings(
  267. + std::move(job_settings_copy),
  268. + base::BindOnce(&PrintViewManagerBase::CompleteUpdatePrintSettings,
  269. + weak_ptr_factory_.GetWeakPtr(), std::move(query),
  270. + std::move(job_settings), std::move(print_settings),
  271. + std::move(callback)));
  272. +
  273. +#if 0 // See https://chromium-review.googlesource.com/412367
  274. // TODO(crbug.com/1424368): Remove this if the printable areas can be made
  275. // fully available from `PrintBackend::GetPrinterSemanticCapsAndDefaults()`
  276. // for in-browser queries.
  277. @@ -784,8 +840,6 @@ void PrintViewManagerBase::UpdatePrintSettings(
  278. }
  279. #endif
  280. - CompleteUpdatePrintSettings(std::move(job_settings),
  281. - std::move(print_settings), std::move(callback));
  282. }
  283. void PrintViewManagerBase::SetAccessibilityTree(
  284. @@ -801,7 +855,7 @@ void PrintViewManagerBase::SetAccessibilityTree(
  285. void PrintViewManagerBase::IsPrintingEnabled(
  286. IsPrintingEnabledCallback callback) {
  287. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  288. - std::move(callback).Run(printing_enabled_.GetValue());
  289. + std::move(callback).Run(true);
  290. }
  291. void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
  292. @@ -852,6 +906,7 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie,
  293. PrintManager::PrintingFailed(cookie, reason);
  294. +#if 0 // Electron does not use Chromium error dialogs
  295. // `PrintingFailed()` can occur because asynchronous compositing results
  296. // don't complete until after a print job has already failed and been
  297. // destroyed. In such cases the error notification to the user will
  298. @@ -861,7 +916,7 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie,
  299. print_job_->document()->cookie() == cookie) {
  300. ShowPrintErrorDialogForGenericError();
  301. }
  302. -
  303. +#endif
  304. ReleasePrinterQuery();
  305. }
  306. @@ -873,15 +928,24 @@ void PrintViewManagerBase::RemoveTestObserver(TestObserver& observer) {
  307. test_observers_.RemoveObserver(&observer);
  308. }
  309. +void PrintViewManagerBase::ShowInvalidPrinterSettingsError() {
  310. + if (!callback_.is_null()) {
  311. + printing_status_ = PrintStatus::kInvalid;
  312. + TerminatePrintJob(true);
  313. + }
  314. +}
  315. +
  316. void PrintViewManagerBase::RenderFrameHostStateChanged(
  317. content::RenderFrameHost* render_frame_host,
  318. content::RenderFrameHost::LifecycleState /*old_state*/,
  319. content::RenderFrameHost::LifecycleState new_state) {
  320. +#if 0
  321. if (new_state == content::RenderFrameHost::LifecycleState::kActive &&
  322. render_frame_host->GetProcess()->IsPdf() &&
  323. !render_frame_host->GetMainFrame()->GetParentOrOuterDocument()) {
  324. GetPrintRenderFrame(render_frame_host)->ConnectToPdfRenderer();
  325. }
  326. +#endif
  327. }
  328. void PrintViewManagerBase::RenderFrameDeleted(
  329. @@ -933,7 +997,12 @@ void PrintViewManagerBase::OnJobDone() {
  330. // Printing is done, we don't need it anymore.
  331. // print_job_->is_job_pending() may still be true, depending on the order
  332. // of object registration.
  333. - printing_succeeded_ = true;
  334. + printing_status_ = PrintStatus::kSucceeded;
  335. + ReleasePrintJob();
  336. +}
  337. +
  338. +void PrintViewManagerBase::UserInitCanceled() {
  339. + printing_status_ = PrintStatus::kCanceled;
  340. ReleasePrintJob();
  341. }
  342. @@ -942,9 +1011,10 @@ void PrintViewManagerBase::OnCanceling() {
  343. }
  344. void PrintViewManagerBase::OnFailed() {
  345. +#if 0 // Electron does not use Chromium error dialogs
  346. if (!canceling_job_)
  347. ShowPrintErrorDialogForGenericError();
  348. -
  349. +#endif
  350. TerminatePrintJob(true);
  351. }
  352. @@ -954,7 +1024,7 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
  353. // Is the document already complete?
  354. if (print_job_->document() && print_job_->document()->IsComplete()) {
  355. - printing_succeeded_ = true;
  356. + printing_status_ = PrintStatus::kSucceeded;
  357. return true;
  358. }
  359. @@ -1007,7 +1077,10 @@ bool PrintViewManagerBase::SetupNewPrintJob(
  360. // Disconnect the current `print_job_`.
  361. auto weak_this = weak_ptr_factory_.GetWeakPtr();
  362. - DisconnectFromCurrentPrintJob();
  363. + if (callback_.is_null()) {
  364. + // Disconnect the current |print_job_| only when calling window.print()
  365. + DisconnectFromCurrentPrintJob();
  366. + }
  367. if (!weak_this)
  368. return false;
  369. @@ -1027,7 +1100,7 @@ bool PrintViewManagerBase::SetupNewPrintJob(
  370. #endif
  371. print_job_->AddObserver(*this);
  372. - printing_succeeded_ = false;
  373. + printing_status_ = PrintStatus::kFailed;
  374. return true;
  375. }
  376. @@ -1095,6 +1168,11 @@ void PrintViewManagerBase::ReleasePrintJob() {
  377. }
  378. #endif
  379. + if (!callback_.is_null()) {
  380. + bool success = printing_status_ == PrintStatus::kSucceeded;
  381. + std::move(callback_).Run(success, PrintReasonFromPrintStatus(printing_status_));
  382. + }
  383. +
  384. if (!print_job_)
  385. return;
  386. @@ -1102,7 +1180,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
  387. // printing_rfh_ should only ever point to a RenderFrameHost with a live
  388. // RenderFrame.
  389. DCHECK(rfh->IsRenderFrameLive());
  390. - GetPrintRenderFrame(rfh)->PrintingDone(printing_succeeded_);
  391. + GetPrintRenderFrame(rfh)->PrintingDone(printing_status_ == PrintStatus::kSucceeded);
  392. }
  393. print_job_->RemoveObserver(*this);
  394. @@ -1144,7 +1222,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
  395. }
  396. bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
  397. - if (print_job_)
  398. + if (print_job_ && print_job_->document())
  399. return true;
  400. if (!cookie) {
  401. @@ -1298,6 +1376,8 @@ void PrintViewManagerBase::CompleteScriptedPrint(
  402. auto callback_wrapper = base::BindOnce(
  403. &PrintViewManagerBase::ScriptedPrintReply, weak_ptr_factory_.GetWeakPtr(),
  404. std::move(callback), render_process_host->GetID());
  405. + auto cancel_job_wrapper = base::BindOnce(
  406. + &PrintViewManagerBase::UserInitCanceled, weak_ptr_factory_.GetWeakPtr());
  407. #if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
  408. DisableThirdPartyBlocking();
  409. #endif
  410. @@ -1312,7 +1392,7 @@ void PrintViewManagerBase::CompleteScriptedPrint(
  411. params->expected_pages_count, params->has_selection, params->margin_type,
  412. params->is_scripted, !render_process_host->IsPdf(),
  413. base::BindOnce(&OnDidScriptedPrint, queue_, std::move(printer_query),
  414. - std::move(callback_wrapper)));
  415. + std::move(callback_wrapper), std::move(cancel_job_wrapper)));
  416. }
  417. #if BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
  418. diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h
  419. index 24a2bc8b26462e6cafbcd5eb89e838b73266ec70..402aab3b14e6987bde0e22e6c82ac438d465330a 100644
  420. --- a/chrome/browser/printing/print_view_manager_base.h
  421. +++ b/chrome/browser/printing/print_view_manager_base.h
  422. @@ -49,6 +49,8 @@ class PrinterQuery;
  423. // rollout.
  424. BASE_DECLARE_FEATURE(kCheckPrintRfhIsActive);
  425. +using CompletionCallback = base::OnceCallback<void(bool, const std::string&)>;
  426. +
  427. // Base class for managing the print commands for a WebContents.
  428. class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  429. public:
  430. @@ -82,7 +84,10 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  431. // Prints the current document immediately. Since the rendering is
  432. // asynchronous, the actual printing will not be completed on the return of
  433. // this function. Returns false if printing is impossible at the moment.
  434. - virtual bool PrintNow(content::RenderFrameHost* rfh);
  435. + virtual bool PrintNow(content::RenderFrameHost* rfh,
  436. + bool silent = true,
  437. + base::Value::Dict settings = {},
  438. + CompletionCallback callback = {});
  439. // Like PrintNow(), but for the node under the context menu, instead of the
  440. // entire frame.
  441. @@ -136,8 +141,10 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  442. void IsPrintingEnabled(IsPrintingEnabledCallback callback) override;
  443. void ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
  444. ScriptedPrintCallback callback) override;
  445. + void ShowInvalidPrinterSettingsError() override;
  446. void PrintingFailed(int32_t cookie,
  447. mojom::PrintFailureReason reason) override;
  448. + void UserInitCanceled();
  449. // Adds and removes observers for `PrintViewManagerBase` events. The order in
  450. // which notifications are sent to observers is undefined. Observers must be
  451. @@ -145,6 +152,14 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  452. void AddTestObserver(TestObserver& observer);
  453. void RemoveTestObserver(TestObserver& observer);
  454. + enum class PrintStatus {
  455. + kSucceeded,
  456. + kCanceled,
  457. + kFailed,
  458. + kInvalid,
  459. + kUnknown
  460. + };
  461. +
  462. protected:
  463. explicit PrintViewManagerBase(content::WebContents* web_contents);
  464. @@ -268,6 +283,7 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  465. bool success);
  466. #endif
  467. void CompleteUpdatePrintSettings(
  468. + std::unique_ptr<PrinterQuery> printer_query,
  469. base::Value::Dict job_settings,
  470. std::unique_ptr<PrintSettings> print_settings,
  471. UpdatePrintSettingsCallback callback);
  472. @@ -362,8 +378,11 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  473. // The current RFH that is printing with a system printing dialog.
  474. raw_ptr<content::RenderFrameHost> printing_rfh_ = nullptr;
  475. + // Respond with success of the print job.
  476. + CompletionCallback callback_;
  477. +
  478. // Indication of success of the print job.
  479. - bool printing_succeeded_ = false;
  480. + PrintStatus printing_status_ = PrintStatus::kUnknown;
  481. // Indication that the job is getting canceled.
  482. bool canceling_job_ = false;
  483. diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc
  484. index 418f53b0db3a2b2624298fca5628aacdd2a99c94..4a110fda692e16ec887cb90c6a2fa611c67b8d6f 100644
  485. --- a/chrome/browser/printing/printer_query.cc
  486. +++ b/chrome/browser/printing/printer_query.cc
  487. @@ -355,17 +355,19 @@ void PrinterQuery::UpdatePrintSettings(base::Value::Dict new_settings,
  488. #endif // BUILDFLAG(IS_LINUX) && BUILDFLAG(USE_CUPS)
  489. }
  490. - mojom::ResultCode result;
  491. {
  492. #if BUILDFLAG(IS_WIN)
  493. // Blocking is needed here because Windows printer drivers are oftentimes
  494. // not thread-safe and have to be accessed on the UI thread.
  495. base::ScopedAllowBlocking allow_blocking;
  496. #endif
  497. - result = printing_context_->UpdatePrintSettings(std::move(new_settings));
  498. + // Reset settings from previous print job
  499. + printing_context_->ResetSettings();
  500. + mojom::ResultCode result_code = printing_context_->UseDefaultSettings();
  501. + if (result_code == mojom::ResultCode::kSuccess)
  502. + result_code = printing_context_->UpdatePrintSettings(std::move(new_settings));
  503. + InvokeSettingsCallback(std::move(callback), result_code);
  504. }
  505. -
  506. - InvokeSettingsCallback(std::move(callback), result);
  507. }
  508. #if BUILDFLAG(IS_CHROMEOS)
  509. diff --git a/chrome/browser/ui/webui/print_preview/fake_print_render_frame.cc b/chrome/browser/ui/webui/print_preview/fake_print_render_frame.cc
  510. index ac54519f611f719470c4b7a139a58f489884ede2..89055b6df74389560b6c5884a511897a36425b7b 100644
  511. --- a/chrome/browser/ui/webui/print_preview/fake_print_render_frame.cc
  512. +++ b/chrome/browser/ui/webui/print_preview/fake_print_render_frame.cc
  513. @@ -21,7 +21,7 @@ FakePrintRenderFrame::FakePrintRenderFrame(
  514. FakePrintRenderFrame::~FakePrintRenderFrame() = default;
  515. -void FakePrintRenderFrame::PrintRequestedPages() {}
  516. +void FakePrintRenderFrame::PrintRequestedPages(bool /*silent*/, ::base::Value::Dict /*settings*/) {}
  517. void FakePrintRenderFrame::PrintWithParams(mojom::PrintPagesParamsPtr params,
  518. PrintWithParamsCallback callback) {
  519. diff --git a/chrome/browser/ui/webui/print_preview/fake_print_render_frame.h b/chrome/browser/ui/webui/print_preview/fake_print_render_frame.h
  520. index 1e8f7bedaf679ee19788bf181b33e5d574d1f863..8be77b57580621bf659a6a2a63a2be94a2301c70 100644
  521. --- a/chrome/browser/ui/webui/print_preview/fake_print_render_frame.h
  522. +++ b/chrome/browser/ui/webui/print_preview/fake_print_render_frame.h
  523. @@ -25,7 +25,7 @@ class FakePrintRenderFrame : public mojom::PrintRenderFrame {
  524. private:
  525. // printing::mojom::PrintRenderFrame:
  526. - void PrintRequestedPages() override;
  527. + void PrintRequestedPages(bool silent, ::base::Value::Dict settings) override;
  528. void PrintWithParams(mojom::PrintPagesParamsPtr params,
  529. PrintWithParamsCallback callback) override;
  530. void PrintForSystemDialog() override;
  531. diff --git a/components/printing/browser/print_manager.cc b/components/printing/browser/print_manager.cc
  532. index 21c81377d32ae8d4185598a7eba88ed1d2063ef0..0767f4e9369e926b1cea99178c1a1975941f1765 100644
  533. --- a/components/printing/browser/print_manager.cc
  534. +++ b/components/printing/browser/print_manager.cc
  535. @@ -47,6 +47,8 @@ void PrintManager::IsPrintingEnabled(IsPrintingEnabledCallback callback) {
  536. std::move(callback).Run(true);
  537. }
  538. +void PrintManager::ShowInvalidPrinterSettingsError() {}
  539. +
  540. void PrintManager::PrintingFailed(int32_t cookie,
  541. mojom::PrintFailureReason reason) {
  542. // Note: Not redundant with cookie checks in the same method in other parts of
  543. diff --git a/components/printing/browser/print_manager.h b/components/printing/browser/print_manager.h
  544. index ca71560874a0189068dd11fbc039f5673bf6bd96..a8551d95e64da2afbc1685b2df8f1fc377c7117b 100644
  545. --- a/components/printing/browser/print_manager.h
  546. +++ b/components/printing/browser/print_manager.h
  547. @@ -48,6 +48,7 @@ class PrintManager : public content::WebContentsObserver,
  548. DidPrintDocumentCallback callback) override;
  549. void IsPrintingEnabled(IsPrintingEnabledCallback callback) override;
  550. void DidShowPrintDialog() override;
  551. + void ShowInvalidPrinterSettingsError() override;
  552. void PrintingFailed(int32_t cookie,
  553. mojom::PrintFailureReason reason) override;
  554. diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom
  555. index 4ecdb28904fac480cf102fffdff24ae008ac88cf..e8150c95fafd83d7e2fe1f472a35acec3ca6e391 100644
  556. --- a/components/printing/common/print.mojom
  557. +++ b/components/printing/common/print.mojom
  558. @@ -302,7 +302,7 @@ union PrintWithParamsResult {
  559. interface PrintRenderFrame {
  560. // Tells the RenderFrame to switch the CSS to print media type, render every
  561. // requested page, and then switch back the CSS to display media type.
  562. - PrintRequestedPages();
  563. + PrintRequestedPages(bool silent, mojo_base.mojom.DictionaryValue settings);
  564. // Requests the frame to be printed with specified parameters. This is used
  565. // to programmatically produce PDF by request from the browser (e.g. over
  566. @@ -391,6 +391,9 @@ interface PrintManagerHost {
  567. [Sync]
  568. ScriptedPrint(ScriptedPrintParams params) => (PrintPagesParams? settings);
  569. + // Tells the browser that there are invalid printer settings.
  570. + ShowInvalidPrinterSettingsError();
  571. +
  572. // Tells the browser printing failed.
  573. PrintingFailed(int32 cookie, PrintFailureReason reason);
  574. diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
  575. index 410dc5e8a46946e0a0293bdefa85b5dbb13821c9..c07c6a91caa137b15402efcb455ff919e0c4fd48 100644
  576. --- a/components/printing/renderer/print_render_frame_helper.cc
  577. +++ b/components/printing/renderer/print_render_frame_helper.cc
  578. @@ -47,6 +47,7 @@
  579. #include "printing/mojom/print.mojom.h"
  580. #include "printing/page_number.h"
  581. #include "printing/print_job_constants.h"
  582. +#include "printing/print_settings.h"
  583. #include "printing/units.h"
  584. #include "services/metrics/public/cpp/ukm_source_id.h"
  585. #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
  586. @@ -1232,14 +1233,14 @@ void PrintRenderFrameHelper::ScriptedPrint(bool user_initiated) {
  587. }
  588. print_in_progress_ = true;
  589. -
  590. auto weak_this = weak_ptr_factory_.GetWeakPtr();
  591. web_frame->DispatchBeforePrintEvent(/*print_client=*/nullptr);
  592. if (!weak_this) {
  593. return;
  594. }
  595. - Print(web_frame, blink::WebNode(), PrintRequestType::kScripted);
  596. + Print(web_frame, blink::WebNode(), PrintRequestType::kScripted,
  597. + false /* silent */, base::Value::Dict() /* new_settings */);
  598. if (!weak_this) {
  599. return;
  600. }
  601. @@ -1270,7 +1271,7 @@ void PrintRenderFrameHelper::BindPrintRenderFrameReceiver(
  602. receivers_.Add(this, std::move(receiver));
  603. }
  604. -void PrintRenderFrameHelper::PrintRequestedPages() {
  605. +void PrintRenderFrameHelper::PrintRequestedPages(bool silent, base::Value::Dict settings) {
  606. ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
  607. if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
  608. return;
  609. @@ -1285,7 +1286,7 @@ void PrintRenderFrameHelper::PrintRequestedPages() {
  610. // plugin node and print that instead.
  611. auto plugin = delegate_->GetPdfElement(frame);
  612. - Print(frame, plugin, PrintRequestType::kRegular);
  613. + Print(frame, plugin, PrintRequestType::kRegular, silent, std::move(settings));
  614. if (render_frame_gone_) {
  615. return;
  616. @@ -1374,7 +1375,8 @@ void PrintRenderFrameHelper::PrintForSystemDialog() {
  617. }
  618. Print(frame, print_preview_context_.source_node(),
  619. - PrintRequestType::kRegular);
  620. + PrintRequestType::kRegular, false,
  621. + base::Value::Dict());
  622. if (render_frame_gone_) {
  623. return;
  624. }
  625. @@ -1437,6 +1439,8 @@ void PrintRenderFrameHelper::PrintPreview(base::Value::Dict settings) {
  626. if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
  627. return;
  628. + blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
  629. + print_preview_context_.InitWithFrame(frame);
  630. print_preview_context_.OnPrintPreview();
  631. #if BUILDFLAG(IS_CHROMEOS_ASH)
  632. @@ -2014,7 +2018,8 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
  633. }
  634. Print(duplicate_node.GetDocument().GetFrame(), duplicate_node,
  635. - PrintRequestType::kRegular);
  636. + PrintRequestType::kRegular, false /* silent */,
  637. + base::Value::Dict() /* new_settings */);
  638. // Check if `this` is still valid.
  639. if (!weak_this) {
  640. return;
  641. @@ -2030,17 +2035,19 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
  642. void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
  643. const blink::WebNode& node,
  644. - PrintRequestType print_request_type) {
  645. + PrintRequestType print_request_type,
  646. + bool silent,
  647. + base::Value::Dict settings) {
  648. // If still not finished with earlier print request simply ignore.
  649. if (prep_frame_view_)
  650. return;
  651. FrameReference frame_ref(frame);
  652. - if (!InitPrintSettings(frame, node)) {
  653. + if (!InitPrintSettings(frame, node, std::move(settings))) {
  654. // Browser triggered this code path. It already knows about the failure.
  655. notify_browser_of_print_failure_ = false;
  656. -
  657. + GetPrintManagerHost()->ShowInvalidPrinterSettingsError();
  658. DidFinishPrinting(PrintingResult::kFailPrintInit);
  659. return;
  660. }
  661. @@ -2061,8 +2068,15 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
  662. print_pages_params_->params->print_scaling_option;
  663. auto self = weak_ptr_factory_.GetWeakPtr();
  664. - mojom::PrintPagesParamsPtr print_settings = GetPrintSettingsFromUser(
  665. + mojom::PrintPagesParamsPtr print_settings;
  666. +
  667. + if (silent) {
  668. + print_settings = mojom::PrintPagesParams::New();
  669. + print_settings->params = print_pages_params_->params->Clone();
  670. + } else {
  671. + print_settings = GetPrintSettingsFromUser(
  672. frame_ref.GetFrame(), node, expected_page_count, print_request_type);
  673. + }
  674. // Check if `this` is still valid.
  675. if (!self)
  676. return;
  677. @@ -2320,25 +2334,33 @@ void PrintRenderFrameHelper::IPCProcessed() {
  678. }
  679. bool PrintRenderFrameHelper::InitPrintSettings(blink::WebLocalFrame* frame,
  680. - const blink::WebNode& node) {
  681. + const blink::WebNode& node,
  682. + base::Value::Dict new_settings) {
  683. // Reset to default values.
  684. ignore_css_margins_ = false;
  685. - mojom::PrintPagesParams settings;
  686. - GetPrintManagerHost()->GetDefaultPrintSettings(&settings.params);
  687. + mojom::PrintPagesParamsPtr settings;
  688. + if (new_settings.empty()) {
  689. + settings = mojom::PrintPagesParams::New();
  690. + settings->params = mojom::PrintParams::New();
  691. + GetPrintManagerHost()->GetDefaultPrintSettings(&settings->params);
  692. + } else {
  693. + GetPrintManagerHost()->UpdatePrintSettings(
  694. + std::move(new_settings), &settings);
  695. + }
  696. // Check if the printer returned any settings, if the settings are null,
  697. // assume there are no printer drivers configured. So safely terminate.
  698. - if (!settings.params) {
  699. + if (!settings || !settings->params) {
  700. // Caller will reset `print_pages_params_`.
  701. return false;
  702. }
  703. bool center_on_paper = !IsPrintingPdfFrame(frame, node);
  704. - settings.params->print_scaling_option =
  705. + settings->params->print_scaling_option =
  706. center_on_paper ? mojom::PrintScalingOption::kCenterShrinkToFitPaper
  707. : mojom::PrintScalingOption::kSourceSize;
  708. - SetPrintPagesParams(settings);
  709. + SetPrintPagesParams(*settings);
  710. return true;
  711. }
  712. diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
  713. index b0ac94751454bd16b4e9bfdc071e2623813133ec..271bd9949a802a370b3619340f3364df14c7fe4a 100644
  714. --- a/components/printing/renderer/print_render_frame_helper.h
  715. +++ b/components/printing/renderer/print_render_frame_helper.h
  716. @@ -245,7 +245,7 @@ class PrintRenderFrameHelper
  717. mojo::PendingAssociatedReceiver<mojom::PrintRenderFrame> receiver);
  718. // printing::mojom::PrintRenderFrame:
  719. - void PrintRequestedPages() override;
  720. + void PrintRequestedPages(bool silent, base::Value::Dict settings) override;
  721. void PrintWithParams(mojom::PrintPagesParamsPtr params,
  722. PrintWithParamsCallback callback) override;
  723. #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
  724. @@ -312,7 +312,9 @@ class PrintRenderFrameHelper
  725. // WARNING: |this| may be gone after this method returns.
  726. void Print(blink::WebLocalFrame* frame,
  727. const blink::WebNode& node,
  728. - PrintRequestType print_request_type);
  729. + PrintRequestType print_request_type,
  730. + bool silent,
  731. + base::Value::Dict settings);
  732. // Notification when printing is done - signal tear-down/free resources.
  733. void DidFinishPrinting(PrintingResult result);
  734. @@ -322,7 +324,8 @@ class PrintRenderFrameHelper
  735. // Initialize print page settings with default settings.
  736. // Used only for native printing workflow.
  737. bool InitPrintSettings(blink::WebLocalFrame* frame,
  738. - const blink::WebNode& node);
  739. + const blink::WebNode& node,
  740. + base::Value::Dict new_settings);
  741. // Calculate number of pages in source document.
  742. uint32_t CalculateNumberOfPages(blink::WebLocalFrame* frame,
  743. diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
  744. index f6b7ba2f3512dcd2528323bb6853452cc9eab1a6..288d9219efa0ea8683fe86c5b339bbf9b829d712 100644
  745. --- a/content/browser/BUILD.gn
  746. +++ b/content/browser/BUILD.gn
  747. @@ -2933,8 +2933,9 @@ source_set("browser") {
  748. "//ppapi/shared_impl",
  749. ]
  750. - assert(enable_printing)
  751. - deps += [ "//printing" ]
  752. + if (enable_printing) {
  753. + deps += [ "//printing" ]
  754. + }
  755. if (is_chromeos) {
  756. sources += [
  757. diff --git a/printing/printing_context.cc b/printing/printing_context.cc
  758. index 87ffdf6f44029700ef615b16366e3a9805e7d3ff..ea407211ca4e33b87de5ed6002ebe1a2ef76372f 100644
  759. --- a/printing/printing_context.cc
  760. +++ b/printing/printing_context.cc
  761. @@ -154,7 +154,6 @@ void PrintingContext::UsePdfSettings() {
  762. mojom::ResultCode PrintingContext::UpdatePrintSettings(
  763. base::Value::Dict job_settings) {
  764. - ResetSettings();
  765. {
  766. std::unique_ptr<PrintSettings> settings =
  767. PrintSettingsFromJobSettings(job_settings);
  768. diff --git a/printing/printing_context.h b/printing/printing_context.h
  769. index 63f170c95050416c595e62f4c460c4cd6b7dbd1c..157e3d046889f9c63fdf0fd5d503890fb82c038d 100644
  770. --- a/printing/printing_context.h
  771. +++ b/printing/printing_context.h
  772. @@ -206,6 +206,9 @@ class COMPONENT_EXPORT(PRINTING) PrintingContext {
  773. bool PrintingAborted() const { return abort_printing_; }
  774. + // Reinitializes the settings for object reuse.
  775. + void ResetSettings();
  776. +
  777. int job_id() const { return job_id_; }
  778. #if BUILDFLAG(ENABLE_OOP_PRINTING)
  779. @@ -224,9 +227,6 @@ class COMPONENT_EXPORT(PRINTING) PrintingContext {
  780. Delegate* delegate,
  781. ProcessBehavior process_behavior);
  782. - // Reinitializes the settings for object reuse.
  783. - void ResetSettings();
  784. -
  785. // Does bookkeeping when an error occurs.
  786. virtual mojom::ResultCode OnError();
  787. diff --git a/sandbox/policy/mac/sandbox_mac.mm b/sandbox/policy/mac/sandbox_mac.mm
  788. index e89fd87753bad3c5663fa53f8dcc4542e7e307e5..2b433a0705234af6f9808ee741a9795d5e251785 100644
  789. --- a/sandbox/policy/mac/sandbox_mac.mm
  790. +++ b/sandbox/policy/mac/sandbox_mac.mm
  791. @@ -38,6 +38,10 @@
  792. #include "sandbox/policy/mac/utility.sb.h"
  793. #include "sandbox/policy/mojom/sandbox.mojom.h"
  794. +#if BUILDFLAG(ENABLE_PRINTING)
  795. +#include "sandbox/policy/mac/print_backend.sb.h"
  796. +#endif
  797. +
  798. namespace sandbox::policy {
  799. base::FilePath GetCanonicalPath(const base::FilePath& path) {