print_dialog_cloud.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/printing/print_dialog_cloud.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/printing/print_dialog_cloud_internal.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/l10n_util.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/base64.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_reader.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_list.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chrome_thread.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/debugger/devtools_manager.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/dom_ui/dom_ui.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/dom_ui/dom_ui_util.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/dom_ui/html_dialog_ui.h"
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/printing/cloud_print/cloud_print_url.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host.h"
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/tab_contents/tab_contents.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_observer.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_registrar.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_source.h"
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/notification_type.h"
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/render_messages_params.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "webkit/glue/webpreferences.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This module implements the UI support in Chrome for cloud printing.
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This means hosting a dialog containing HTML/JavaScript and using
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the published cloud print user interface integration APIs to get
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// page setup settings from the dialog contents and provide the
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// generated print PDF to the dialog contents for uploading to the
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// cloud print service.
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Currently, the flow between these classes is as follows:
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// PrintDialogCloud::CreatePrintDialogForPdf is called from
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// resource_message_filter_gtk.cc once the renderer has informed the
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// renderer host that PDF generation into the renderer host provided
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// temp file has been completed.  That call is on the IO thread.
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// That, in turn, hops over to the UI thread to create an instance of
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// PrintDialogCloud.
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The constructor for PrintDialogCloud creates a
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CloudPrintHtmlDialogDelegate and asks the current active browser to
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// show an HTML dialog using that class as the delegate. That class
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// hands in the kCloudPrintResourcesURL as the URL to visit.  That is
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// recognized by the GetDOMUIFactoryFunction as a signal to create an
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExternalHtmlDialogUI.
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CloudPrintHtmlDialogDelegate also temporarily owns a
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CloudPrintFlowHandler, a class which is responsible for the actual
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// interactions with the dialog contents, including handing in the PDF
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// print data and getting any page setup parameters that the dialog
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// contents provides.  As part of bringing up the dialog,
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HtmlDialogUI::RenderViewCreated is called (an override of
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// DOMUI::RenderViewCreated).  That routine, in turn, calls the
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// delegate's GetDOMMessageHandlers routine, at which point the
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ownership of the CloudPrintFlowHandler is handed over.  A pointer
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to the flow handler is kept to facilitate communication back and
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// forth between the two classes.
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The DOMUI continues dialog bring-up, calling
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CloudPrintFlowHandler::RegisterMessages.  This is where the
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// additional object model capabilities are registered for the dialog
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// contents to use.  It is also at this time that capabilities for the
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// dialog contents are adjusted to allow the dialog contents to close
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the window.  In addition, the pending URL is redirected to the
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// actual cloud print service URL.  The flow controller also registers
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// for notification of when the dialog contents finish loading, which
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is currently used to send the PDF data to the dialog contents.
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// In order to send the PDF data to the dialog contents, the flow
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// handler uses a CloudPrintDataSender.  It creates one, letting it
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// know the name of the temporary file containing the PDF data, and
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// posts the task of reading the file
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (CloudPrintDataSender::ReadPrintDataFile) to the file thread.  That
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// routine reads in the file, and then hops over to the IO thread to
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// send that data to the dialog contents.
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// When the dialog contents are finished (by either being cancelled or
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// hitting the print button), the delegate is notified, and responds
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that the dialog should be closed, at which point things are torn
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// down and released.
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(scottbyer):
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://code.google.com/p/chromium/issues/detail?id=44093 The
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// high-level flow (where the PDF data is generated before even
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// bringing up the dialog) isn't what we want.
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace internal_cloud_print_helpers {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GetRealOrInt(const DictionaryValue& dictionary,
993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  const std::string& path,
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  double* out_value) {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!dictionary.GetReal(path, out_value)) {
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int int_value = 0;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!dictionary.GetInteger(path, &int_value))
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *out_value = int_value;
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// From the JSON parsed value, get the entries for the page setup
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// parameters.
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GetPageSetupParameters(const std::string& json,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            ViewMsg_Print_Params& parameters) {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false));
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DLOG_IF(ERROR, (!parsed_value.get() ||
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  !parsed_value->IsType(Value::TYPE_DICTIONARY)))
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      << "PageSetup call didn't have expected contents";
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY))
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool result = true;
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* params = static_cast<DictionaryValue*>(parsed_value.get());
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  result &= GetRealOrInt(*params, "dpi", &parameters.dpi);
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  result &= GetRealOrInt(*params, "min_shrink", &parameters.min_shrink);
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  result &= GetRealOrInt(*params, "max_shrink", &parameters.max_shrink);
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  result &= params->GetBoolean("selection_only", &parameters.selection_only);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintDataSenderHelper::CallJavascriptFunction(
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::wstring& function_name) {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(function_name);
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintDataSenderHelper::CallJavascriptFunction(
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::wstring& function_name, const Value& arg) {
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(function_name, arg);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintDataSenderHelper::CallJavascriptFunction(
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::wstring& function_name, const Value& arg1, const Value& arg2) {
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(function_name, arg1, arg2);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Clears out the pointer we're using to communicate.  Either routine is
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// potentially expensive enough that stopping whatever is in progress
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is worth it.
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintDataSender::CancelPrintDataFile() {
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutoLock lock(lock_);
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't own helper, it was passed in to us, so no need to
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // delete, just let it go.
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  helper_ = NULL;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Grab the raw PDF file contents and massage them into shape for
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// sending to the dialog contents (and up to the cloud print server)
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// by encoding it and prefixing it with the appropriate mime type.
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Once that is done, kick off the next part of the task on the IO
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// thread.
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintDataSender::ReadPrintDataFile(const FilePath& path_to_pdf) {
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 file_size = 0;
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (file_util::GetFileSize(path_to_pdf, &file_size) && file_size != 0) {
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string file_data;
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (file_size < kuint32max) {
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      file_data.reserve(static_cast<unsigned int>(file_size));
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DLOG(WARNING) << " print data file too large to reserve space";
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (helper_ && file_util::ReadFileToString(path_to_pdf, &file_data)) {
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string base64_data;
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      base::Base64Encode(file_data, &base64_data);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string header("data:application/pdf;base64,");
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      base64_data.insert(0, header);
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      scoped_ptr<StringValue> new_data(new StringValue(base64_data));
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      print_data_.swap(new_data);
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ChromeThread::PostTask(ChromeThread::IO, FROM_HERE,
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             NewRunnableMethod(
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 this,
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 &CloudPrintDataSender::SendPrintDataFile));
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We have the data in hand that needs to be pushed into the dialog
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// contents; do so from the IO thread.
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(scottbyer): If the print data ends up being larger than the
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// upload limit (currently 10MB), what we need to do is upload that
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// large data to google docs and set the URL in the printing
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// JavaScript to that location, and make sure it gets deleted when not
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// needed. - 4/1/2010
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintDataSender::SendPrintDataFile() {
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutoLock lock(lock_);
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (helper_ && print_data_.get()) {
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    StringValue title(print_job_title_);
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Send the print data to the dialog contents.  The JavaScript
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // function is a preliminary API for prototyping purposes and is
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // subject to change.
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const_cast<CloudPrintDataSenderHelper*>(helper_)->CallJavascriptFunction(
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        L"printApp._printDataUrl", *print_data_, title);
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintFlowHandler::SetDialogDelegate(
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CloudPrintHtmlDialogDelegate* delegate) {
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Even if setting a new dom_ui, it means any previous task needs
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to be cancelled, it's now invalid.
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CancelAnyRunningTask();
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dialog_delegate_ = delegate;
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Cancels any print data sender we have in flight and removes our
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// reference to it, so when the task that is calling it finishes and
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// removes it's reference, it goes away.
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintFlowHandler::CancelAnyRunningTask() {
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (print_data_sender_.get()) {
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    print_data_sender_->CancelPrintDataFile();
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    print_data_sender_ = NULL;
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintFlowHandler::RegisterMessages() {
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!dom_ui_)
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(scottbyer) - This is where we will register messages for the
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // UI JS to use.  Needed: Call to update page setup parameters.
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback(
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "ShowDebugger",
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &CloudPrintFlowHandler::HandleShowDebugger));
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback(
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "SendPrintData",
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &CloudPrintFlowHandler::HandleSendPrintData));
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback(
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "SetPageParameters",
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &CloudPrintFlowHandler::HandleSetPageParameters));
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (dom_ui_->tab_contents()) {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Also, take the opportunity to set some (minimal) additional
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // script permissions required for the web UI.
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(scottbyer): learn how to make sure we're talking to the
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // right web site first.
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderViewHost* rvh = dom_ui_->tab_contents()->render_view_host();
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (rvh && rvh->delegate()) {
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WebPreferences webkit_prefs = rvh->delegate()->GetWebkitPrefs();
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      webkit_prefs.allow_scripts_to_close_windows = true;
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      rvh->UpdateWebPreferences(webkit_prefs);
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Register for appropriate notifications, and re-direct the URL
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // to the real server URL, now that we've gotten an HTML dialog
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // going.
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* controller = &dom_ui_->tab_contents()->controller();
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationEntry* pending_entry = controller->pending_entry();
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (pending_entry)
2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      pending_entry->set_url(CloudPrintURL(
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          dom_ui_->GetProfile()).GetCloudPrintServiceDialogURL());
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::LOAD_STOP,
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<NavigationController>(controller));
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintFlowHandler::Observe(NotificationType type,
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    const NotificationSource& source,
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    const NotificationDetails& details) {
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::LOAD_STOP) {
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Choose one or the other.  If you need to debug, bring up the
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // debugger.  You can then use the various chrome.send()
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // registrations above to kick of the various function calls,
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // including chrome.send("SendPrintData") in the javaScript
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // console and watch things happen with:
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // HandleShowDebugger(NULL);
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HandleSendPrintData(NULL);
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid CloudPrintFlowHandler::HandleShowDebugger(const ListValue* args) {
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowDebugger();
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintFlowHandler::ShowDebugger() {
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (dom_ui_) {
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderViewHost* rvh = dom_ui_->tab_contents()->render_view_host();
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (rvh)
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DevToolsManager::GetInstance()->OpenDevToolsWindow(rvh);
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochscoped_refptr<CloudPrintDataSender>
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCloudPrintFlowHandler::CreateCloudPrintDataSender() {
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(dom_ui_);
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  print_data_helper_.reset(new CloudPrintDataSenderHelper(dom_ui_));
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new CloudPrintDataSender(print_data_helper_.get(), print_job_title_);
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid CloudPrintFlowHandler::HandleSendPrintData(const ListValue* args) {
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This will cancel any ReadPrintDataFile() or SendPrintDataFile()
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // requests in flight (this is anticipation of when setting page
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // setup parameters becomes asynchronous and may be set while some
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // data is in flight).  Then we can clear out the print data.
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CancelAnyRunningTask();
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (dom_ui_) {
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    print_data_sender_ = CreateCloudPrintDataSender();
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           NewRunnableMethod(
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               print_data_sender_.get(),
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &CloudPrintDataSender::ReadPrintDataFile,
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               path_to_pdf_));
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid CloudPrintFlowHandler::HandleSetPageParameters(const ListValue* args) {
3223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string json(dom_ui_util::GetJsonResponseFromFirstArgumentInList(args));
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (json.empty())
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These are backstop default values - 72 dpi to match the screen,
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 8.5x11 inch paper with margins subtracted (1/4 inch top, left,
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // right and 0.56 bottom), and the min page shrink and max page
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // shrink values appear all over the place with no explanation.
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(scottbyer): Get a Linux/ChromeOS edge for PrintSettings
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // working so that we can get the default values from there.  Fix up
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // PrintWebViewHelper to do the same.
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kDPI = 72;
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kWidth = static_cast<int>((8.5-0.25-0.25)*kDPI);
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kHeight = static_cast<int>((11-0.25-0.56)*kDPI);
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const double kMinPageShrink = 1.25;
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const double kMaxPageShrink = 2.0;
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewMsg_Print_Params default_settings;
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  default_settings.printable_size = gfx::Size(kWidth, kHeight);
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  default_settings.dpi = kDPI;
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  default_settings.min_shrink = kMinPageShrink;
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  default_settings.max_shrink = kMaxPageShrink;
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  default_settings.desired_dpi = kDPI;
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  default_settings.document_cookie = 0;
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  default_settings.selection_only = false;
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!GetPageSetupParameters(json, default_settings)) {
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(scottbyer) - Here is where we would kick the originating
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // renderer thread with these new parameters in order to get it to
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // re-generate the PDF and hand it back to us.  window.print() is
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // currently synchronous, so there's a lot of work to do to get to
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // that point.
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCloudPrintHtmlDialogDelegate::CloudPrintHtmlDialogDelegate(
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath& path_to_pdf,
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width, int height,
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& json_arguments,
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const string16& print_job_title)
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : flow_handler_(new CloudPrintFlowHandler(path_to_pdf, print_job_title)),
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      owns_flow_handler_(true) {
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Init(width, height, json_arguments);
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCloudPrintHtmlDialogDelegate::CloudPrintHtmlDialogDelegate(
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CloudPrintFlowHandler* flow_handler,
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width, int height,
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& json_arguments)
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : flow_handler_(flow_handler),
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      owns_flow_handler_(true) {
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Init(width, height, json_arguments);
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintHtmlDialogDelegate::Init(
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width, int height, const std::string& json_arguments) {
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This information is needed to show the dialog HTML content.
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string cloud_print_url(chrome::kCloudPrintResourcesURL);
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params_.url = GURL(cloud_print_url);
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params_.height = height;
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params_.width = width;
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params_.json_input = json_arguments;
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  flow_handler_->SetDialogDelegate(this);
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCloudPrintHtmlDialogDelegate::~CloudPrintHtmlDialogDelegate() {
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the flow_handler_ is about to outlive us because we don't own
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // it anymore, we need to have it remove it's reference to us.
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  flow_handler_->SetDialogDelegate(NULL);
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (owns_flow_handler_) {
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete flow_handler_;
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CloudPrintHtmlDialogDelegate::IsDialogModal() const {
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::wstring CloudPrintHtmlDialogDelegate::GetDialogTitle() const {
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return l10n_util::GetString(IDS_CLOUD_PRINT_TITLE);
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGURL CloudPrintHtmlDialogDelegate::GetDialogContentURL() const {
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return params_.url;
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintHtmlDialogDelegate::GetDOMMessageHandlers(
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<DOMMessageHandler*>* handlers) const {
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handlers->push_back(flow_handler_);
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't own flow_handler_ anymore, but it sticks around until at
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // least right after OnDialogClosed() is called (and this object is
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // destroyed).
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  owns_flow_handler_ = false;
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintHtmlDialogDelegate::GetDialogSize(gfx::Size* size) const {
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size->set_width(params_.width);
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size->set_height(params_.height);
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string CloudPrintHtmlDialogDelegate::GetDialogArgs() const {
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return params_.json_input;
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintHtmlDialogDelegate::OnDialogClosed(
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& json_retval) {
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CloudPrintHtmlDialogDelegate::OnCloseContents(TabContents* source,
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   bool* out_close_dialog) {
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (out_close_dialog)
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *out_close_dialog = true;
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // end of namespace internal_cloud_print_helpers
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static, called on the IO thread.  This is the main entry point into
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// creating the dialog.
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(scottbyer): The signature here will need to change as the
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// workflow through the printing code changes to allow for dynamically
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// changing page setup parameters while the dialog is active.
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PrintDialogCloud::CreatePrintDialogForPdf(const FilePath& path_to_pdf) {
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeThread::PostTask(
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ChromeThread::UI, FROM_HERE,
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableFunction(&PrintDialogCloud::CreateDialogImpl, path_to_pdf));
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static, called from the UI thread.
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PrintDialogCloud::CreateDialogImpl(const FilePath& path_to_pdf) {
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  new PrintDialogCloud(path_to_pdf);
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Initialize the print dialog.  Called on the UI thread.
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPrintDialogCloud::PrintDialogCloud(const FilePath& path_to_pdf)
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : browser_(BrowserList::GetLastActive()) {
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(scottbyer): Verify GAIA login valid, execute GAIA login if not (should
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be distilled out of bookmark sync.)
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 print_job_title;
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (browser_ && browser_->GetSelectedTabContents())
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    print_job_title = browser_->GetSelectedTabContents()->GetTitle();
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(scottbyer): Get the dialog width, height from the dialog
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // contents, and take the screen size into account.
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HtmlDialogUIDelegate* dialog_delegate =
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new internal_cloud_print_helpers::CloudPrintHtmlDialogDelegate(
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          path_to_pdf, 500, 400, std::string(), print_job_title);
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_->BrowserShowHtmlDialog(dialog_delegate, NULL);
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPrintDialogCloud::~PrintDialogCloud() {
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
486