Changed PrintRenderFrame.PrintWithParams mojo interface to use callback.

This method reported results via client interfaces DidPrintDocument and
PrintingFailed which made it difficult to use for CDP Page.printToPdf
implementation.

This CL changes PrintWithParams so that it reports results using
a callback that is specified at the call site.

Bug: 1240796
Change-Id: I9ae59719eeff28d3ca06ced0b6c9afa8d87a2b23
Cq-Include-Trybots: luci.chromium.try:linux-headless-shell-rel
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3761203
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Emily Stark <estark@chromium.org>
Commit-Queue: Peter Kvitek <kvitekp@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1024912}
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
index b2bd74f..f3c3f85 100644
--- a/chrome/browser/ui/webui/print_preview/fake_print_render_frame.cc
+++ b/chrome/browser/ui/webui/print_preview/fake_print_render_frame.cc
@@ -23,7 +23,8 @@
 
 void FakePrintRenderFrame::PrintRequestedPages() {}
 
-void FakePrintRenderFrame::PrintWithParams(mojom::PrintPagesParamsPtr params) {
+void FakePrintRenderFrame::PrintWithParams(mojom::PrintPagesParamsPtr params,
+                                           PrintWithParamsCallback callback) {
   NOTREACHED();
 }
 
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
index 42f9f296..0e788384 100644
--- a/chrome/browser/ui/webui/print_preview/fake_print_render_frame.h
+++ b/chrome/browser/ui/webui/print_preview/fake_print_render_frame.h
@@ -26,7 +26,8 @@
  private:
   // printing::mojom::PrintRenderFrame:
   void PrintRequestedPages() override;
-  void PrintWithParams(mojom::PrintPagesParamsPtr params) override;
+  void PrintWithParams(mojom::PrintPagesParamsPtr params,
+                       PrintWithParamsCallback callback) override;
   void PrintForSystemDialog() override;
   void SetPrintPreviewUI(
       mojo::PendingAssociatedRemote<mojom::PrintPreviewUI> preview) override;
diff --git a/components/printing/browser/print_to_pdf/pdf_print_manager.cc b/components/printing/browser/print_to_pdf/pdf_print_manager.cc
index 82591f8..4f49a65e 100644
--- a/components/printing/browser/print_to_pdf/pdf_print_manager.cc
+++ b/components/printing/browser/print_to_pdf/pdf_print_manager.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/bind.h"
 #include "build/build_config.h"
 #include "components/printing/browser/print_to_pdf/pdf_print_utils.h"
 #include "printing/mojom/print.mojom.h"
@@ -132,7 +133,39 @@
   set_cookie(print_pages_params->params->document_cookie);
   callback_ = std::move(callback);
 
-  GetPrintRenderFrame(rfh)->PrintWithParams(std::move(print_pages_params));
+  // There is no need for a weak pointer here since the mojo proxy is held
+  // in the base class. If we're gone, mojo will discard the callback.
+  GetPrintRenderFrame(rfh)->PrintWithParams(
+      std::move(print_pages_params),
+      base::BindOnce(&PdfPrintManager::OnDidPrintWithParams,
+                     base::Unretained(this)));
+}
+
+void PdfPrintManager::OnDidPrintWithParams(
+    printing::mojom::PrintWithParamsResultPtr result) {
+  if (result->is_failure_reason()) {
+    switch (result->get_failure_reason()) {
+      case printing::mojom::PrintFailureReason::kGeneralFailure:
+        ReleaseJob(PRINTING_FAILED);
+        return;
+      case printing::mojom::PrintFailureReason::kInvalidPageRange:
+        ReleaseJob(PAGE_COUNT_EXCEEDED);
+        return;
+    }
+  }
+
+  auto& content = *result->get_params()->content;
+  if (!content.metafile_data_region.IsValid()) {
+    ReleaseJob(INVALID_MEMORY_HANDLE);
+    return;
+  }
+  base::ReadOnlySharedMemoryMapping map = content.metafile_data_region.Map();
+  if (!map.IsValid()) {
+    ReleaseJob(METAFILE_MAP_ERROR);
+    return;
+  }
+  data_ = std::string(static_cast<const char*>(map.memory()), map.size());
+  ReleaseJob(PRINT_SUCCESS);
 }
 
 void PdfPrintManager::GetDefaultPrintSettings(
@@ -154,14 +187,6 @@
   ReleaseJob(INVALID_PRINTER_SETTINGS);
 }
 
-void PdfPrintManager::PrintingFailed(
-    int32_t cookie,
-    printing::mojom::PrintFailureReason reason) {
-  ReleaseJob(reason == printing::mojom::PrintFailureReason::kInvalidPageRange
-                 ? PAGE_COUNT_EXCEEDED
-                 : PRINTING_FAILED);
-}
-
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 void PdfPrintManager::UpdatePrintSettings(
     int32_t cookie,
@@ -231,26 +256,6 @@
   Reset();
 }
 
-void PdfPrintManager::DidPrintDocument(
-    printing::mojom::DidPrintDocumentParamsPtr params,
-    DidPrintDocumentCallback callback) {
-  auto& content = *params->content;
-  if (!content.metafile_data_region.IsValid()) {
-    ReleaseJob(INVALID_MEMORY_HANDLE);
-    std::move(callback).Run(false);
-    return;
-  }
-  base::ReadOnlySharedMemoryMapping map = content.metafile_data_region.Map();
-  if (!map.IsValid()) {
-    ReleaseJob(METAFILE_MAP_ERROR);
-    std::move(callback).Run(false);
-    return;
-  }
-  data_ = std::string(static_cast<const char*>(map.memory()), map.size());
-  std::move(callback).Run(true);
-  ReleaseJob(PRINT_SUCCESS);
-}
-
 void PdfPrintManager::Reset() {
   printing_rfh_ = nullptr;
   callback_.Reset();
diff --git a/components/printing/browser/print_to_pdf/pdf_print_manager.h b/components/printing/browser/print_to_pdf/pdf_print_manager.h
index bb2508e2..b7bb578 100644
--- a/components/printing/browser/print_to_pdf/pdf_print_manager.h
+++ b/components/printing/browser/print_to_pdf/pdf_print_manager.h
@@ -60,22 +60,21 @@
                   PrintToPdfCallback callback);
 
  private:
-  explicit PdfPrintManager(content::WebContents* web_contents);
   friend class content::WebContentsUserData<PdfPrintManager>;
 
+  explicit PdfPrintManager(content::WebContents* web_contents);
+
+  void OnDidPrintWithParams(printing::mojom::PrintWithParamsResultPtr result);
+
   // WebContentsObserver overrides (via PrintManager):
   void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
 
   // printing::mojom::PrintManagerHost:
-  void DidPrintDocument(printing::mojom::DidPrintDocumentParamsPtr params,
-                        DidPrintDocumentCallback callback) override;
   void GetDefaultPrintSettings(
       GetDefaultPrintSettingsCallback callback) override;
   void ScriptedPrint(printing::mojom::ScriptedPrintParamsPtr params,
                      ScriptedPrintCallback callback) override;
   void ShowInvalidPrinterSettingsError() override;
-  void PrintingFailed(int32_t cookie,
-                      printing::mojom::PrintFailureReason reason) override;
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
   void UpdatePrintSettings(int32_t cookie,
                            base::Value::Dict job_settings,
diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom
index f2c17a8f..95d9f190 100644
--- a/components/printing/common/print.mojom
+++ b/components/printing/common/print.mojom
@@ -275,6 +275,11 @@
   kInvalidPageRange,
 };
 
+union PrintWithParamsResult {
+  DidPrintDocumentParams params;
+  PrintFailureReason failure_reason;
+};
+
 // Render process interface exposed to the browser to handle most of the
 // printing grunt work for RenderView.
 interface PrintRenderFrame {
@@ -289,7 +294,8 @@
   // interactive print preview -- the final print settings are supplied by
   // the caller and printing is completed without further round-trips to the
   // browser.
-  PrintWithParams(PrintPagesParams params);
+  PrintWithParams(PrintPagesParams params)
+      => (PrintWithParamsResult result);
 
   // Tells the RenderFrame to switch the CSS to print media type, render every
   // requested page using the print preview document's frame/node, and then
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index bb0a934f..0766270 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -1334,19 +1334,26 @@
 }
 
 void PrintRenderFrameHelper::PrintWithParams(
-    mojom::PrintPagesParamsPtr settings) {
+    mojom::PrintPagesParamsPtr settings,
+    PrintWithParamsCallback callback) {
   DCHECK(!settings->params->dpi.IsEmpty());
   DCHECK(settings->params->document_cookie);
 
   ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
-  if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
+  if (ipc_nesting_level_ > kAllowedIpcDepthForPrint) {
+    std::move(callback).Run(mojom::PrintWithParamsResult::NewFailureReason(
+        mojom::PrintFailureReason::kGeneralFailure));
     return;
+  }
 
   blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
   frame->DispatchBeforePrintEvent(/*print_client=*/nullptr);
   // Don't print if the RenderFrame is gone.
-  if (render_frame_gone_)
+  if (render_frame_gone_) {
+    std::move(callback).Run(mojom::PrintWithParamsResult::NewFailureReason(
+        mojom::PrintFailureReason::kGeneralFailure));
     return;
+  }
 
   // If we are printing a frame with an internal PDF plugin element, find the
   // plugin node and print that instead.
@@ -1361,6 +1368,10 @@
   SetPrintPagesParams(*settings);
   prep_frame_view_ = std::make_unique<PrepareFrameAndViewForPrint>(
       *settings->params, frame, plugin_node, /* ignore_css_margins=*/false);
+
+  CHECK(!print_with_params_callback_);
+  print_with_params_callback_ = std::move(callback);
+
   PrintPages();
   FinishFramePrinting();
 
@@ -2126,6 +2137,19 @@
 }
 
 void PrintRenderFrameHelper::DidFinishPrinting(PrintingResult result) {
+  // Code in PrintPagesNative() handles the success case firing the callback,
+  // so if we get here with the pending callback it must be the failure case.
+  if (print_with_params_callback_) {
+    DCHECK_NE(result, OK);
+    std::move(print_with_params_callback_)
+        .Run(mojom::PrintWithParamsResult::NewFailureReason(
+            result == INVALID_PAGE_RANGE
+                ? mojom::PrintFailureReason::kInvalidPageRange
+                : mojom::PrintFailureReason::kGeneralFailure));
+    Reset();
+    return;
+  }
+
   int cookie =
       print_pages_params_ ? print_pages_params_->params->document_cookie : 0;
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
@@ -2172,6 +2196,11 @@
       break;
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
   }
+
+  Reset();
+}
+
+void PrintRenderFrameHelper::Reset() {
   prep_frame_view_.reset();
   print_pages_params_.reset();
   notify_browser_of_print_failure_ = true;
@@ -2285,6 +2314,13 @@
 #if BUILDFLAG(IS_WIN)
   page_params->physical_offsets = printer_printable_area_.origin();
 #endif
+
+  if (print_with_params_callback_) {
+    std::move(print_with_params_callback_)
+        .Run(mojom::PrintWithParamsResult::NewParams(std::move(page_params)));
+    return true;
+  }
+
   bool completed = false;
   GetPrintManagerHost()->DidPrintDocument(std::move(page_params), &completed);
   return completed;
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
index c2bf286..6602654 100644
--- a/components/printing/renderer/print_render_frame_helper.h
+++ b/components/printing/renderer/print_render_frame_helper.h
@@ -256,7 +256,8 @@
 
   // printing::mojom::PrintRenderFrame:
   void PrintRequestedPages() override;
-  void PrintWithParams(mojom::PrintPagesParamsPtr params) override;
+  void PrintWithParams(mojom::PrintPagesParamsPtr params,
+                       PrintWithParamsCallback callback) override;
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
   void PrintForSystemDialog() override;
   void SetPrintPreviewUI(
@@ -467,6 +468,9 @@
   void QuitScriptedPrintPreviewRunLoop();
   void QuitGetPrintSettingsFromUserRunLoop();
 
+  // Resets internal state
+  void Reset();
+
   // WebView used only to print the selection.
   std::unique_ptr<PrepareFrameAndViewForPrint> prep_frame_view_;
   bool reset_prep_frame_view_ = false;
@@ -694,6 +698,9 @@
   //   parameters so that it can be invoked after DidStopLoading.
   base::OnceClosure on_stop_loading_closure_;
 
+  // This is used to report PrintWithParams() call result.
+  PrintWithParamsCallback print_with_params_callback_;
+
   // Stores the quit closures of Mojo responses.
   scoped_refptr<ClosuresForMojoResponse> closures_for_mojo_responses_;