print_dialog_cloud.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
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" 14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/browser_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", ¶meters.dpi); 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result &= GetRealOrInt(*params, "min_shrink", ¶meters.min_shrink); 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result &= GetRealOrInt(*params, "max_shrink", ¶meters.max_shrink); 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result &= params->GetBoolean("selection_only", ¶meters.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) { 161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::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); 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod( 179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick this, 180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &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() { 194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::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. 212731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::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() { 221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::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) { 305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::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(); 313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod( 315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick print_data_sender_.get(), 316731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &CloudPrintDataSender::ReadPrintDataFile, 317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 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. 383731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::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. 396731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::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) { 453731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 455731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 456731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::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) { 462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::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