printing.patch 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  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/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc
  11. index 6f35d5ab358627ff8b1cbf09f5643f0f484e027a..5e736b846880a7d4a1e1611a0f70feca102bfbbc 100644
  12. --- a/chrome/browser/printing/print_job.cc
  13. +++ b/chrome/browser/printing/print_job.cc
  14. @@ -97,6 +97,7 @@ bool PrintWithReducedRasterization(PrefService* prefs) {
  15. return base::FeatureList::IsEnabled(features::kPrintWithReducedRasterization);
  16. }
  17. +#if 0
  18. PrefService* GetPrefsForWebContents(content::WebContents* web_contents) {
  19. // TODO(thestig): Figure out why crbug.com/1083911 occurred, which is likely
  20. // because `web_contents` was null. As a result, this section has many more
  21. @@ -111,6 +112,7 @@ content::WebContents* GetWebContents(content::GlobalRenderFrameHostId rfh_id) {
  22. auto* rfh = content::RenderFrameHost::FromID(rfh_id);
  23. return rfh ? content::WebContents::FromRenderFrameHost(rfh) : nullptr;
  24. }
  25. +#endif
  26. #endif // BUILDFLAG(IS_WIN)
  27. @@ -151,10 +153,8 @@ void PrintJob::Initialize(std::unique_ptr<PrinterQuery> query,
  28. #if BUILDFLAG(IS_WIN)
  29. pdf_page_mapping_ = PageNumber::GetPages(settings->ranges(), page_count);
  30. - PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
  31. - if (prefs && prefs->IsManagedPreference(prefs::kPdfUseSkiaRendererEnabled)) {
  32. - use_skia_ = prefs->GetBoolean(prefs::kPdfUseSkiaRendererEnabled);
  33. - }
  34. + // TODO(codebytere): should we enable this later?
  35. + use_skia_ = false;
  36. #endif
  37. auto new_doc = base::MakeRefCounted<PrintedDocument>(std::move(settings),
  38. @@ -404,8 +404,10 @@ void PrintJob::StartPdfToEmfConversion(
  39. const PrintSettings& settings = document()->settings();
  40. +#if 0
  41. PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
  42. - bool print_with_reduced_rasterization = PrintWithReducedRasterization(prefs);
  43. +#endif
  44. + bool print_with_reduced_rasterization = PrintWithReducedRasterization(nullptr);
  45. using RenderMode = PdfRenderSettings::Mode;
  46. RenderMode mode = print_with_reduced_rasterization
  47. @@ -497,8 +499,10 @@ void PrintJob::StartPdfToPostScriptConversion(
  48. if (ps_level2) {
  49. mode = PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2;
  50. } else {
  51. +#if 0
  52. PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
  53. - mode = PrintWithPostScriptType42Fonts(prefs)
  54. +#endif
  55. + mode = PrintWithPostScriptType42Fonts(nullptr)
  56. ? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS
  57. : PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
  58. }
  59. diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
  60. index 05d05dd3d2902947e2ddf9a3f9379abe0008d74e..8a65ef057271bbef16f1d596229a5976997aaa4b 100644
  61. --- a/chrome/browser/printing/print_view_manager_base.cc
  62. +++ b/chrome/browser/printing/print_view_manager_base.cc
  63. @@ -83,6 +83,20 @@ namespace printing {
  64. namespace {
  65. +std::string PrintReasonFromPrintStatus(PrintViewManager::PrintStatus status) {
  66. + if (status == PrintViewManager::PrintStatus::kInvalid) {
  67. + return "Invalid printer settings";
  68. + } else if (status == PrintViewManager::PrintStatus::kCanceled) {
  69. + return "Print job canceled";
  70. + } else if (status == PrintViewManager::PrintStatus::kFailed) {
  71. + return "Print job failed";
  72. + }
  73. + return "";
  74. +}
  75. +
  76. +using PrintSettingsCallback =
  77. + base::OnceCallback<void(std::unique_ptr<PrinterQuery>)>;
  78. +
  79. void OnDidGetDefaultPrintSettings(
  80. scoped_refptr<PrintQueriesQueue> queue,
  81. bool want_pdf_settings,
  82. @@ -91,9 +105,9 @@ void OnDidGetDefaultPrintSettings(
  83. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  84. if (printer_query->last_status() != mojom::ResultCode::kSuccess) {
  85. - if (!want_pdf_settings) {
  86. +#if 0 // Electron does not use Chromium error dialogs
  87. ShowPrintErrorDialogForInvalidPrinterError();
  88. - }
  89. +#endif
  90. std::move(callback).Run(nullptr);
  91. return;
  92. }
  93. @@ -103,9 +117,9 @@ void OnDidGetDefaultPrintSettings(
  94. params->document_cookie = printer_query->cookie();
  95. if (!PrintMsgPrintParamsIsValid(*params)) {
  96. - if (!want_pdf_settings) {
  97. +#if 0 // Electron does not use Chromium error dialogs
  98. ShowPrintErrorDialogForInvalidPrinterError();
  99. - }
  100. +#endif
  101. std::move(callback).Run(nullptr);
  102. return;
  103. }
  104. @@ -117,14 +131,14 @@ void OnDidGetDefaultPrintSettings(
  105. void OnDidScriptedPrint(
  106. scoped_refptr<PrintQueriesQueue> queue,
  107. std::unique_ptr<PrinterQuery> printer_query,
  108. - mojom::PrintManagerHost::ScriptedPrintCallback callback) {
  109. + mojom::PrintManagerHost::ScriptedPrintCallback callback,
  110. + base::OnceCallback<void()> cancel_job) {
  111. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  112. if (printer_query->last_status() != mojom::ResultCode::kSuccess ||
  113. !printer_query->settings().dpi()) {
  114. - // Notify user of the error, unless it was explicitly canceled.
  115. - if (printer_query->last_status() != mojom::ResultCode::kCanceled) {
  116. - ShowPrintErrorDialogForGenericError();
  117. + if (printer_query->last_status() == mojom::ResultCode::kCanceled) {
  118. + std::move(cancel_job).Run();
  119. }
  120. std::move(callback).Run(nullptr);
  121. return;
  122. @@ -182,9 +196,11 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
  123. : PrintManager(web_contents),
  124. queue_(g_browser_process->print_job_manager()->queue()) {
  125. DCHECK(queue_);
  126. +#if 0
  127. Profile* profile =
  128. Profile::FromBrowserContext(web_contents->GetBrowserContext());
  129. printing_enabled_.Init(prefs::kPrintingEnabled, profile->GetPrefs());
  130. +#endif
  131. }
  132. PrintViewManagerBase::~PrintViewManagerBase() {
  133. @@ -208,12 +224,16 @@ void PrintViewManagerBase::DisableThirdPartyBlocking() {
  134. }
  135. #endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
  136. -bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
  137. +bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
  138. + base::Value::Dict settings,
  139. + CompletionCallback callback) {
  140. if (!StartPrintCommon(rfh)) {
  141. return false;
  142. }
  143. - GetPrintRenderFrame(rfh)->PrintRequestedPages();
  144. + callback_ = std::move(callback);
  145. +
  146. + GetPrintRenderFrame(rfh)->PrintRequestedPages(std::move(settings));
  147. for (auto& observer : GetTestObservers()) {
  148. observer.OnPrintNow(rfh);
  149. @@ -295,7 +315,7 @@ void PrintViewManagerBase::PrintDocument(
  150. const gfx::Size& page_size,
  151. const gfx::Rect& content_area,
  152. const gfx::Point& offsets) {
  153. -#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  154. +#if 0
  155. if (content_analysis_before_printing_document_) {
  156. std::move(content_analysis_before_printing_document_)
  157. .Run(print_data, page_size, content_area, offsets);
  158. @@ -342,12 +362,13 @@ void PrintViewManagerBase::OnDidUpdatePrintableArea(
  159. }
  160. PRINTER_LOG(EVENT) << "Paper printable area updated for vendor id "
  161. << print_settings->requested_media().vendor_id;
  162. - CompleteUpdatePrintSettings(std::move(job_settings),
  163. + CompleteUpdatePrintSettings(nullptr /* printer_query */, std::move(job_settings),
  164. std::move(print_settings), std::move(callback));
  165. }
  166. #endif
  167. void PrintViewManagerBase::CompleteUpdatePrintSettings(
  168. + std::unique_ptr<PrinterQuery> printer_query,
  169. base::Value::Dict job_settings,
  170. std::unique_ptr<PrintSettings> print_settings,
  171. UpdatePrintSettingsCallback callback) {
  172. @@ -355,7 +376,8 @@ void PrintViewManagerBase::CompleteUpdatePrintSettings(
  173. settings->pages = GetPageRangesFromJobSettings(job_settings);
  174. settings->params = mojom::PrintParams::New();
  175. RenderParamsFromPrintSettings(*print_settings, settings->params.get());
  176. - settings->params->document_cookie = PrintSettings::NewCookie();
  177. + settings->params->document_cookie = printer_query ? printer_query->cookie()
  178. + : PrintSettings::NewCookie();
  179. if (!PrintMsgPrintParamsIsValid(*settings->params)) {
  180. mojom::PrinterType printer_type = static_cast<mojom::PrinterType>(
  181. *job_settings.FindInt(kSettingPrinterType));
  182. @@ -367,6 +389,10 @@ void PrintViewManagerBase::CompleteUpdatePrintSettings(
  183. return;
  184. }
  185. + if (printer_query && printer_query->cookie() && printer_query->settings().dpi()) {
  186. + queue_->QueuePrinterQuery(std::move(printer_query));
  187. + }
  188. +
  189. set_cookie(settings->params->document_cookie);
  190. std::move(callback).Run(std::move(settings));
  191. }
  192. @@ -408,7 +434,9 @@ void PrintViewManagerBase::OnPrintSettingsDone(
  193. UnregisterSystemPrintClient();
  194. }
  195. #endif
  196. +#if 0 // Electron does not use Chromium error dialogs
  197. ShowPrintErrorDialogForGenericError();
  198. +#endif
  199. std::move(callback).Run(base::Value("Update settings failed"));
  200. return;
  201. }
  202. @@ -437,7 +465,7 @@ void PrintViewManagerBase::StartLocalPrintJob(
  203. PrinterHandler::PrintCallback callback) {
  204. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  205. -#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  206. +#if 0
  207. // Populating `content_analysis_before_printing_document_` if needed should be
  208. // done first in this function's workflow, this way other code can check if
  209. // content analysis is going to happen and delay starting `print_job_` to
  210. @@ -664,7 +692,7 @@ void PrintViewManagerBase::GetDefaultPrintSettings(
  211. #if BUILDFLAG(ENABLE_OOP_PRINTING)
  212. if (ShouldPrintJobOop() &&
  213. -#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  214. +#if 0
  215. !analyzing_content_ &&
  216. #endif
  217. !query_with_ui_client_id().has_value()) {
  218. @@ -692,7 +720,7 @@ void PrintViewManagerBase::GetDefaultPrintSettings(
  219. // Sometimes it is desired to get the PDF settings as opposed to the settings
  220. // of the default system print driver.
  221. -#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  222. +#if 0
  223. bool want_pdf_settings = analyzing_content_;
  224. #else
  225. bool want_pdf_settings = false;
  226. @@ -736,10 +764,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
  227. // `job_settings` does not yet contain the rasterized PDF dpi, so if the user
  228. // has the print preference set, fetch it for use in
  229. // `PrintSettingsFromJobSettings()`.
  230. - content::BrowserContext* context =
  231. - web_contents() ? web_contents()->GetBrowserContext() : nullptr;
  232. - PrefService* prefs =
  233. - context ? Profile::FromBrowserContext(context)->GetPrefs() : nullptr;
  234. + PrefService* prefs = nullptr;
  235. if (prefs && prefs->HasPrefPath(prefs::kPrintRasterizePdfDpi)) {
  236. int value = prefs->GetInteger(prefs::kPrintRasterizePdfDpi);
  237. if (value > 0)
  238. @@ -764,8 +789,22 @@ void PrintViewManagerBase::UpdatePrintSettings(
  239. }
  240. }
  241. -#if BUILDFLAG(IS_WIN)
  242. - // TODO(crbug.com/40260379): Remove this if the printable areas can be made
  243. + std::unique_ptr<PrinterQuery> query =
  244. + queue_->CreatePrinterQuery(GetCurrentTargetFrame()->GetGlobalId());
  245. + auto* query_ptr = query.get();
  246. + // We need to clone this before calling SetSettings because some environments
  247. + // evaluate job_settings.Clone() first, and some std::move(job_settings) first,
  248. + // for the former things work correctly but for the latter the cloned value is null.
  249. + auto job_settings_copy = job_settings.Clone();
  250. + query_ptr->SetSettings(
  251. + std::move(job_settings_copy),
  252. + base::BindOnce(&PrintViewManagerBase::CompleteUpdatePrintSettings,
  253. + weak_ptr_factory_.GetWeakPtr(), std::move(query),
  254. + std::move(job_settings), std::move(print_settings),
  255. + std::move(callback)));
  256. +
  257. +#if 0 // See https://chromium-review.googlesource.com/412367
  258. + // TODO(crbug.com/1424368): Remove this if the printable areas can be made
  259. // fully available from `PrintBackend::GetPrinterSemanticCapsAndDefaults()`
  260. // for in-browser queries.
  261. if (printer_type == mojom::PrinterType::kLocal) {
  262. @@ -786,8 +825,6 @@ void PrintViewManagerBase::UpdatePrintSettings(
  263. }
  264. #endif
  265. - CompleteUpdatePrintSettings(std::move(job_settings),
  266. - std::move(print_settings), std::move(callback));
  267. }
  268. void PrintViewManagerBase::SetAccessibilityTree(
  269. @@ -803,7 +840,7 @@ void PrintViewManagerBase::SetAccessibilityTree(
  270. void PrintViewManagerBase::IsPrintingEnabled(
  271. IsPrintingEnabledCallback callback) {
  272. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  273. - std::move(callback).Run(GetPrintingEnabledBooleanPref());
  274. + std::move(callback).Run(true);
  275. }
  276. void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
  277. @@ -829,7 +866,7 @@ void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
  278. return;
  279. }
  280. #endif
  281. -#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  282. +#if 0
  283. std::optional<enterprise_connectors::ContentAnalysisDelegate::Data>
  284. scanning_data = enterprise_data_protection::GetPrintAnalysisData(
  285. web_contents(), enterprise_data_protection::PrintScanningContext::
  286. @@ -859,11 +896,9 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie,
  287. // destroyed. In such cases the error notification to the user will
  288. // have already been displayed, and a second message should not be
  289. // shown.
  290. - if (print_job_ && print_job_->document() &&
  291. - print_job_->document()->cookie() == cookie) {
  292. +#if 0 // Electron does not use Chromium error dialogs
  293. ShowPrintErrorDialogForGenericError();
  294. - }
  295. -
  296. +#endif
  297. ReleasePrinterQuery();
  298. }
  299. @@ -875,15 +910,24 @@ void PrintViewManagerBase::RemoveTestObserver(TestObserver& observer) {
  300. test_observers_.RemoveObserver(&observer);
  301. }
  302. +void PrintViewManagerBase::ShowInvalidPrinterSettingsError() {
  303. + if (!callback_.is_null()) {
  304. + printing_status_ = PrintStatus::kInvalid;
  305. + TerminatePrintJob(true);
  306. + }
  307. +}
  308. +
  309. void PrintViewManagerBase::RenderFrameHostStateChanged(
  310. content::RenderFrameHost* render_frame_host,
  311. content::RenderFrameHost::LifecycleState /*old_state*/,
  312. content::RenderFrameHost::LifecycleState new_state) {
  313. +#if 0
  314. if (new_state == content::RenderFrameHost::LifecycleState::kActive &&
  315. render_frame_host->GetProcess()->IsPdf() &&
  316. !render_frame_host->GetMainFrame()->GetParentOrOuterDocument()) {
  317. GetPrintRenderFrame(render_frame_host)->ConnectToPdfRenderer();
  318. }
  319. +#endif
  320. }
  321. void PrintViewManagerBase::RenderFrameDeleted(
  322. @@ -925,13 +969,14 @@ void PrintViewManagerBase::SystemDialogCancelled() {
  323. // System dialog was cancelled. Clean up the print job and notify the
  324. // BackgroundPrintingManager.
  325. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  326. + printing_status_ = PrintStatus::kCanceled;
  327. ReleasePrinterQuery();
  328. TerminatePrintJob(true);
  329. }
  330. #endif
  331. bool PrintViewManagerBase::GetPrintingEnabledBooleanPref() const {
  332. - return printing_enabled_.GetValue();
  333. + return true;
  334. }
  335. void PrintViewManagerBase::OnDocDone(int job_id, PrintedDocument* document) {
  336. @@ -945,18 +990,26 @@ void PrintViewManagerBase::OnJobDone() {
  337. // Printing is done, we don't need it anymore.
  338. // print_job_->is_job_pending() may still be true, depending on the order
  339. // of object registration.
  340. - printing_succeeded_ = true;
  341. + printing_status_ = PrintStatus::kSucceeded;
  342. + ReleasePrintJob();
  343. +}
  344. +
  345. +void PrintViewManagerBase::UserInitCanceled() {
  346. + printing_status_ = PrintStatus::kCanceled;
  347. ReleasePrintJob();
  348. }
  349. void PrintViewManagerBase::OnCanceling() {
  350. + printing_status_ = PrintStatus::kCanceled;
  351. canceling_job_ = true;
  352. }
  353. void PrintViewManagerBase::OnFailed() {
  354. if (!canceling_job_)
  355. + printing_status_ = PrintStatus::kFailed;
  356. +#if 0 // Electron does not use Chromium error dialogs
  357. ShowPrintErrorDialogForGenericError();
  358. -
  359. +#endif
  360. TerminatePrintJob(true);
  361. }
  362. @@ -966,7 +1019,7 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
  363. // Is the document already complete?
  364. if (print_job_->document() && print_job_->document()->IsComplete()) {
  365. - printing_succeeded_ = true;
  366. + printing_status_ = PrintStatus::kSucceeded;
  367. return true;
  368. }
  369. @@ -1019,7 +1072,10 @@ bool PrintViewManagerBase::SetupNewPrintJob(
  370. // Disconnect the current `print_job_`.
  371. auto weak_this = weak_ptr_factory_.GetWeakPtr();
  372. - DisconnectFromCurrentPrintJob();
  373. + if (callback_.is_null()) {
  374. + // Disconnect the current |print_job_| only when calling window.print()
  375. + DisconnectFromCurrentPrintJob();
  376. + }
  377. if (!weak_this)
  378. return false;
  379. @@ -1039,7 +1095,7 @@ bool PrintViewManagerBase::SetupNewPrintJob(
  380. #endif
  381. print_job_->AddObserver(*this);
  382. - printing_succeeded_ = false;
  383. + printing_status_ = PrintStatus::kUnknown;
  384. return true;
  385. }
  386. @@ -1097,7 +1153,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
  387. // Ensure that any residual registration of printing client is released.
  388. // This might be necessary in some abnormal cases, such as the associated
  389. // render process having terminated.
  390. -#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  391. +#if 0
  392. if (!analyzing_content_) {
  393. UnregisterSystemPrintClient();
  394. }
  395. @@ -1107,6 +1163,11 @@ void PrintViewManagerBase::ReleasePrintJob() {
  396. }
  397. #endif
  398. + if (!callback_.is_null()) {
  399. + bool success = printing_status_ == PrintStatus::kSucceeded;
  400. + std::move(callback_).Run(success, PrintReasonFromPrintStatus(printing_status_));
  401. + }
  402. +
  403. if (!print_job_)
  404. return;
  405. @@ -1114,7 +1175,7 @@ void PrintViewManagerBase::ReleasePrintJob() {
  406. // printing_rfh_ should only ever point to a RenderFrameHost with a live
  407. // RenderFrame.
  408. DCHECK(rfh->IsRenderFrameLive());
  409. - GetPrintRenderFrame(rfh)->PrintingDone(printing_succeeded_);
  410. + GetPrintRenderFrame(rfh)->PrintingDone(printing_status_ == PrintStatus::kSucceeded);
  411. }
  412. print_job_->RemoveObserver(*this);
  413. @@ -1156,7 +1217,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
  414. }
  415. bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
  416. - if (print_job_)
  417. + if (print_job_ && print_job_->document())
  418. return true;
  419. if (!cookie) {
  420. @@ -1179,7 +1240,7 @@ bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
  421. return false;
  422. }
  423. -#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  424. +#if 0
  425. // Don't start printing if enterprise checks are being performed to check if
  426. // printing is allowed, or if content analysis is going to take place right
  427. // before starting `print_job_`.
  428. @@ -1310,6 +1371,8 @@ void PrintViewManagerBase::CompleteScriptedPrint(
  429. auto callback_wrapper = base::BindOnce(
  430. &PrintViewManagerBase::ScriptedPrintReply, weak_ptr_factory_.GetWeakPtr(),
  431. std::move(callback), render_process_host->GetID());
  432. + auto cancel_job_wrapper = base::BindOnce(
  433. + &PrintViewManagerBase::UserInitCanceled, weak_ptr_factory_.GetWeakPtr());
  434. #if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
  435. DisableThirdPartyBlocking();
  436. #endif
  437. @@ -1324,10 +1387,10 @@ void PrintViewManagerBase::CompleteScriptedPrint(
  438. params->expected_pages_count, params->has_selection, params->margin_type,
  439. params->is_scripted, !render_process_host->IsPdf(),
  440. base::BindOnce(&OnDidScriptedPrint, queue_, std::move(printer_query),
  441. - std::move(callback_wrapper)));
  442. + std::move(callback_wrapper), std::move(cancel_job_wrapper)));
  443. }
  444. -#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  445. +#if 0
  446. void PrintViewManagerBase::CompletePrintDocumentAfterContentAnalysis(
  447. scoped_refptr<base::RefCountedMemory> print_data,
  448. const gfx::Size& page_size,
  449. diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h
  450. index 1917f8b94962d7a4c83f139623a5f5d352011627..47ef610c43c4dcfee0cf528eb2e6075b579117ee 100644
  451. --- a/chrome/browser/printing/print_view_manager_base.h
  452. +++ b/chrome/browser/printing/print_view_manager_base.h
  453. @@ -52,6 +52,8 @@ class PrinterQuery;
  454. // rollout.
  455. BASE_DECLARE_FEATURE(kCheckPrintRfhIsActive);
  456. +using CompletionCallback = base::OnceCallback<void(bool, const std::string&)>;
  457. +
  458. // Base class for managing the print commands for a WebContents.
  459. class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  460. public:
  461. @@ -87,7 +89,9 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  462. // Prints the current document immediately. Since the rendering is
  463. // asynchronous, the actual printing will not be completed on the return of
  464. // this function. Returns false if printing is impossible at the moment.
  465. - virtual bool PrintNow(content::RenderFrameHost* rfh);
  466. + virtual bool PrintNow(content::RenderFrameHost* rfh,
  467. + base::Value::Dict settings = {},
  468. + CompletionCallback callback = {});
  469. // Like PrintNow(), but for the node under the context menu, instead of the
  470. // entire frame.
  471. @@ -141,8 +145,10 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  472. void IsPrintingEnabled(IsPrintingEnabledCallback callback) override;
  473. void ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
  474. ScriptedPrintCallback callback) override;
  475. + void ShowInvalidPrinterSettingsError() override;
  476. void PrintingFailed(int32_t cookie,
  477. mojom::PrintFailureReason reason) override;
  478. + void UserInitCanceled();
  479. // Adds and removes observers for `PrintViewManagerBase` events. The order in
  480. // which notifications are sent to observers is undefined. Observers must be
  481. @@ -150,6 +156,14 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  482. void AddTestObserver(TestObserver& observer);
  483. void RemoveTestObserver(TestObserver& observer);
  484. + enum class PrintStatus {
  485. + kSucceeded,
  486. + kCanceled,
  487. + kFailed,
  488. + kInvalid,
  489. + kUnknown
  490. + };
  491. +
  492. protected:
  493. #if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  494. using PrintDocumentCallback =
  495. @@ -229,7 +243,7 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  496. mojom::ScriptedPrintParamsPtr params,
  497. ScriptedPrintCallback callback);
  498. -#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  499. +#if 0
  500. // Helper method bound to `content_analysis_before_printing_document_` when
  501. // content analysis should happen right before the document is to be printed.
  502. // This method is virtual for testing purposes.
  503. @@ -293,6 +307,7 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  504. bool success);
  505. #endif
  506. void CompleteUpdatePrintSettings(
  507. + std::unique_ptr<PrinterQuery> printer_query,
  508. base::Value::Dict job_settings,
  509. std::unique_ptr<PrintSettings> print_settings,
  510. UpdatePrintSettingsCallback callback);
  511. @@ -387,8 +402,11 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
  512. // The current RFH that is printing with a system printing dialog.
  513. raw_ptr<content::RenderFrameHost> printing_rfh_ = nullptr;
  514. + // Respond with success of the print job.
  515. + CompletionCallback callback_;
  516. +
  517. // Indication of success of the print job.
  518. - bool printing_succeeded_ = false;
  519. + PrintStatus printing_status_ = PrintStatus::kUnknown;
  520. // Indication that the job is getting canceled.
  521. bool canceling_job_ = false;
  522. diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc
  523. index 402be34ab888cdf834d0fb65de0832e9a8021ced..82ddc92a35d824926c30279e660cc4e86e6f0b09 100644
  524. --- a/chrome/browser/printing/printer_query.cc
  525. +++ b/chrome/browser/printing/printer_query.cc
  526. @@ -355,17 +355,19 @@ void PrinterQuery::UpdatePrintSettings(base::Value::Dict new_settings,
  527. #endif // BUILDFLAG(IS_LINUX) && BUILDFLAG(USE_CUPS)
  528. }
  529. - mojom::ResultCode result;
  530. {
  531. #if BUILDFLAG(IS_WIN)
  532. // Blocking is needed here because Windows printer drivers are oftentimes
  533. // not thread-safe and have to be accessed on the UI thread.
  534. base::ScopedAllowBlocking allow_blocking;
  535. #endif
  536. - result = printing_context_->UpdatePrintSettings(std::move(new_settings));
  537. + // Reset settings from previous print job
  538. + printing_context_->ResetSettings();
  539. + mojom::ResultCode result_code = printing_context_->UseDefaultSettings();
  540. + if (result_code == mojom::ResultCode::kSuccess)
  541. + result_code = printing_context_->UpdatePrintSettings(std::move(new_settings));
  542. + InvokeSettingsCallback(std::move(callback), result_code);
  543. }
  544. -
  545. - InvokeSettingsCallback(std::move(callback), result);
  546. }
  547. #if BUILDFLAG(IS_CHROMEOS)
  548. diff --git a/components/printing/browser/print_manager.cc b/components/printing/browser/print_manager.cc
  549. index 21c81377d32ae8d4185598a7eba88ed1d2063ef0..0767f4e9369e926b1cea99178c1a1975941f1765 100644
  550. --- a/components/printing/browser/print_manager.cc
  551. +++ b/components/printing/browser/print_manager.cc
  552. @@ -47,6 +47,8 @@ void PrintManager::IsPrintingEnabled(IsPrintingEnabledCallback callback) {
  553. std::move(callback).Run(true);
  554. }
  555. +void PrintManager::ShowInvalidPrinterSettingsError() {}
  556. +
  557. void PrintManager::PrintingFailed(int32_t cookie,
  558. mojom::PrintFailureReason reason) {
  559. // Note: Not redundant with cookie checks in the same method in other parts of
  560. diff --git a/components/printing/browser/print_manager.h b/components/printing/browser/print_manager.h
  561. index ca71560874a0189068dd11fbc039f5673bf6bd96..a8551d95e64da2afbc1685b2df8f1fc377c7117b 100644
  562. --- a/components/printing/browser/print_manager.h
  563. +++ b/components/printing/browser/print_manager.h
  564. @@ -48,6 +48,7 @@ class PrintManager : public content::WebContentsObserver,
  565. DidPrintDocumentCallback callback) override;
  566. void IsPrintingEnabled(IsPrintingEnabledCallback callback) override;
  567. void DidShowPrintDialog() override;
  568. + void ShowInvalidPrinterSettingsError() override;
  569. void PrintingFailed(int32_t cookie,
  570. mojom::PrintFailureReason reason) override;
  571. diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom
  572. index 3c2fdc9f9a6c60efc4b0afacbfb83eef55917791..8fd9aff538fa03da6c171927c316d4f611c46da1 100644
  573. --- a/components/printing/common/print.mojom
  574. +++ b/components/printing/common/print.mojom
  575. @@ -303,7 +303,7 @@ union PrintWithParamsResult {
  576. interface PrintRenderFrame {
  577. // Tells the RenderFrame to switch the CSS to print media type, render every
  578. // requested page, and then switch back the CSS to display media type.
  579. - PrintRequestedPages();
  580. + PrintRequestedPages(mojo_base.mojom.DictionaryValue settings);
  581. // Requests the frame to be printed with specified parameters. This is used
  582. // to programmatically produce PDF by request from the browser (e.g. over
  583. @@ -392,6 +392,9 @@ interface PrintManagerHost {
  584. [Sync]
  585. ScriptedPrint(ScriptedPrintParams params) => (PrintPagesParams? settings);
  586. + // Tells the browser that there are invalid printer settings.
  587. + ShowInvalidPrinterSettingsError();
  588. +
  589. // Tells the browser printing failed.
  590. PrintingFailed(int32 cookie, PrintFailureReason reason);
  591. diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
  592. index e1e7623427eccb5f7e4d0caf4394b6ee01357049..a8ace3f66e5961a14726faf537ba428f45939f9b 100644
  593. --- a/components/printing/renderer/print_render_frame_helper.cc
  594. +++ b/components/printing/renderer/print_render_frame_helper.cc
  595. @@ -52,6 +52,7 @@
  596. #include "printing/mojom/print.mojom.h"
  597. #include "printing/page_number.h"
  598. #include "printing/print_job_constants.h"
  599. +#include "printing/print_settings.h"
  600. #include "printing/units.h"
  601. #include "services/metrics/public/cpp/ukm_source_id.h"
  602. #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
  603. @@ -1227,14 +1228,14 @@ void PrintRenderFrameHelper::ScriptedPrint(bool user_initiated) {
  604. }
  605. print_in_progress_ = true;
  606. -
  607. auto weak_this = weak_ptr_factory_.GetWeakPtr();
  608. web_frame->DispatchBeforePrintEvent(/*print_client=*/nullptr);
  609. if (!weak_this) {
  610. return;
  611. }
  612. - Print(web_frame, blink::WebNode(), PrintRequestType::kScripted);
  613. + Print(web_frame, blink::WebNode(), PrintRequestType::kScripted,
  614. + base::Value::Dict());
  615. if (!weak_this) {
  616. return;
  617. }
  618. @@ -1265,12 +1266,14 @@ void PrintRenderFrameHelper::BindPrintRenderFrameReceiver(
  619. receivers_.Add(this, std::move(receiver));
  620. }
  621. -void PrintRenderFrameHelper::PrintRequestedPages() {
  622. - PrintRequestedPagesInternal(/*already_notified_frame=*/false);
  623. +void PrintRenderFrameHelper::PrintRequestedPages(base::Value::Dict settings) {
  624. + PrintRequestedPagesInternal(/*already_notified_frame=*/false,
  625. + std::move(settings));
  626. }
  627. void PrintRenderFrameHelper::PrintRequestedPagesInternal(
  628. - bool already_notified_frame) {
  629. + bool already_notified_frame,
  630. + base::Value::Dict settings) {
  631. ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
  632. if (ipc_nesting_level_ > kAllowedIpcDepthForPrint) {
  633. return;
  634. @@ -1287,9 +1290,10 @@ void PrintRenderFrameHelper::PrintRequestedPagesInternal(
  635. is_loading_ = frame->WillPrintSoon();
  636. if (is_loading_) {
  637. - on_stop_loading_closure_ = base::BindOnce(
  638. - &PrintRenderFrameHelper::PrintRequestedPagesInternal,
  639. - weak_ptr_factory_.GetWeakPtr(), /*already_notified_frame=*/true);
  640. + on_stop_loading_closure_ =
  641. + base::BindOnce(&PrintRenderFrameHelper::PrintRequestedPagesInternal,
  642. + weak_ptr_factory_.GetWeakPtr(),
  643. + /*already_notified_frame=*/true, std::move(settings));
  644. SetupOnStopLoadingTimeout();
  645. return;
  646. }
  647. @@ -1299,7 +1303,7 @@ void PrintRenderFrameHelper::PrintRequestedPagesInternal(
  648. // plugin node and print that instead.
  649. auto plugin = delegate_->GetPdfElement(frame);
  650. - Print(frame, plugin, PrintRequestType::kRegular);
  651. + Print(frame, plugin, PrintRequestType::kRegular, std::move(settings));
  652. if (render_frame_gone_) {
  653. return;
  654. @@ -1455,6 +1459,8 @@ void PrintRenderFrameHelper::PrintPreview(base::Value::Dict settings) {
  655. if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
  656. return;
  657. + blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
  658. + print_preview_context_.InitWithFrame(frame);
  659. print_preview_context_.OnPrintPreview();
  660. #if BUILDFLAG(IS_CHROMEOS_ASH)
  661. @@ -2062,17 +2068,19 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
  662. void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
  663. const blink::WebNode& node,
  664. - PrintRequestType print_request_type) {
  665. + PrintRequestType print_request_type,
  666. + base::Value::Dict settings) {
  667. // If still not finished with earlier print request simply ignore.
  668. if (prep_frame_view_)
  669. return;
  670. + bool silent = settings.FindBool("silent").value_or(false);
  671. FrameReference frame_ref(frame);
  672. - if (!InitPrintSettings(frame, node)) {
  673. + if (!InitPrintSettings(frame, node, std::move(settings))) {
  674. // Browser triggered this code path. It already knows about the failure.
  675. notify_browser_of_print_failure_ = false;
  676. -
  677. + GetPrintManagerHost()->ShowInvalidPrinterSettingsError();
  678. DidFinishPrinting(PrintingResult::kFailPrintInit);
  679. return;
  680. }
  681. @@ -2093,8 +2101,15 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
  682. print_pages_params_->params->print_scaling_option;
  683. auto self = weak_ptr_factory_.GetWeakPtr();
  684. - mojom::PrintPagesParamsPtr print_settings = GetPrintSettingsFromUser(
  685. + mojom::PrintPagesParamsPtr print_settings;
  686. +
  687. + if (silent) {
  688. + print_settings = mojom::PrintPagesParams::New();
  689. + print_settings->params = print_pages_params_->params->Clone();
  690. + } else {
  691. + print_settings = GetPrintSettingsFromUser(
  692. frame_ref.GetFrame(), node, expected_page_count, print_request_type);
  693. + }
  694. // Check if `this` is still valid.
  695. if (!self)
  696. return;
  697. @@ -2359,29 +2374,37 @@ void PrintRenderFrameHelper::IPCProcessed() {
  698. }
  699. bool PrintRenderFrameHelper::InitPrintSettings(blink::WebLocalFrame* frame,
  700. - const blink::WebNode& node) {
  701. + const blink::WebNode& node,
  702. + base::Value::Dict new_settings) {
  703. // Reset to default values.
  704. ignore_css_margins_ = false;
  705. - mojom::PrintPagesParams settings;
  706. - GetPrintManagerHost()->GetDefaultPrintSettings(&settings.params);
  707. + mojom::PrintPagesParamsPtr settings;
  708. + if (new_settings.empty()) {
  709. + settings = mojom::PrintPagesParams::New();
  710. + settings->params = mojom::PrintParams::New();
  711. + GetPrintManagerHost()->GetDefaultPrintSettings(&settings->params);
  712. + } else {
  713. + GetPrintManagerHost()->UpdatePrintSettings(
  714. + std::move(new_settings), &settings);
  715. + }
  716. // Check if the printer returned any settings, if the settings are null,
  717. // assume there are no printer drivers configured. So safely terminate.
  718. - if (!settings.params) {
  719. + if (!settings || !settings->params) {
  720. // Caller will reset `print_pages_params_`.
  721. return false;
  722. }
  723. bool center_on_paper = !IsPrintingPdfFrame(frame, node);
  724. - settings.params->print_scaling_option =
  725. + settings->params->print_scaling_option =
  726. center_on_paper ? mojom::PrintScalingOption::kCenterShrinkToFitPaper
  727. : mojom::PrintScalingOption::kSourceSize;
  728. - RecordDebugEvent(settings.params->printed_doc_type ==
  729. + RecordDebugEvent(settings->params->printed_doc_type ==
  730. mojom::SkiaDocumentType::kMSKP
  731. ? DebugEvent::kSetPrintSettings5
  732. : DebugEvent::kSetPrintSettings6);
  733. - SetPrintPagesParams(settings);
  734. + SetPrintPagesParams(*settings);
  735. return true;
  736. }
  737. diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
  738. index b8c803184f267d87696c4e72c3d993ff3b69d95b..7278dfae56305cc8669fc2240563450f96bb6f52 100644
  739. --- a/components/printing/renderer/print_render_frame_helper.h
  740. +++ b/components/printing/renderer/print_render_frame_helper.h
  741. @@ -259,7 +259,7 @@ class PrintRenderFrameHelper
  742. mojo::PendingAssociatedReceiver<mojom::PrintRenderFrame> receiver);
  743. // printing::mojom::PrintRenderFrame:
  744. - void PrintRequestedPages() override;
  745. + void PrintRequestedPages(base::Value::Dict settings) override;
  746. void PrintWithParams(mojom::PrintPagesParamsPtr params,
  747. PrintWithParamsCallback callback) override;
  748. #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
  749. @@ -326,7 +326,8 @@ class PrintRenderFrameHelper
  750. // WARNING: |this| may be gone after this method returns.
  751. void Print(blink::WebLocalFrame* frame,
  752. const blink::WebNode& node,
  753. - PrintRequestType print_request_type);
  754. + PrintRequestType print_request_type,
  755. + base::Value::Dict settings = {});
  756. // Notification when printing is done - signal tear-down/free resources.
  757. void DidFinishPrinting(PrintingResult result);
  758. @@ -336,7 +337,8 @@ class PrintRenderFrameHelper
  759. // Initialize print page settings with default settings.
  760. // Used only for native printing workflow.
  761. bool InitPrintSettings(blink::WebLocalFrame* frame,
  762. - const blink::WebNode& node);
  763. + const blink::WebNode& node,
  764. + base::Value::Dict new_settings);
  765. // Calculate number of pages in source document.
  766. uint32_t CalculateNumberOfPages(blink::WebLocalFrame* frame,
  767. @@ -634,7 +636,8 @@ class PrintRenderFrameHelper
  768. };
  769. void SetupOnStopLoadingTimeout();
  770. - void PrintRequestedPagesInternal(bool already_notified_frame);
  771. + void PrintRequestedPagesInternal(bool already_notified_frame,
  772. + base::Value::Dict settings);
  773. ScriptingThrottler scripting_throttler_;
  774. diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
  775. index 31c9a53d5c7f09a7326ef57753b4a49f0239a7f8..7e913765d72087d57165efe59bca70584f43c836 100644
  776. --- a/content/browser/BUILD.gn
  777. +++ b/content/browser/BUILD.gn
  778. @@ -3041,8 +3041,9 @@ source_set("browser") {
  779. "//ppapi/shared_impl",
  780. ]
  781. - assert(enable_printing)
  782. - deps += [ "//printing" ]
  783. + if (enable_printing) {
  784. + deps += [ "//printing" ]
  785. + }
  786. if (is_chromeos) {
  787. sources += [
  788. diff --git a/printing/printing_context.cc b/printing/printing_context.cc
  789. index 0bb34c4715224a0cef10465778db946f299ac513..c70803a5737676eec498dd18074a47ffabac62c0 100644
  790. --- a/printing/printing_context.cc
  791. +++ b/printing/printing_context.cc
  792. @@ -154,7 +154,6 @@ void PrintingContext::UsePdfSettings() {
  793. mojom::ResultCode PrintingContext::UpdatePrintSettings(
  794. base::Value::Dict job_settings) {
  795. - ResetSettings();
  796. {
  797. std::unique_ptr<PrintSettings> settings =
  798. PrintSettingsFromJobSettings(job_settings);
  799. diff --git a/printing/printing_context.h b/printing/printing_context.h
  800. index 63f170c95050416c595e62f4c460c4cd6b7dbd1c..157e3d046889f9c63fdf0fd5d503890fb82c038d 100644
  801. --- a/printing/printing_context.h
  802. +++ b/printing/printing_context.h
  803. @@ -206,6 +206,9 @@ class COMPONENT_EXPORT(PRINTING) PrintingContext {
  804. bool PrintingAborted() const { return abort_printing_; }
  805. + // Reinitializes the settings for object reuse.
  806. + void ResetSettings();
  807. +
  808. int job_id() const { return job_id_; }
  809. #if BUILDFLAG(ENABLE_OOP_PRINTING)
  810. @@ -224,9 +227,6 @@ class COMPONENT_EXPORT(PRINTING) PrintingContext {
  811. Delegate* delegate,
  812. ProcessBehavior process_behavior);
  813. - // Reinitializes the settings for object reuse.
  814. - void ResetSettings();
  815. -
  816. // Does bookkeeping when an error occurs.
  817. virtual mojom::ResultCode OnError();