Simplify GCP integration with print preview.
Removes GCP printers from the printer dropdown on platforms other than Chrome OS.
Adds an option to the printer dropdown to close print preview and print via the cloud print dialog.

BUG=
TEST=Cloud print printers should only appear in print preview in chrome os.
If cloud print is enabled, a new option should appear in the print preview dropdown that closes print preview and brings up the cloud print dialog.


Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=101256

Review URL: http://codereview.chromium.org/7830013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101822 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 90ab601..873b4d41 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6082,14 +6082,6 @@
           desc="Option shown in printer drop-down list when the user isn't signed in to cloud print.  Choosing it will display a sign in dialog.">
         Sign in to access cloud printers...
       </message>
-      <message name="IDS_PRINT_PREVIEW_MORE_PRINTERS"
-          desc="Option shown in printer drop-down list that displays an interface for finding/using additional cloud based printers.">
-        More printers...
-      </message>
-      <message name="IDS_PRINT_PREVIEW_ADD_CLOUD_PRINTER"
-          desc="Option shown in printer drop-down list that takes the user to a page to add cloud based printers.">
-        Add cloud printers...
-      </message>
       <message name="IDS_PRINT_PREVIEW_CLOUD_PRINTERS"
           desc="Option shown in printer drop-down list that serves as a heading above all cloud based printers.">
         Cloud printers
@@ -6110,6 +6102,14 @@
           desc="Option shown in printer drop-down list for managing local printers.">
         Manage local printers...
       </message>
+      <message name="IDS_PRINT_PREVIEW_PRINT_WITH_CLOUD_PRINT"
+          desc="Option shown in printer drop-down list to allow the user to print using cloud print.">
+        Print with Google Cloud Print...
+      </message>
+      <message name="IDS_PRINT_PREVIEW_PRINT_WITH_CLOUD_PRINT_WAIT"
+          desc="Message shown in the print preview page after choosing cloud print before the dialog displays">
+        Loading Google Cloud Print
+      </message>
       <message name="IDS_PRINT_PREVIEW_SUMMARY_FORMAT_LONG" desc="Print summary, explaining to the user how many pages will be printed.">
         Total: <ph name="NUMBER_OF_SHEETS">$1<ex>10</ex></ph> <ph name="SHEETS_LABEL">$2<ex>sheets of paper</ex></ph> (<ph name="NUMBER_OF_PAGES">$3<ex>4</ex></ph> <ph name="PAGE_OR_PAGES_LABEL">$4<ex>Pages</ex></ph>)
       </message>
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index 9cf9fb7..8320b6f 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -1104,7 +1104,8 @@
     string16 printTicket16 = base::SysNSStringToUTF16(printTicket);
     print_dialog_cloud::CreatePrintDialogForFile(
         FilePath([inputPath UTF8String]), title16,
-        printTicket16, [mime UTF8String], /*modal=*/false);
+        printTicket16, [mime UTF8String], /*modal=*/false,
+        /*delete_on_close=*/false);
   }
 }
 
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc
index eb504a87..618ba8d 100644
--- a/chrome/browser/printing/print_dialog_cloud.cc
+++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -442,8 +442,10 @@
     const string16& print_job_title,
     const string16& print_ticket,
     const std::string& file_type,
-    bool modal)
-    : flow_handler_(new CloudPrintFlowHandler(path_to_file,
+    bool modal,
+    bool delete_on_close)
+    : delete_on_close_(delete_on_close),
+      flow_handler_(new CloudPrintFlowHandler(path_to_file,
                                               print_job_title,
                                               print_ticket,
                                               file_type)),
@@ -458,8 +460,10 @@
     CloudPrintFlowHandler* flow_handler,
     int width, int height,
     const std::string& json_arguments,
-    bool modal)
-    : flow_handler_(flow_handler),
+    bool modal,
+    bool delete_on_close)
+    : delete_on_close_(delete_on_close),
+      flow_handler_(flow_handler),
       modal_(modal),
       owns_flow_handler_(true) {
   Init(width, height, json_arguments);
@@ -526,8 +530,7 @@
   // Get the final dialog size and store it.
   flow_handler_->StoreDialogClientSize();
 
-  if (CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kCloudPrintDeleteFile)) {
+  if (delete_on_close_) {
     BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
         NewRunnableFunction(&internal_cloud_print_helpers::Delete,
                             path_to_file_));
@@ -555,12 +558,36 @@
   return true;
 }
 
+void CreatePrintDialogForBytesImpl(scoped_refptr<RefCountedBytes> data,
+                                   const string16& print_job_title,
+                                   const string16& print_ticket,
+                                   const std::string& file_type,
+                                   bool modal) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+  // TODO([email protected]) Writing the PDF to a file before printing
+  // is wasteful.  Modify the dialog flow to pull PDF data from memory.
+  // See http://code.google.com/p/chromium/issues/detail?id=44093
+  FilePath path;
+  if (file_util::CreateTemporaryFile(&path)) {
+    file_util::WriteFile(path,
+                         reinterpret_cast<const char*>(data->front()),
+                         data->size());
+  }
+  print_dialog_cloud::CreatePrintDialogForFile(path,
+                                               print_job_title,
+                                               print_ticket,
+                                               file_type,
+                                               modal,
+                                               true);
+}
+
 // Called from the UI thread, starts up the dialog.
 void CreateDialogImpl(const FilePath& path_to_file,
                       const string16& print_job_title,
                       const string16& print_ticket,
                       const std::string& file_type,
-                      bool modal) {
+                      bool modal,
+                      bool delete_on_close) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   Browser* browser = BrowserList::GetLastActive();
 
@@ -599,7 +626,7 @@
   HtmlDialogUIDelegate* dialog_delegate =
       new internal_cloud_print_helpers::CloudPrintHtmlDialogDelegate(
           path_to_file, width, height, std::string(), job_title, print_ticket,
-          file_type, modal);
+          file_type, modal, delete_on_close);
   if (modal) {
     DCHECK(browser);
     browser->BrowserShowHtmlDialog(dialog_delegate, NULL);
@@ -627,7 +654,8 @@
                               const string16& print_job_title,
                               const string16& print_ticket,
                               const std::string& file_type,
-                              bool modal) {
+                              bool modal,
+                              bool delete_on_close) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE) ||
          BrowserThread::CurrentlyOn(BrowserThread::UI));
 
@@ -638,7 +666,28 @@
                           print_job_title,
                           print_ticket,
                           file_type,
-                          modal));
+                          modal,
+                          delete_on_close));
+}
+
+void CreatePrintDialogForBytes(scoped_refptr<RefCountedBytes> data,
+                               const string16& print_job_title,
+                               const string16& print_ticket,
+                               const std::string& file_type,
+                               bool modal) {
+  // TODO([email protected]) Avoid cloning the PDF data.  Make use of a
+  // shared memory object instead.
+  // http://code.google.com/p/chromium/issues/detail?id=44093
+  scoped_refptr<RefCountedBytes> cloned_data(new RefCountedBytes(data->data()));
+  BrowserThread::PostTask(
+      BrowserThread::FILE, FROM_HERE,
+      NewRunnableFunction(
+          &internal_cloud_print_helpers::CreatePrintDialogForBytesImpl,
+          cloned_data,
+          print_job_title,
+          print_ticket,
+          file_type,
+          modal));
 }
 
 bool CreatePrintDialogFromCommandLine(const CommandLine& command_line) {
@@ -665,11 +714,15 @@
             switches::kCloudPrintFileType);
       }
 
+      bool delete_on_close = CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kCloudPrintDeleteFile);
+
       print_dialog_cloud::CreatePrintDialogForFile(cloud_print_file,
                                                    print_job_title,
                                                    print_job_print_ticket,
                                                    file_type,
-                                                   false);
+                                                   false,
+                                                   delete_on_close);
       return true;
     }
   }
diff --git a/chrome/browser/printing/print_dialog_cloud.h b/chrome/browser/printing/print_dialog_cloud.h
index 2631345b..78ff15d 100644
--- a/chrome/browser/printing/print_dialog_cloud.h
+++ b/chrome/browser/printing/print_dialog_cloud.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/basictypes.h"
+#include "base/memory/ref_counted_memory.h"
 #include "base/string16.h"
 
 class FilePath;
@@ -16,13 +17,24 @@
 
 namespace print_dialog_cloud {
 
+// Creates a print dialog to print a file on disk.
 // Called on the FILE or UI thread. Even though this may start up a modal
 // dialog, it will return immediately. The dialog is handled asynchronously.
 void CreatePrintDialogForFile(const FilePath& path_to_file,
                               const string16& print_job_title,
                               const string16& print_ticket,
                               const std::string& file_type,
-                              bool modal);
+                              bool modal,
+                              bool delete_on_close);
+
+// Creates a print dialog to print data in RAM.
+// Called on the FILE or UI thread. Even though this may start up a modal
+// dialog, it will return immediately. The dialog is handled asynchronously.
+void CreatePrintDialogForBytes(scoped_refptr<RefCountedBytes> data,
+                               const string16& print_job_title,
+                               const string16& print_ticket,
+                               const std::string& file_type,
+                               bool modal);
 
 // Parse switches from command_line and display the print dialog as appropriate.
 bool CreatePrintDialogFromCommandLine(const CommandLine& command_line);
diff --git a/chrome/browser/printing/print_dialog_cloud_internal.h b/chrome/browser/printing/print_dialog_cloud_internal.h
index 6e04242..995b9a64 100644
--- a/chrome/browser/printing/print_dialog_cloud_internal.h
+++ b/chrome/browser/printing/print_dialog_cloud_internal.h
@@ -158,7 +158,8 @@
                                const string16& print_job_title,
                                const string16& print_ticket,
                                const std::string& file_type,
-                               bool modal);
+                               bool modal,
+                               bool delete_on_close);
   virtual ~CloudPrintHtmlDialogDelegate();
 
   // HTMLDialogUIDelegate implementation:
@@ -182,9 +183,11 @@
   CloudPrintHtmlDialogDelegate(CloudPrintFlowHandler* flow_handler,
                                int width, int height,
                                const std::string& json_arguments,
-                               bool modal);
+                               bool modal,
+                               bool delete_on_close);
   void Init(int width, int height, const std::string& json_arguments);
 
+  bool delete_on_close_;
   CloudPrintFlowHandler* flow_handler_;
   bool modal_;
   mutable bool owns_flow_handler_;
@@ -200,7 +203,8 @@
                       const string16& print_job_title,
                       const string16& print_ticket,
                       const std::string& file_type,
-                      bool modal);
+                      bool modal,
+                      bool delete_on_close);
 
 void Delete(const FilePath& path_to_file);
 
diff --git a/chrome/browser/printing/print_dialog_cloud_uitest.cc b/chrome/browser/printing/print_dialog_cloud_uitest.cc
index 2279ac9a..f2af4af 100644
--- a/chrome/browser/printing/print_dialog_cloud_uitest.cc
+++ b/chrome/browser/printing/print_dialog_cloud_uitest.cc
@@ -204,7 +204,8 @@
                             string16(),
                             string16(),
                             std::string("application/pdf"),
-                            true));
+                            true,
+                            false));
   }
 
   bool handler_added_;
diff --git a/chrome/browser/printing/print_dialog_cloud_unittest.cc b/chrome/browser/printing/print_dialog_cloud_unittest.cc
index 6fc2eaf..583171e4 100644
--- a/chrome/browser/printing/print_dialog_cloud_unittest.cc
+++ b/chrome/browser/printing/print_dialog_cloud_unittest.cc
@@ -310,7 +310,7 @@
     EXPECT_CALL(*mock_flow_handler_.get(), SetDialogDelegate(_));
     EXPECT_CALL(*mock_flow_handler_.get(), SetDialogDelegate(NULL));
     delegate_.reset(new CloudPrintHtmlDialogDelegate(
-        mock_flow_handler_.get(), 100, 100, std::string(), true));
+        mock_flow_handler_.get(), 100, 100, std::string(), true, false));
   }
 
   virtual void TearDown() {
diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc
index 1f9ad53..f0b8a65 100644
--- a/chrome/browser/printing/printing_message_filter.cc
+++ b/chrome/browser/printing/printing_message_filter.cc
@@ -172,7 +172,8 @@
         string16(),
         string16(),
         std::string("application/pdf"),
-        true);
+        true,
+        false);
   else
     NOTIMPLEMENTED();
 
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js
index b085402..2ef447e 100644
--- a/chrome/browser/resources/print_preview/print_preview.js
+++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -17,12 +17,11 @@
 var previewModifiable = false;
 
 // Destination list special value constants.
-const ADD_CLOUD_PRINTER = 'addCloudPrinter';
 const MANAGE_CLOUD_PRINTERS = 'manageCloudPrinters';
 const MANAGE_LOCAL_PRINTERS = 'manageLocalPrinters';
-const MORE_PRINTERS = 'morePrinters';
 const SIGN_IN = 'signIn';
 const PRINT_TO_PDF = 'Print to PDF';
+const PRINT_WITH_CLOUD_PRINT = 'printWithCloudPrint';
 
 // State of the print preview settings.
 var printSettings = new PrintSettings();
@@ -223,16 +222,17 @@
   if (cloudprint.isCloudPrint(printerList.options[selectedIndex])) {
     updateWithCloudPrinterCapabilities();
     skip_refresh = true;
+  } else if (selectedValue == PRINT_WITH_CLOUD_PRINT) {
+    // If a preview is pending this will just disable controls.
+    // Once the preview completes we'll try again.
+    printWithCloudPrintDialog();
+    skip_refresh = true;
   } else if (selectedValue == SIGN_IN ||
              selectedValue == MANAGE_CLOUD_PRINTERS ||
-             selectedValue == MANAGE_LOCAL_PRINTERS ||
-             selectedValue == ADD_CLOUD_PRINTER) {
+             selectedValue == MANAGE_LOCAL_PRINTERS) {
     printerList.selectedIndex = lastSelectedPrinterIndex;
     chrome.send(selectedValue);
     skip_refresh = true;
-  } else if (selectedValue == MORE_PRINTERS) {
-    onSystemDialogLinkClicked();
-    skip_refresh = true;
   } else if (selectedValue == PRINT_TO_PDF) {
     updateWithPrinterCapabilities({
         'disableColorOption': true,
@@ -457,6 +457,10 @@
  */
 function requestToPrintPendingDocument() {
   hasPendingPrintDocumentRequest = false;
+  if (getSelectedPrinterName() == PRINT_WITH_CLOUD_PRINT) {
+    chrome.send('printWithCloudPrint');
+    return;
+  }
 
   if (!areSettingsValid()) {
     if (isTabHidden)
@@ -600,13 +604,19 @@
                            false,
                            false);
   addDestinationListOption('', '', false, true, true);
-
+  if (useCloudPrint) {
+    addDestinationListOption(localStrings.getString('printWithCloudPrint'),
+                             PRINT_WITH_CLOUD_PRINT,
+                             false,
+                             false,
+                             false);
+    addDestinationListOption('', '', false, true, true);
+  }
   // Add options to manage printers.
   if (!cr.isChromeOS) {
     addDestinationListOption(localStrings.getString('manageLocalPrinters'),
         MANAGE_LOCAL_PRINTERS, false, false, false);
-  }
-  if (useCloudPrint) {
+  } else if (useCloudPrint) {
     // Fetch recent printers.
     cloudprint.fetchPrinters(addCloudPrinters, false);
     // Fetch the full printer list.
@@ -726,7 +736,6 @@
  */
 function addCloudPrinters(printers) {
   var isFirstPass = false;
-  var showMorePrintersOption = false;
   var printerList = $('printer-list');
 
   if (firstCloudPrintOptionPos == lastCloudPrintOptionPos) {
@@ -744,42 +753,21 @@
     cloudprint.setCloudPrint(option, null, null);
   }
   if (printers != null) {
-    if (printers.length == 0) {
-      addDestinationListOptionAtPosition(lastCloudPrintOptionPos++,
-          localStrings.getString('addCloudPrinter'),
-          ADD_CLOUD_PRINTER,
-          false,
-          false,
-          false);
-    } else {
-      for (var i = 0; i < printers.length; i++) {
-        if (!cloudPrinterAlreadyAdded(printers[i]['id'])) {
-          if (!trackCloudPrinterAdded(printers[i]['id'])) {
-            showMorePrintersOption = true;
-            break;
-          }
-          var option = addDestinationListOptionAtPosition(
-              lastCloudPrintOptionPos++,
-              printers[i]['name'],
-              printers[i]['id'],
-              printers[i]['name'] == defaultOrLastUsedPrinterName,
-              false,
-              false);
-          cloudprint.setCloudPrint(option,
-                                   printers[i]['name'],
-                                   printers[i]['id']);
+    for (var i = 0; i < printers.length; i++) {
+      if (!cloudPrinterAlreadyAdded(printers[i]['id'])) {
+        if (!trackCloudPrinterAdded(printers[i]['id'])) {
+          break;
         }
-      }
-      if (showMorePrintersOption) {
-        addDestinationListOptionAtPosition(lastCloudPrintOptionPos++,
-                                           '',
-                                           '',
-                                           false,
-                                           true,
-                                           true);
-        addDestinationListOptionAtPosition(lastCloudPrintOptionPos++,
-            localStrings.getString('morePrinters'),
-            MORE_PRINTERS, false, false, false);
+        var option = addDestinationListOptionAtPosition(
+            lastCloudPrintOptionPos++,
+            printers[i]['name'],
+            printers[i]['id'],
+            printers[i]['name'] == defaultOrLastUsedPrinterName,
+            false,
+            false);
+        cloudprint.setCloudPrint(option,
+                                 printers[i]['name'],
+                                 printers[i]['id']);
       }
     }
   } else {
@@ -1112,6 +1100,21 @@
       'printPreviewTitleFormat', initiatorTabTitle);
 }
 
+/**
+ * Attempt to hide the preview tab and display the Cloud Print
+ * dialog instead. Just disables controls if we're waiting on a new preview
+ * to be generated.
+ */
+function printWithCloudPrintDialog() {
+  if (isPrintReadyMetafileReady) {
+    chrome.send('printWithCloudPrint');
+  } else {
+    showCustomMessage(localStrings.getString('printWithCloudPrintWait'));
+    disableInputElementsInSidebar();
+    hasPendingPrintDocumentRequest = true;
+  }
+}
+
 /// Pull in all other scripts in a single shot.
 <include src="print_preview_animations.js"/>
 <include src="print_preview_cloud.js"/>
diff --git a/chrome/browser/ui/webui/print_preview_data_source.cc b/chrome/browser/ui/webui/print_preview_data_source.cc
index e8976de..6383e86 100644
--- a/chrome/browser/ui/webui/print_preview_data_source.cc
+++ b/chrome/browser/ui/webui/print_preview_data_source.cc
@@ -101,8 +101,6 @@
                      IDS_PRINT_PREVIEW_PAGE_RANGE_INSTRUCTION);
   AddLocalizedString("copiesInstruction", IDS_PRINT_PREVIEW_COPIES_INSTRUCTION);
   AddLocalizedString("signIn", IDS_PRINT_PREVIEW_SIGN_IN);
-  AddLocalizedString("morePrinters", IDS_PRINT_PREVIEW_MORE_PRINTERS);
-  AddLocalizedString("addCloudPrinter", IDS_PRINT_PREVIEW_ADD_CLOUD_PRINTER);
   AddLocalizedString("cloudPrinters", IDS_PRINT_PREVIEW_CLOUD_PRINTERS);
   AddLocalizedString("localPrinters", IDS_PRINT_PREVIEW_LOCAL_PRINTERS);
   AddLocalizedString("manageCloudPrinters",
@@ -110,6 +108,10 @@
   AddLocalizedString("manageLocalPrinters",
                      IDS_PRINT_PREVIEW_MANAGE_LOCAL_PRINTERS);
   AddLocalizedString("managePrinters", IDS_PRINT_PREVIEW_MANAGE_PRINTERS);
+  AddLocalizedString("printWithCloudPrintWait",
+                     IDS_PRINT_PREVIEW_PRINT_WITH_CLOUD_PRINT_WAIT);
+  AddLocalizedString("printWithCloudPrint",
+                     IDS_PRINT_PREVIEW_PRINT_WITH_CLOUD_PRINT);
   AddLocalizedString("incrementTitle", IDS_PRINT_PREVIEW_INCREMENT_TITLE);
   AddLocalizedString("decrementTitle", IDS_PRINT_PREVIEW_DECREMENT_TITLE);
   AddLocalizedString("printPagesLabel", IDS_PRINT_PREVIEW_PRINT_PAGES_LABEL);
diff --git a/chrome/browser/ui/webui/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview_handler.cc
index 3f3eed73..2453b6f 100644
--- a/chrome/browser/ui/webui/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview_handler.cc
@@ -22,6 +22,8 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/printing/background_printing_manager.h"
+#include "chrome/browser/printing/print_dialog_cloud.h"
+#include "chrome/browser/printing/print_job_manager.h"
 #include "chrome/browser/printing/cloud_print/cloud_print_url.h"
 #include "chrome/browser/printing/printer_manager_dialog.h"
 #include "chrome/browser/printing/print_preview_tab_controller.h"
@@ -83,6 +85,7 @@
   PREVIEW_STARTED,
   INITIATOR_TAB_CRASHED,
   INITIATOR_TAB_CLOSED,
+  PRINT_WITH_CLOUD_PRINT,
   USERACTION_BUCKET_BOUNDARY
 };
 
@@ -469,12 +472,10 @@
       NewCallback(this, &PrintPreviewHandler::HandleGetPrinterCapabilities));
   web_ui_->RegisterMessageCallback("showSystemDialog",
       NewCallback(this, &PrintPreviewHandler::HandleShowSystemDialog));
-  web_ui_->RegisterMessageCallback("morePrinters",
-      NewCallback(this, &PrintPreviewHandler::HandleShowSystemDialog));
   web_ui_->RegisterMessageCallback("signIn",
       NewCallback(this, &PrintPreviewHandler::HandleSignin));
-  web_ui_->RegisterMessageCallback("addCloudPrinter",
-      NewCallback(this, &PrintPreviewHandler::HandleManageCloudPrint));
+  web_ui_->RegisterMessageCallback("printWithCloudPrint",
+      NewCallback(this, &PrintPreviewHandler::HandlePrintWithCloudPrint));
   web_ui_->RegisterMessageCallback("manageCloudPrinters",
       NewCallback(this, &PrintPreviewHandler::HandleManageCloudPrint));
   web_ui_->RegisterMessageCallback("manageLocalPrinters",
@@ -738,6 +739,31 @@
   cloud_print_signin_dialog::CreateCloudPrintSigninDialog(preview_tab());
 }
 
+void PrintPreviewHandler::HandlePrintWithCloudPrint(const ListValue* /*args*/) {
+  // Record the number of times the user asks to print via cloud print
+  // instead of the print preview dialog.
+  ReportStats();
+  ReportUserActionHistogram(PRINT_WITH_CLOUD_PRINT);
+
+  PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(web_ui_);
+  scoped_refptr<RefCountedBytes> data;
+  print_preview_ui->GetPrintPreviewDataForIndex(
+      printing::COMPLETE_PREVIEW_DOCUMENT_INDEX, &data);
+  CHECK(data.get());
+  DCHECK_GT(data->size(), 0U);
+  print_dialog_cloud::CreatePrintDialogForBytes(data,
+      string16(print_preview_ui->initiator_tab_title()),
+      string16(),
+      std::string("application/pdf"),
+      false);
+
+  // Once the cloud print dialog comes up we're no longer in a background
+  // printing situation.  Close the print preview.
+  // TODO([email protected]) The flow should be changed as described in
+  // http://code.google.com/p/chromium/issues/detail?id=44093
+  ActivateInitiatorTabAndClosePreviewTab();
+}
+
 void PrintPreviewHandler::HandleManageCloudPrint(const ListValue* /*args*/) {
   Browser* browser = BrowserList::GetLastActive();
   browser->OpenURL(CloudPrintURL(browser->profile()).
diff --git a/chrome/browser/ui/webui/print_preview_handler.h b/chrome/browser/ui/webui/print_preview_handler.h
index c74aece12..77d8a7a5 100644
--- a/chrome/browser/ui/webui/print_preview_handler.h
+++ b/chrome/browser/ui/webui/print_preview_handler.h
@@ -124,6 +124,9 @@
   // |args| is unused.
   void HandleManagePrinters(const base::ListValue* args);
 
+  // Asks the browser to show the cloud print dialog. |args| is unused.
+  void HandlePrintWithCloudPrint(const base::ListValue* args);
+
   // Asks the browser to close the preview tab. |args| is unused.
   void HandleClosePreviewTab(const base::ListValue* args);