Print Preview Handler: Fix renderer crashes

- Ensure that messages intended for a previous instance of
PrintPreviewUI are dropped and not forwarded to the UI.
- Track request IDs in messages that resolve or reject preview
callbacks and maintain a map instead of a queue, since with the
addition of the PDF compositor service requests may not be
returned in the order they were received.
- Split more conditionals to improve stack traces in future.

Bug: 827056
Change-Id: I8a194a480be780ce4cf0a8544f60d9abe502bdf1
Reviewed-on: https://chromium-review.googlesource.com/1085747
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#566911}
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc
index e891e27..e1613a9 100644
--- a/chrome/browser/printing/print_preview_message_handler.cc
+++ b/chrome/browser/printing/print_preview_message_handler.cc
@@ -90,11 +90,15 @@
   return dialog_controller->GetPrintPreviewForContents(web_contents());
 }
 
-PrintPreviewUI* PrintPreviewMessageHandler::GetPrintPreviewUI() {
+PrintPreviewUI* PrintPreviewMessageHandler::GetPrintPreviewUI(
+    int preview_ui_id) {
   WebContents* dialog = GetPrintPreviewDialog();
   if (!dialog || !dialog->GetWebUI())
     return nullptr;
-  return static_cast<PrintPreviewUI*>(dialog->GetWebUI()->GetController());
+  PrintPreviewUI* preview_ui =
+      static_cast<PrintPreviewUI*>(dialog->GetWebUI()->GetController());
+  return preview_ui->GetIDForPrintPreviewUI() == preview_ui_id ? preview_ui
+                                                               : nullptr;
 }
 
 void PrintPreviewMessageHandler::OnRequestPrintPreview(
@@ -109,29 +113,31 @@
 }
 
 void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(
-    const PrintHostMsg_DidGetPreviewPageCount_Params& params) {
+    const PrintHostMsg_DidGetPreviewPageCount_Params& params,
+    const PrintHostMsg_PreviewIds& ids) {
   if (params.page_count <= 0) {
     NOTREACHED();
     return;
   }
 
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
 
   print_preview_ui->ClearAllPreviewData();
-  print_preview_ui->OnDidGetPreviewPageCount(params);
+  print_preview_ui->OnDidGetPreviewPageCount(params, ids.request_id);
 }
 
 void PrintPreviewMessageHandler::OnDidPreviewPage(
     content::RenderFrameHost* render_frame_host,
-    const PrintHostMsg_DidPreviewPage_Params& params) {
+    const PrintHostMsg_DidPreviewPage_Params& params,
+    const PrintHostMsg_PreviewIds& ids) {
   int page_number = params.page_number;
   const PrintHostMsg_DidPrintContent_Params& content = params.content;
   if (page_number < FIRST_PAGE_INDEX || !content.data_size)
     return;
 
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
 
@@ -146,17 +152,18 @@
         content.subframe_content_info,
         base::BindOnce(&PrintPreviewMessageHandler::OnCompositePdfPageDone,
                        weak_ptr_factory_.GetWeakPtr(), params.page_number,
-                       params.preview_request_id));
+                       ids));
   } else {
     NotifyUIPreviewPageReady(
-        page_number, params.preview_request_id,
+        page_number, ids,
         GetDataFromHandle(content.metafile_data_handle, content.data_size));
   }
 }
 
 void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
     content::RenderFrameHost* render_frame_host,
-    const PrintHostMsg_DidPreviewDocument_Params& params) {
+    const PrintHostMsg_DidPreviewDocument_Params& params,
+    const PrintHostMsg_PreviewIds& ids) {
   // Always try to stop the worker.
   StopWorker(params.document_cookie);
 
@@ -165,7 +172,7 @@
     return;
   }
 
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
 
@@ -179,94 +186,111 @@
         content.data_size, content.subframe_content_info,
         base::BindOnce(&PrintPreviewMessageHandler::OnCompositePdfDocumentDone,
                        weak_ptr_factory_.GetWeakPtr(),
-                       params.expected_pages_count, params.preview_request_id));
+                       params.expected_pages_count, ids));
   } else {
     NotifyUIPreviewDocumentReady(
-        params.expected_pages_count, params.preview_request_id,
+        params.expected_pages_count, ids,
         GetDataFromHandle(content.metafile_data_handle, content.data_size));
   }
 }
 
-void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) {
+void PrintPreviewMessageHandler::OnPrintPreviewFailed(
+    int document_cookie,
+    const PrintHostMsg_PreviewIds& ids) {
   StopWorker(document_cookie);
 
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
-  print_preview_ui->OnPrintPreviewFailed();
+  print_preview_ui->OnPrintPreviewFailed(ids.request_id);
 }
 
 void PrintPreviewMessageHandler::OnDidGetDefaultPageLayout(
     const PageSizeMargins& page_layout_in_points,
     const gfx::Rect& printable_area_in_points,
-    bool has_custom_page_size_style) {
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+    bool has_custom_page_size_style,
+    const PrintHostMsg_PreviewIds& ids) {
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
-  print_preview_ui->OnDidGetDefaultPageLayout(page_layout_in_points,
-                                              printable_area_in_points,
-                                              has_custom_page_size_style);
+
+  print_preview_ui->OnDidGetDefaultPageLayout(
+      page_layout_in_points, printable_area_in_points,
+      has_custom_page_size_style, ids.request_id);
 }
 
-void PrintPreviewMessageHandler::OnPrintPreviewCancelled(int document_cookie) {
+void PrintPreviewMessageHandler::OnPrintPreviewCancelled(
+    int document_cookie,
+    const PrintHostMsg_PreviewIds& ids) {
   // Always need to stop the worker.
   StopWorker(document_cookie);
 
   // Notify UI
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
-  print_preview_ui->OnPrintPreviewCancelled();
+  print_preview_ui->OnPrintPreviewCancelled(ids.request_id);
 }
 
-void PrintPreviewMessageHandler::OnInvalidPrinterSettings(int document_cookie) {
+void PrintPreviewMessageHandler::OnInvalidPrinterSettings(
+    int document_cookie,
+    const PrintHostMsg_PreviewIds& ids) {
   StopWorker(document_cookie);
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
-  print_preview_ui->OnInvalidPrinterSettings();
+  print_preview_ui->OnInvalidPrinterSettings(ids.request_id);
 }
 
 void PrintPreviewMessageHandler::OnSetOptionsFromDocument(
-    const PrintHostMsg_SetOptionsFromDocument_Params& params) {
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+    const PrintHostMsg_SetOptionsFromDocument_Params& params,
+    const PrintHostMsg_PreviewIds& ids) {
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
-  print_preview_ui->OnSetOptionsFromDocument(params);
+  print_preview_ui->OnSetOptionsFromDocument(params, ids.request_id);
 }
 
 void PrintPreviewMessageHandler::NotifyUIPreviewPageReady(
     int page_number,
-    int request_id,
+    const PrintHostMsg_PreviewIds& ids,
     scoped_refptr<base::RefCountedMemory> data_bytes) {
   DCHECK(data_bytes);
 
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
+
+  // Don't bother notifying the UI if this request has been cancelled already.
+  bool cancel = false;
+  PrintPreviewUI::GetCurrentPrintPreviewStatus(ids, &cancel);
+  if (cancel)
+    return;
+
   print_preview_ui->SetPrintPreviewDataForIndex(page_number,
                                                 std::move(data_bytes));
-  print_preview_ui->OnDidPreviewPage(page_number, request_id);
+  print_preview_ui->OnDidPreviewPage(page_number, ids.request_id);
 }
 
 void PrintPreviewMessageHandler::NotifyUIPreviewDocumentReady(
     int page_count,
-    int request_id,
+    const PrintHostMsg_PreviewIds& ids,
     scoped_refptr<base::RefCountedMemory> data_bytes) {
   if (!data_bytes || !data_bytes->size())
     return;
 
-  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
+  PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
   if (!print_preview_ui)
     return;
+
   print_preview_ui->SetPrintPreviewDataForIndex(COMPLETE_PREVIEW_DOCUMENT_INDEX,
                                                 std::move(data_bytes));
-  print_preview_ui->OnPreviewDataIsAvailable(page_count, request_id);
+  print_preview_ui->OnPreviewDataIsAvailable(page_count, ids.request_id);
 }
 
 void PrintPreviewMessageHandler::OnCompositePdfPageDone(
     int page_number,
-    int request_id,
+    const PrintHostMsg_PreviewIds& ids,
     mojom::PdfCompositor::Status status,
     base::ReadOnlySharedMemoryRegion region) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -275,13 +299,13 @@
     return;
   }
   NotifyUIPreviewPageReady(
-      page_number, request_id,
+      page_number, ids,
       base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region));
 }
 
 void PrintPreviewMessageHandler::OnCompositePdfDocumentDone(
     int page_count,
-    int request_id,
+    const PrintHostMsg_PreviewIds& ids,
     mojom::PdfCompositor::Status status,
     base::ReadOnlySharedMemoryRegion region) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -290,7 +314,7 @@
     return;
   }
   NotifyUIPreviewDocumentReady(
-      page_count, request_id,
+      page_count, ids,
       base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region));
 }
 
diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h
index 0c3938ac..6356792 100644
--- a/chrome/browser/printing/print_preview_message_handler.h
+++ b/chrome/browser/printing/print_preview_message_handler.h
@@ -18,6 +18,7 @@
 struct PrintHostMsg_DidGetPreviewPageCount_Params;
 struct PrintHostMsg_DidPreviewDocument_Params;
 struct PrintHostMsg_DidPreviewPage_Params;
+struct PrintHostMsg_PreviewIds;
 struct PrintHostMsg_RequestPrintPreview_Params;
 struct PrintHostMsg_SetOptionsFromDocument_Params;
 
@@ -53,8 +54,9 @@
   // observed.
   content::WebContents* GetPrintPreviewDialog();
 
-  // Gets the PrintPreviewUI associated with the WebContents being observed.
-  PrintPreviewUI* GetPrintPreviewUI();
+  // Gets the PrintPreviewUI associated with the WebContents being observed and
+  // verifies that its id matches |preview_ui_id|.
+  PrintPreviewUI* GetPrintPreviewUI(int preview_ui_id);
 
   // Message handlers.
   void OnRequestPrintPreview(
@@ -62,36 +64,44 @@
       const PrintHostMsg_RequestPrintPreview_Params& params);
   void OnDidGetDefaultPageLayout(const PageSizeMargins& page_layout_in_points,
                                  const gfx::Rect& printable_area_in_points,
-                                 bool has_custom_page_size_style);
+                                 bool has_custom_page_size_style,
+                                 const PrintHostMsg_PreviewIds& ids);
   void OnDidGetPreviewPageCount(
-      const PrintHostMsg_DidGetPreviewPageCount_Params& params);
+      const PrintHostMsg_DidGetPreviewPageCount_Params& params,
+      const PrintHostMsg_PreviewIds& ids);
   void OnDidPreviewPage(content::RenderFrameHost* render_frame_host,
-                        const PrintHostMsg_DidPreviewPage_Params& params);
+                        const PrintHostMsg_DidPreviewPage_Params& params,
+                        const PrintHostMsg_PreviewIds& ids);
   void OnMetafileReadyForPrinting(
       content::RenderFrameHost* render_frame_host,
-      const PrintHostMsg_DidPreviewDocument_Params& params);
-  void OnPrintPreviewFailed(int document_cookie);
-  void OnPrintPreviewCancelled(int document_cookie);
-  void OnInvalidPrinterSettings(int document_cookie);
+      const PrintHostMsg_DidPreviewDocument_Params& params,
+      const PrintHostMsg_PreviewIds& ids);
+  void OnPrintPreviewFailed(int document_cookie,
+                            const PrintHostMsg_PreviewIds& ids);
+  void OnPrintPreviewCancelled(int document_cookie,
+                               const PrintHostMsg_PreviewIds& ids);
+  void OnInvalidPrinterSettings(int document_cookie,
+                                const PrintHostMsg_PreviewIds& ids);
   void OnSetOptionsFromDocument(
-      const PrintHostMsg_SetOptionsFromDocument_Params& params);
+      const PrintHostMsg_SetOptionsFromDocument_Params& params,
+      const PrintHostMsg_PreviewIds& ids);
 
   void NotifyUIPreviewPageReady(
       int page_number,
-      int request_id,
+      const PrintHostMsg_PreviewIds& ids,
       scoped_refptr<base::RefCountedMemory> data_bytes);
   void NotifyUIPreviewDocumentReady(
       int page_count,
-      int request_id,
+      const PrintHostMsg_PreviewIds& ids,
       scoped_refptr<base::RefCountedMemory> data_bytes);
 
   // Callbacks for pdf compositor client.
   void OnCompositePdfPageDone(int page_number,
-                              int request_id,
+                              const PrintHostMsg_PreviewIds& ids,
                               mojom::PdfCompositor::Status status,
                               base::ReadOnlySharedMemoryRegion region);
   void OnCompositePdfDocumentDone(int page_count,
-                                  int request_id,
+                                  const PrintHostMsg_PreviewIds& ids,
                                   mojom::PdfCompositor::Status status,
                                   base::ReadOnlySharedMemoryRegion region);
 
diff --git a/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
index 999a5994..e8f0cfb 100644
--- a/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
+++ b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
@@ -270,7 +270,8 @@
   // Called when the observer gets the IPC message stating that the page count
   // is ready.
   void OnDidGetPreviewPageCount(
-        const PrintHostMsg_DidGetPreviewPageCount_Params &params) {
+      const PrintHostMsg_DidGetPreviewPageCount_Params& params,
+      const PrintHostMsg_PreviewIds& ids) {
     WebContents* web_contents = GetDialog();
     ASSERT_TRUE(web_contents);
     Observe(web_contents);
diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc
index a976099..54866fd 100644
--- a/chrome/browser/printing/printing_message_filter.cc
+++ b/chrome/browser/printing/printing_message_filter.cc
@@ -362,12 +362,9 @@
 }
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
-void PrintingMessageFilter::OnCheckForCancel(int32_t preview_ui_id,
-                                             int preview_request_id,
+void PrintingMessageFilter::OnCheckForCancel(const PrintHostMsg_PreviewIds& ids,
                                              bool* cancel) {
-  PrintPreviewUI::GetCurrentPrintPreviewStatus(preview_ui_id,
-                                               preview_request_id,
-                                               cancel);
+  PrintPreviewUI::GetCurrentPrintPreviewStatus(ids, cancel);
 }
 #endif
 
diff --git a/chrome/browser/printing/printing_message_filter.h b/chrome/browser/printing/printing_message_filter.h
index 8dc442ca..a881a85 100644
--- a/chrome/browser/printing/printing_message_filter.h
+++ b/chrome/browser/printing/printing_message_filter.h
@@ -18,6 +18,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "printing/buildflags/buildflags.h"
 
+struct PrintHostMsg_PreviewIds;
 struct PrintHostMsg_ScriptedPrint_Params;
 class Profile;
 
@@ -94,9 +95,7 @@
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
   // Check to see if print preview has been cancelled.
-  void OnCheckForCancel(int32_t preview_ui_id,
-                        int preview_request_id,
-                        bool* cancel);
+  void OnCheckForCancel(const PrintHostMsg_PreviewIds& ids, bool* cancel);
 #if defined(OS_WIN)
   void NotifySystemDialogCancelled(int routing_id);
 #endif
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 07e885d8..ed13425 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -600,6 +600,37 @@
   return static_cast<PrintPreviewUI*>(web_ui()->GetController());
 }
 
+bool PrintPreviewHandler::ShouldReceiveRendererMessage(int request_id) {
+  if (!IsJavascriptAllowed()) {
+    BadMessageReceived();
+    return false;
+  }
+
+  if (!base::ContainsKey(preview_callbacks_, request_id)) {
+    BadMessageReceived();
+    return false;
+  }
+
+  return true;
+}
+
+std::string PrintPreviewHandler::GetCallbackId(int request_id) {
+  std::string result;
+  if (!IsJavascriptAllowed()) {
+    BadMessageReceived();
+    return result;
+  }
+
+  auto it = preview_callbacks_.find(request_id);
+  if (it == preview_callbacks_.end()) {
+    BadMessageReceived();
+    return result;
+  }
+  result = it->second;
+  preview_callbacks_.erase(it);
+  return result;
+}
+
 void PrintPreviewHandler::HandleGetPrinters(const base::ListValue* args) {
   std::string callback_id;
   CHECK(args->GetString(0, &callback_id));
@@ -680,7 +711,8 @@
   settings->GetInteger(printing::kPreviewRequestID, &request_id);
   CHECK_GT(request_id, -1);
 
-  preview_callbacks_.push(callback_id);
+  CHECK(!base::ContainsKey(preview_callbacks_, request_id));
+  preview_callbacks_[request_id] = callback_id;
   print_preview_ui()->OnPrintPreviewRequest(request_id);
   // Add an additional key in order to identify |print_preview_ui| later on
   // when calling PrintPreviewUI::GetCurrentPrintPreviewStatus() on the IO
@@ -1117,50 +1149,41 @@
 }
 
 void PrintPreviewHandler::OnPrintPreviewReady(int preview_uid, int request_id) {
-  if (request_id < 0 || preview_callbacks_.empty() || !IsJavascriptAllowed()) {
-    // invalid ID or extra message
-    BadMessageReceived();
+  std::string callback_id = GetCallbackId(request_id);
+  if (callback_id.empty())
     return;
-  }
 
-  ResolveJavascriptCallback(base::Value(preview_callbacks_.front()),
-                            base::Value(preview_uid));
-  preview_callbacks_.pop();
+  ResolveJavascriptCallback(base::Value(callback_id), base::Value(preview_uid));
 }
 
-void PrintPreviewHandler::OnPrintPreviewFailed() {
-  if (preview_callbacks_.empty() || !IsJavascriptAllowed()) {
-    BadMessageReceived();
+void PrintPreviewHandler::OnPrintPreviewFailed(int request_id) {
+  std::string callback_id = GetCallbackId(request_id);
+  if (callback_id.empty())
     return;
-  }
 
   if (!reported_failed_preview_) {
     reported_failed_preview_ = true;
     ReportUserActionHistogram(PREVIEW_FAILED);
   }
-  RejectJavascriptCallback(base::Value(preview_callbacks_.front()),
+  RejectJavascriptCallback(base::Value(callback_id),
                            base::Value("PREVIEW_FAILED"));
-  preview_callbacks_.pop();
 }
 
-void PrintPreviewHandler::OnInvalidPrinterSettings() {
-  if (preview_callbacks_.empty() || !IsJavascriptAllowed()) {
-    BadMessageReceived();
+void PrintPreviewHandler::OnInvalidPrinterSettings(int request_id) {
+  std::string callback_id = GetCallbackId(request_id);
+  if (callback_id.empty())
     return;
-  }
 
-  RejectJavascriptCallback(base::Value(preview_callbacks_.front()),
+  RejectJavascriptCallback(base::Value(callback_id),
                            base::Value("SETTINGS_INVALID"));
-  preview_callbacks_.pop();
 }
 
 void PrintPreviewHandler::SendPrintPresetOptions(bool disable_scaling,
                                                  int copies,
-                                                 int duplex) {
-  if (preview_callbacks_.empty() || !IsJavascriptAllowed()) {
-    BadMessageReceived();
+                                                 int duplex,
+                                                 int request_id) {
+  if (!ShouldReceiveRendererMessage(request_id))
     return;
-  }
 
   FireWebUIListener("print-preset-options", base::Value(disable_scaling),
                     base::Value(copies), base::Value(duplex));
@@ -1169,10 +1192,8 @@
 void PrintPreviewHandler::SendPageCountReady(int page_count,
                                              int request_id,
                                              int fit_to_page_scaling) {
-  if (preview_callbacks_.empty() || !IsJavascriptAllowed()) {
-    BadMessageReceived();
+  if (!ShouldReceiveRendererMessage(request_id))
     return;
-  }
 
   FireWebUIListener("page-count-ready", base::Value(page_count),
                     base::Value(request_id), base::Value(fit_to_page_scaling));
@@ -1180,11 +1201,10 @@
 
 void PrintPreviewHandler::SendPageLayoutReady(
     const base::DictionaryValue& layout,
-    bool has_custom_page_size_style) {
-  if (preview_callbacks_.empty() || !IsJavascriptAllowed()) {
-    BadMessageReceived();
+    bool has_custom_page_size_style,
+    int request_id) {
+  if (!ShouldReceiveRendererMessage(request_id))
     return;
-  }
 
   FireWebUIListener("page-layout-ready", layout,
                     base::Value(has_custom_page_size_style));
@@ -1193,29 +1213,19 @@
 void PrintPreviewHandler::SendPagePreviewReady(int page_index,
                                                int preview_uid,
                                                int preview_response_id) {
-  if (!IsJavascriptAllowed()) {
-    BadMessageReceived();
+  if (!ShouldReceiveRendererMessage(preview_response_id))
     return;
-  }
 
   FireWebUIListener("page-preview-ready", base::Value(page_index),
                     base::Value(preview_uid), base::Value(preview_response_id));
 }
 
-void PrintPreviewHandler::OnPrintPreviewCancelled() {
-  if (!IsJavascriptAllowed()) {
-    BadMessageReceived();
+void PrintPreviewHandler::OnPrintPreviewCancelled(int request_id) {
+  std::string callback_id = GetCallbackId(request_id);
+  if (callback_id.empty())
     return;
-  }
 
-  if (preview_callbacks_.empty()) {
-    BadMessageReceived();
-    return;
-  }
-
-  RejectJavascriptCallback(base::Value(preview_callbacks_.front()),
-                           base::Value("CANCELLED"));
-  preview_callbacks_.pop();
+  RejectJavascriptCallback(base::Value(callback_id), base::Value("CANCELLED"));
 }
 
 void PrintPreviewHandler::OnPrintRequestCancelled() {
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
index 27d7caa3..17f7cfc3 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
@@ -5,10 +5,10 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_HANDLER_H_
 #define CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_HANDLER_H_
 
+#include <map>
 #include <memory>
 #include <string>
 
-#include "base/containers/queue.h"
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
@@ -65,14 +65,17 @@
       const std::string& account_id,
       const GoogleServiceAuthError& error) override;
 
-  // Called when print preview failed.
-  void OnPrintPreviewFailed();
+  // Called when print preview failed. |request_id| identifies the request that
+  // failed.
+  void OnPrintPreviewFailed(int request_id);
 
-  // Called when print preview is cancelled due to a new request.
-  void OnPrintPreviewCancelled();
+  // Called when print preview is cancelled due to a new request. |request_id|
+  // identifies the cancelled request.
+  void OnPrintPreviewCancelled(int request_id);
 
-  // Called when printer settings were invalid.
-  void OnInvalidPrinterSettings();
+  // Called when printer settings were invalid. |request_id| identifies the
+  // request that requested the printer with invalid settings.
+  void OnInvalidPrinterSettings(int request_id);
 
   // Called when print preview is ready.
   void OnPrintPreviewReady(int preview_uid, int request_id);
@@ -81,7 +84,10 @@
   void OnPrintRequestCancelled();
 
   // Send the print preset options from the document.
-  void SendPrintPresetOptions(bool disable_scaling, int copies, int duplex);
+  void SendPrintPresetOptions(bool disable_scaling,
+                              int copies,
+                              int duplex,
+                              int request_id);
 
   // Send the print preview page count and fit to page scaling
   void SendPageCountReady(int page_count,
@@ -90,7 +96,8 @@
 
   // Send the default page layout
   void SendPageLayoutReady(const base::DictionaryValue& layout,
-                           bool has_custom_page_size_style);
+                           bool has_custom_page_size_style,
+                           int request_id);
 
   // Notify the WebUI that the page preview is ready.
   void SendPagePreviewReady(int page_index,
@@ -148,6 +155,18 @@
 
   PrintPreviewUI* print_preview_ui() const;
 
+  // Whether the the handler should be receiving messages from the renderer to
+  // forward to the Print Preview JS in response to preview request with id
+  // |request_id|. Kills the renderer if the handler should not be receiving
+  // messages, or if |request_id| does not correspond to an outstanding request.
+  bool ShouldReceiveRendererMessage(int request_id);
+
+  // Gets the preview callback id associated with |request_id| and removes it
+  // from the |preview_callbacks_| map. Returns an empty string and kills the
+  // renderer if no callback is found, the handler should not be receiving
+  // messages, or if |request_id| is invalid.
+  std::string GetCallbackId(int request_id);
+
   // Gets the list of printers. First element of |args| is the Javascript
   // callback, second element of |args| is the printer type to fetch.
   void HandleGetPrinters(const base::ListValue* args);
@@ -320,7 +339,8 @@
   // GetPrinterHandler().
   std::unique_ptr<PrinterHandler> local_printer_handler_;
 
-  base::queue<std::string> preview_callbacks_;
+  // Maps preview request ids to callbacks.
+  std::map<int, std::string> preview_callbacks_;
 
   base::WeakPtrFactory<PrintPreviewHandler> weak_factory_;
 
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
index 98b91ef..7e4bffc 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
@@ -630,7 +630,7 @@
   layout.SetKey(printing::kSettingPrintableAreaY, base::Value(17));
   layout.SetKey(printing::kSettingPrintableAreaWidth, base::Value(578));
   layout.SetKey(printing::kSettingPrintableAreaHeight, base::Value(734));
-  handler()->SendPageLayoutReady(layout, false);
+  handler()->SendPageLayoutReady(layout, false, preview_request_id);
 
   // Verify that page-layout-ready webUI event was fired.
   AssertWebUIEventFired(*web_ui()->call_data().back(), "page-layout-ready");
@@ -653,7 +653,8 @@
   // None of these should work since there has been no new preview request.
   // Check that there are no new web UI messages sent.
   size_t message_count = web_ui()->call_data().size();
-  handler()->SendPageLayoutReady(base::DictionaryValue(), false);
+  handler()->SendPageLayoutReady(base::DictionaryValue(), false,
+                                 preview_request_id);
   EXPECT_EQ(message_count, web_ui()->call_data().size());
   handler()->SendPageCountReady(1, 0, -1);
   EXPECT_EQ(message_count, web_ui()->call_data().size());
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index 9be9474..1323b06 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -639,15 +639,15 @@
 }
 
 // static
-void PrintPreviewUI::GetCurrentPrintPreviewStatus(int32_t preview_ui_id,
-                                                  int request_id,
-                                                  bool* cancel) {
+void PrintPreviewUI::GetCurrentPrintPreviewStatus(
+    const PrintHostMsg_PreviewIds& ids,
+    bool* cancel) {
   int current_id = -1;
-  if (!g_print_preview_request_id_map.Get().Get(preview_ui_id, &current_id)) {
+  if (!g_print_preview_request_id_map.Get().Get(ids.ui_id, &current_id)) {
     *cancel = true;
     return;
   }
-  *cancel = (request_id != current_id);
+  *cancel = (ids.request_id != current_id);
 }
 
 int32_t PrintPreviewUI::GetIDForPrintPreviewUI() const {
@@ -680,8 +680,8 @@
   }
 }
 
-void PrintPreviewUI::OnPrintPreviewCancelled() {
-  handler_->OnPrintPreviewCancelled();
+void PrintPreviewUI::OnPrintPreviewCancelled(int request_id) {
+  handler_->OnPrintPreviewCancelled(request_id);
 }
 
 void PrintPreviewUI::OnPrintPreviewRequest(int request_id) {
@@ -693,17 +693,20 @@
 }
 
 void PrintPreviewUI::OnDidGetPreviewPageCount(
-    const PrintHostMsg_DidGetPreviewPageCount_Params& params) {
+    const PrintHostMsg_DidGetPreviewPageCount_Params& params,
+    int request_id) {
   DCHECK_GT(params.page_count, 0);
   if (g_testing_delegate)
     g_testing_delegate->DidGetPreviewPageCount(params.page_count);
-  handler_->SendPageCountReady(params.page_count, params.preview_request_id,
+  handler_->SendPageCountReady(params.page_count, request_id,
                                params.fit_to_page_scaling);
 }
 
 void PrintPreviewUI::OnDidGetDefaultPageLayout(
-    const PageSizeMargins& page_layout, const gfx::Rect& printable_area,
-    bool has_custom_page_size_style) {
+    const PageSizeMargins& page_layout,
+    const gfx::Rect& printable_area,
+    bool has_custom_page_size_style,
+    int request_id) {
   if (page_layout.margin_top < 0 || page_layout.margin_left < 0 ||
       page_layout.margin_bottom < 0 || page_layout.margin_right < 0 ||
       page_layout.content_width < 0 || page_layout.content_height < 0 ||
@@ -725,7 +728,7 @@
                     printable_area.width());
   layout.SetInteger(printing::kSettingPrintableAreaHeight,
                     printable_area.height());
-  handler_->SendPageLayoutReady(layout, has_custom_page_size_style);
+  handler_->SendPageLayoutReady(layout, has_custom_page_size_style, request_id);
 }
 
 void PrintPreviewUI::OnDidPreviewPage(int page_number,
@@ -758,12 +761,12 @@
   g_print_preview_request_id_map.Get().Set(id_, -1);
 }
 
-void PrintPreviewUI::OnPrintPreviewFailed() {
-  handler_->OnPrintPreviewFailed();
+void PrintPreviewUI::OnPrintPreviewFailed(int request_id) {
+  handler_->OnPrintPreviewFailed(request_id);
 }
 
-void PrintPreviewUI::OnInvalidPrinterSettings() {
-  handler_->OnInvalidPrinterSettings();
+void PrintPreviewUI::OnInvalidPrinterSettings(int request_id) {
+  handler_->OnInvalidPrinterSettings(request_id);
 }
 
 void PrintPreviewUI::OnHidePreviewDialog() {
@@ -796,9 +799,10 @@
 }
 
 void PrintPreviewUI::OnSetOptionsFromDocument(
-    const PrintHostMsg_SetOptionsFromDocument_Params& params) {
+    const PrintHostMsg_SetOptionsFromDocument_Params& params,
+    int request_id) {
   handler_->SendPrintPresetOptions(params.is_scaling_disabled, params.copies,
-                                   params.duplex);
+                                   params.duplex, request_id);
 }
 
 // static
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.h b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
index 87d879753f..336b9b82 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
@@ -19,6 +19,7 @@
 
 class PrintPreviewHandler;
 struct PrintHostMsg_DidGetPreviewPageCount_Params;
+struct PrintHostMsg_PreviewIds;
 struct PrintHostMsg_RequestPrintPreview_Params;
 struct PrintHostMsg_SetOptionsFromDocument_Params;
 
@@ -74,11 +75,10 @@
       content::WebContents* print_preview_dialog,
       const PrintHostMsg_RequestPrintPreview_Params& params);
 
-  // Determines whether to cancel a print preview request based on
-  // |preview_ui_id| and |request_id|.
+  // Determines whether to cancel a print preview request based on the request
+  // and ui ids in |ids|.
   // Can be called from any thread.
-  static void GetCurrentPrintPreviewStatus(int32_t preview_ui_id,
-                                           int request_id,
+  static void GetCurrentPrintPreviewStatus(const PrintHostMsg_PreviewIds& ids,
                                            bool* cancel);
 
   // Returns an id to uniquely identify this PrintPreviewUI.
@@ -89,13 +89,15 @@
 
   // Notifies the Web UI about the page count of the request preview.
   void OnDidGetPreviewPageCount(
-      const PrintHostMsg_DidGetPreviewPageCount_Params& params);
+      const PrintHostMsg_DidGetPreviewPageCount_Params& params,
+      int request_id);
 
   // Notifies the Web UI of the default page layout according to the currently
   // selected printer and page size.
   void OnDidGetDefaultPageLayout(const printing::PageSizeMargins& page_layout,
                                  const gfx::Rect& printable_area,
-                                 bool has_custom_page_size_style);
+                                 bool has_custom_page_size_style,
+                                 int request_id);
 
   // Notifies the Web UI that the 0-based page |page_number| has been rendered.
   // |preview_request_id| indicates wich request resulted in this response.
@@ -107,23 +109,25 @@
   void OnPreviewDataIsAvailable(int expected_pages_count,
                                 int preview_request_id);
 
-  // Notifies the Web UI that the print preview failed to render.
-  void OnPrintPreviewFailed();
+  // Notifies the Web UI that the print preview failed to render for the request
+  // with id = |request_id|.
+  void OnPrintPreviewFailed(int request_id);
 
   // Notified the Web UI that this print preview dialog's RenderProcess has been
   // closed, which may occur for several reasons, e.g. tab closure or crash.
   void OnPrintPreviewDialogClosed();
 
-  // Notifies the Web UI that the preview request was cancelled.
-  void OnPrintPreviewCancelled();
+  // Notifies the Web UI that the preview request identified by |request_id|
+  // was cancelled.
+  void OnPrintPreviewCancelled(int request_id);
 
   // Notifies the Web UI that initiator is closed, so we can disable all the
   // controls that need the initiator for generating the preview data.
   void OnInitiatorClosed();
 
   // Notifies the Web UI that the printer is unavailable or its settings are
-  // invalid.
-  void OnInvalidPrinterSettings();
+  // invalid. |request_id| is the preview request id with the invalid printer.
+  void OnInvalidPrinterSettings(int request_id);
 
   // Notifies the Web UI to cancel the pending preview request.
   virtual void OnCancelPendingPreviewRequest();
@@ -136,7 +140,8 @@
 
   // Notifies the WebUI to set print preset options from source PDF.
   void OnSetOptionsFromDocument(
-      const PrintHostMsg_SetOptionsFromDocument_Params& params);
+      const PrintHostMsg_SetOptionsFromDocument_Params& params,
+      int request_id);
 
   // Allows tests to wait until the print preview dialog is loaded.
   class TestingDelegate {
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
index 02e979f..4f8c397 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "components/prefs/pref_service.h"
+#include "components/printing/common/print_messages.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/site_instance.h"
@@ -203,7 +204,8 @@
   // Test with invalid |preview_ui_addr|.
   bool cancel = false;
   const int32_t kInvalidId = -5;
-  preview_ui->GetCurrentPrintPreviewStatus(kInvalidId, 0, &cancel);
+  preview_ui->GetCurrentPrintPreviewStatus(
+      PrintHostMsg_PreviewIds(0, kInvalidId), &cancel);
   EXPECT_TRUE(cancel);
 
   const int kFirstRequestId = 1000;
@@ -213,24 +215,24 @@
   // Test with kFirstRequestId.
   preview_ui->OnPrintPreviewRequest(kFirstRequestId);
   cancel = true;
-  preview_ui->GetCurrentPrintPreviewStatus(preview_ui_addr, kFirstRequestId,
-                                           &cancel);
+  preview_ui->GetCurrentPrintPreviewStatus(
+      PrintHostMsg_PreviewIds(kFirstRequestId, preview_ui_addr), &cancel);
   EXPECT_FALSE(cancel);
 
   cancel = false;
-  preview_ui->GetCurrentPrintPreviewStatus(preview_ui_addr, kSecondRequestId,
-                                           &cancel);
+  preview_ui->GetCurrentPrintPreviewStatus(
+      PrintHostMsg_PreviewIds(kSecondRequestId, preview_ui_addr), &cancel);
   EXPECT_TRUE(cancel);
 
   // Test with kSecondRequestId.
   preview_ui->OnPrintPreviewRequest(kSecondRequestId);
   cancel = false;
-  preview_ui->GetCurrentPrintPreviewStatus(preview_ui_addr, kFirstRequestId,
-                                           &cancel);
+  preview_ui->GetCurrentPrintPreviewStatus(
+      PrintHostMsg_PreviewIds(kFirstRequestId, preview_ui_addr), &cancel);
   EXPECT_TRUE(cancel);
 
   cancel = true;
-  preview_ui->GetCurrentPrintPreviewStatus(preview_ui_addr, kSecondRequestId,
-                                           &cancel);
+  preview_ui->GetCurrentPrintPreviewStatus(
+      PrintHostMsg_PreviewIds(kSecondRequestId, preview_ui_addr), &cancel);
   EXPECT_FALSE(cancel);
 }
diff --git a/components/printing/common/print_messages.cc b/components/printing/common/print_messages.cc
index 8b6f52b..c2eee78 100644
--- a/components/printing/common/print_messages.cc
+++ b/components/printing/common/print_messages.cc
@@ -152,6 +152,14 @@
 PrintHostMsg_RequestPrintPreview_Params::
     ~PrintHostMsg_RequestPrintPreview_Params() {}
 
+PrintHostMsg_PreviewIds::PrintHostMsg_PreviewIds()
+    : request_id(-1), ui_id(-1) {}
+
+PrintHostMsg_PreviewIds::PrintHostMsg_PreviewIds(int request_id, int ui_id)
+    : request_id(request_id), ui_id(ui_id) {}
+
+PrintHostMsg_PreviewIds::~PrintHostMsg_PreviewIds() {}
+
 PrintHostMsg_SetOptionsFromDocument_Params::
     PrintHostMsg_SetOptionsFromDocument_Params()
     : is_scaling_disabled(false),
diff --git a/components/printing/common/print_messages.h b/components/printing/common/print_messages.h
index cd3fe29..d85d26c 100644
--- a/components/printing/common/print_messages.h
+++ b/components/printing/common/print_messages.h
@@ -96,6 +96,14 @@
   bool selection_only;
 };
 
+struct PrintHostMsg_PreviewIds {
+  PrintHostMsg_PreviewIds();
+  PrintHostMsg_PreviewIds(int request_id, int ui_id);
+  ~PrintHostMsg_PreviewIds();
+  int request_id;
+  int ui_id;
+};
+
 struct PrintHostMsg_SetOptionsFromDocument_Params {
   PrintHostMsg_SetOptionsFromDocument_Params();
   ~PrintHostMsg_SetOptionsFromDocument_Params();
@@ -212,6 +220,11 @@
   IPC_STRUCT_TRAITS_MEMBER(selection_only)
 IPC_STRUCT_TRAITS_END()
 
+IPC_STRUCT_TRAITS_BEGIN(PrintHostMsg_PreviewIds)
+  IPC_STRUCT_TRAITS_MEMBER(request_id)
+  IPC_STRUCT_TRAITS_MEMBER(ui_id)
+IPC_STRUCT_TRAITS_END()
+
 IPC_STRUCT_TRAITS_BEGIN(PrintHostMsg_SetOptionsFromDocument_Params)
   // Specifies whether print scaling is enabled or not.
   IPC_STRUCT_TRAITS_MEMBER(is_scaling_disabled)
@@ -284,9 +297,6 @@
 
   // Whether the preview can be modified.
   IPC_STRUCT_MEMBER(bool, modifiable)
-
-  // The id of the preview request.
-  IPC_STRUCT_MEMBER(int, preview_request_id)
 IPC_STRUCT_END()
 
 // Parameters to describe a rendered preview page.
@@ -297,9 +307,6 @@
   // |page_number| is zero-based and should not be negative.
   IPC_STRUCT_MEMBER(int, page_number)
 
-  // The id of the preview request.
-  IPC_STRUCT_MEMBER(int, preview_request_id)
-
   // Cookie for the document to ensure correctness.
   IPC_STRUCT_MEMBER(int, document_cookie)
 IPC_STRUCT_END()
@@ -311,9 +318,6 @@
 
   // Scaling % to fit to page
   IPC_STRUCT_MEMBER(int, fit_to_page_scaling)
-
-  // The id of the preview request.
-  IPC_STRUCT_MEMBER(int, preview_request_id)
 IPC_STRUCT_END()
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
 
@@ -457,34 +461,37 @@
                     PrintHostMsg_RequestPrintPreview_Params /* params */)
 
 // Notify the browser the number of pages in the print preview document.
-IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetPreviewPageCount,
-                    PrintHostMsg_DidGetPreviewPageCount_Params /* params */)
+IPC_MESSAGE_ROUTED2(PrintHostMsg_DidGetPreviewPageCount,
+                    PrintHostMsg_DidGetPreviewPageCount_Params /* params */,
+                    PrintHostMsg_PreviewIds /* ids */)
 
 // Notify the browser of the default page layout according to the currently
 // selected printer and page size.
 // |printable_area_in_points| Specifies the printable area in points.
 // |has_custom_page_size_style| is true when the printing frame has a custom
 // page size css otherwise false.
-IPC_MESSAGE_ROUTED3(PrintHostMsg_DidGetDefaultPageLayout,
+IPC_MESSAGE_ROUTED4(PrintHostMsg_DidGetDefaultPageLayout,
                     printing::PageSizeMargins /* page layout in points */,
                     gfx::Rect /* printable area in points */,
-                    bool /* has custom page size style */)
+                    bool /* has custom page size style */,
+                    PrintHostMsg_PreviewIds /* ids */)
 
 // Notify the browser a print preview page has been rendered.
-IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPreviewPage,
-                    PrintHostMsg_DidPreviewPage_Params /* params */)
+IPC_MESSAGE_ROUTED2(PrintHostMsg_DidPreviewPage,
+                    PrintHostMsg_DidPreviewPage_Params /* params */,
+                    PrintHostMsg_PreviewIds /* ids */)
 
 // Asks the browser whether the print preview has been cancelled.
-IPC_SYNC_MESSAGE_ROUTED2_1(PrintHostMsg_CheckForCancel,
-                           int32_t /* PrintPreviewUI ID */,
-                           int /* request id */,
+IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_CheckForCancel,
+                           PrintHostMsg_PreviewIds /* ids */,
                            bool /* print preview cancelled */)
 
 // Sends back to the browser the complete rendered document (non-draft mode,
 // used for printing) that was requested by a PrintMsg_PrintPreview message.
 // The memory handle in this message is already valid in the browser process.
-IPC_MESSAGE_ROUTED1(PrintHostMsg_MetafileReadyForPrinting,
-                    PrintHostMsg_DidPreviewDocument_Params /* params */)
+IPC_MESSAGE_ROUTED2(PrintHostMsg_MetafileReadyForPrinting,
+                    PrintHostMsg_DidPreviewDocument_Params /* params */,
+                    PrintHostMsg_PreviewIds /* ids */)
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
 
 // This is sent when there are invalid printer settings.
@@ -496,18 +503,21 @@
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 // Tell the browser print preview failed.
-IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewFailed,
-                    int /* document cookie */)
+IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewFailed,
+                    int /* document cookie */,
+                    PrintHostMsg_PreviewIds /* ids */)
 
 // Tell the browser print preview was cancelled.
-IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewCancelled,
-                    int /* document cookie */)
+IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewCancelled,
+                    int /* document cookie */,
+                    PrintHostMsg_PreviewIds /* ids */)
 
 // Tell the browser print preview found the selected printer has invalid
 // settings (which typically caused by disconnected network printer or printer
 // driver is bogus).
-IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewInvalidPrinterSettings,
-                    int /* document cookie */)
+IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewInvalidPrinterSettings,
+                    int /* document cookie */,
+                    PrintHostMsg_PreviewIds /* ids */)
 
 // Run a nested run loop in the renderer until print preview for
 // window.print() finishes.
@@ -519,8 +529,9 @@
                     bool /* is_modifiable */)
 
 // Notify the browser to set print presets based on source PDF document.
-IPC_MESSAGE_ROUTED1(PrintHostMsg_SetOptionsFromDocument,
-                    PrintHostMsg_SetOptionsFromDocument_Params /* params */)
+IPC_MESSAGE_ROUTED2(PrintHostMsg_SetOptionsFromDocument,
+                    PrintHostMsg_SetOptionsFromDocument_Params /* params */,
+                    PrintHostMsg_PreviewIds /* ids */)
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
 
 #endif  // COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index a1ca0fc..d1f6630 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -1178,8 +1178,12 @@
   if (print_pages_params_->params.is_first_request &&
       !print_preview_context_.IsModifiable()) {
     PrintHostMsg_SetOptionsFromDocument_Params options;
-    if (SetOptionsFromPdfDocument(&options))
-      Send(new PrintHostMsg_SetOptionsFromDocument(routing_id(), options));
+    if (SetOptionsFromPdfDocument(&options)) {
+      PrintHostMsg_PreviewIds ids(
+          print_pages_params_->params.preview_request_id,
+          print_pages_params_->params.preview_ui_id);
+      Send(new PrintHostMsg_SetOptionsFromDocument(routing_id(), options, ids));
+    }
   }
 
   is_print_ready_metafile_sent_ = false;
@@ -1289,16 +1293,18 @@
     }
   }
   int fit_to_page_scaling = static_cast<int>(100.0f * fit_to_page_scale_factor);
+  PrintHostMsg_PreviewIds ids(print_params.preview_request_id,
+                              print_params.preview_ui_id);
+
   // Margins: Send default page layout to browser process.
   Send(new PrintHostMsg_DidGetDefaultPageLayout(
       routing_id(), default_page_layout, printable_area_in_points,
-      has_page_size_style));
+      has_page_size_style, ids));
 
   PrintHostMsg_DidGetPreviewPageCount_Params params;
   params.page_count = print_preview_context_.total_page_count();
   params.fit_to_page_scaling = fit_to_page_scaling;
-  params.preview_request_id = print_params.preview_request_id;
-  Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), params));
+  Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), params, ids));
   if (CheckForCancel())
     return false;
 
@@ -1380,12 +1386,14 @@
   preview_params.expected_pages_count =
       print_preview_context_.total_page_count();
   preview_params.modifiable = print_preview_context_.IsModifiable();
-  preview_params.preview_request_id =
-      print_pages_params_->params.preview_request_id;
+
+  PrintHostMsg_PreviewIds ids(print_pages_params_->params.preview_request_id,
+                              print_pages_params_->params.preview_ui_id);
 
   is_print_ready_metafile_sent_ = true;
 
-  Send(new PrintHostMsg_MetafileReadyForPrinting(routing_id(), preview_params));
+  Send(new PrintHostMsg_MetafileReadyForPrinting(routing_id(), preview_params,
+                                                 ids));
   return true;
 }
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
@@ -1590,6 +1598,13 @@
 void PrintRenderFrameHelper::DidFinishPrinting(PrintingResult result) {
   int cookie =
       print_pages_params_ ? print_pages_params_->params.document_cookie : 0;
+#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
+  PrintHostMsg_PreviewIds ids;
+  if (print_pages_params_) {
+    ids.ui_id = print_pages_params_->params.preview_ui_id;
+    ids.request_id = print_pages_params_->params.preview_request_id;
+  }
+#endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
   switch (result) {
     case OK:
       break;
@@ -1609,16 +1624,17 @@
       if (!is_print_ready_metafile_sent_) {
         if (notify_browser_of_print_failure_) {
           LOG(ERROR) << "CreatePreviewDocument failed";
-          Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie));
+          Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie, ids));
         } else {
-          Send(new PrintHostMsg_PrintPreviewCancelled(routing_id(), cookie));
+          Send(new PrintHostMsg_PrintPreviewCancelled(routing_id(), cookie,
+                                                      ids));
         }
       }
       print_preview_context_.Failed(notify_browser_of_print_failure_);
       break;
     case INVALID_SETTINGS:
       Send(new PrintHostMsg_PrintPreviewInvalidPrinterSettings(routing_id(),
-                                                               cookie));
+                                                               cookie, ids));
       print_preview_context_.Failed(false);
       break;
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
@@ -2135,9 +2151,11 @@
 bool PrintRenderFrameHelper::CheckForCancel() {
   const PrintMsg_Print_Params& print_params = print_pages_params_->params;
   bool cancel = false;
-  Send(new PrintHostMsg_CheckForCancel(routing_id(), print_params.preview_ui_id,
-                                       print_params.preview_request_id,
-                                       &cancel));
+  Send(new PrintHostMsg_CheckForCancel(
+      routing_id(),
+      PrintHostMsg_PreviewIds(print_params.preview_request_id,
+                              print_params.preview_ui_id),
+      &cancel));
   if (cancel)
     notify_browser_of_print_failure_ = false;
   return cancel;
@@ -2159,12 +2177,13 @@
   }
 
   preview_page_params.page_number = page_number;
-  preview_page_params.preview_request_id =
-      print_pages_params_->params.preview_request_id;
   preview_page_params.document_cookie =
       print_pages_params_->params.document_cookie;
 
-  Send(new PrintHostMsg_DidPreviewPage(routing_id(), preview_page_params));
+  PrintHostMsg_PreviewIds ids(print_pages_params_->params.preview_request_id,
+                              print_pages_params_->params.preview_ui_id);
+
+  Send(new PrintHostMsg_DidPreviewPage(routing_id(), preview_page_params, ids));
   return true;
 }
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
diff --git a/components/printing/test/print_mock_render_thread.cc b/components/printing/test/print_mock_render_thread.cc
index 051163c..d0281eef 100644
--- a/components/printing/test/print_mock_render_thread.cc
+++ b/components/printing/test/print_mock_render_thread.cc
@@ -100,20 +100,21 @@
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 void PrintMockRenderThread::OnDidGetPreviewPageCount(
-    const PrintHostMsg_DidGetPreviewPageCount_Params& params) {
+    const PrintHostMsg_DidGetPreviewPageCount_Params& params,
+    const PrintHostMsg_PreviewIds& ids) {
   print_preview_pages_remaining_ = params.page_count;
 }
 
 void PrintMockRenderThread::OnDidPreviewPage(
-    const PrintHostMsg_DidPreviewPage_Params& params) {
+    const PrintHostMsg_DidPreviewPage_Params& params,
+    const PrintHostMsg_PreviewIds& ids) {
   DCHECK_GE(params.page_number, printing::FIRST_PAGE_INDEX);
   print_preview_pages_remaining_--;
   print_preview_pages_.emplace_back(params.page_number,
                                     params.content.data_size);
 }
 
-void PrintMockRenderThread::OnCheckForCancel(int32_t preview_ui_id,
-                                             int preview_request_id,
+void PrintMockRenderThread::OnCheckForCancel(const PrintHostMsg_PreviewIds& ids,
                                              bool* cancel) {
   *cancel =
       (print_preview_pages_remaining_ == print_preview_cancel_page_number_);
diff --git a/components/printing/test/print_mock_render_thread.h b/components/printing/test/print_mock_render_thread.h
index fa6d4a3..cb92370 100644
--- a/components/printing/test/print_mock_render_thread.h
+++ b/components/printing/test/print_mock_render_thread.h
@@ -25,6 +25,7 @@
 struct PrintHostMsg_DidGetPreviewPageCount_Params;
 struct PrintHostMsg_DidPreviewPage_Params;
 struct PrintHostMsg_DidPrintDocument_Params;
+struct PrintHostMsg_PreviewIds;
 struct PrintHostMsg_ScriptedPrint_Params;
 struct PrintMsg_PrintPages_Params;
 struct PrintMsg_Print_Params;
@@ -78,11 +79,11 @@
   void OnDidPrintDocument(const PrintHostMsg_DidPrintDocument_Params& params);
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
   void OnDidGetPreviewPageCount(
-      const PrintHostMsg_DidGetPreviewPageCount_Params& params);
-  void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params);
-  void OnCheckForCancel(int32_t preview_ui_id,
-                        int preview_request_id,
-                        bool* cancel);
+      const PrintHostMsg_DidGetPreviewPageCount_Params& params,
+      const PrintHostMsg_PreviewIds& ids);
+  void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params,
+                        const PrintHostMsg_PreviewIds& ids);
+  void OnCheckForCancel(const PrintHostMsg_PreviewIds& ids, bool* cancel);
 #endif
 
   // For print preview, PrintRenderFrameHelper will update settings.