blob: 4721c47afb8bb2aa94aa0ab6d937c05a543f3220 [file] [log] [blame]
[email protected]80a8fad2011-01-29 04:02:381// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]73852b8f2010-05-14 00:38:122// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/printing/print_dialog_cloud.h"
6#include "chrome/browser/printing/print_dialog_cloud_internal.h"
7
[email protected]73852b8f2010-05-14 00:38:128#include "base/base64.h"
9#include "base/file_util.h"
10#include "base/json/json_reader.h"
[email protected]73852b8f2010-05-14 00:38:1211#include "base/values.h"
12#include "chrome/browser/browser_list.h"
[email protected]017a7a112010-10-12 16:38:2713#include "chrome/browser/browser_thread.h"
[email protected]37858e52010-08-26 00:22:0214#include "chrome/browser/debugger/devtools_manager.h"
[email protected]73852b8f2010-05-14 00:38:1215#include "chrome/browser/dom_ui/dom_ui.h"
[email protected]e82abf32011-01-31 23:12:4916#include "chrome/browser/dom_ui/web_ui_util.h"
[email protected]ea161da2010-11-02 21:57:3517#include "chrome/browser/prefs/pref_service.h"
[email protected]2283eead2010-09-29 23:17:3018#include "chrome/browser/printing/cloud_print/cloud_print_url.h"
[email protected]8ecad5e2010-12-02 21:18:3319#include "chrome/browser/profiles/profile.h"
[email protected]e39027a2011-01-24 21:41:5420#include "chrome/browser/profiles/profile_manager.h"
[email protected]73852b8f2010-05-14 00:38:1221#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]37858e52010-08-26 00:22:0222#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]ea161da2010-11-02 21:57:3523#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]eb2d7902011-02-02 18:19:5624#include "chrome/browser/ui/browser_dialogs.h"
[email protected]73852b8f2010-05-14 00:38:1225#include "chrome/common/notification_registrar.h"
26#include "chrome/common/notification_source.h"
[email protected]939856a2010-08-24 20:29:0227#include "chrome/common/notification_type.h"
[email protected]ea161da2010-11-02 21:57:3528#include "chrome/common/pref_names.h"
[email protected]939856a2010-08-24 20:29:0229#include "chrome/common/render_messages_params.h"
[email protected]73852b8f2010-05-14 00:38:1230#include "chrome/common/url_constants.h"
[email protected]c051a1b2011-01-21 23:30:1731#include "ui/base/l10n/l10n_util.h"
[email protected]939856a2010-08-24 20:29:0232#include "webkit/glue/webpreferences.h"
[email protected]73852b8f2010-05-14 00:38:1233
34#include "grit/generated_resources.h"
35
36// This module implements the UI support in Chrome for cloud printing.
37// This means hosting a dialog containing HTML/JavaScript and using
38// the published cloud print user interface integration APIs to get
39// page setup settings from the dialog contents and provide the
40// generated print PDF to the dialog contents for uploading to the
41// cloud print service.
42
43// Currently, the flow between these classes is as follows:
44
45// PrintDialogCloud::CreatePrintDialogForPdf is called from
46// resource_message_filter_gtk.cc once the renderer has informed the
47// renderer host that PDF generation into the renderer host provided
[email protected]032682b2011-01-12 22:05:0248// temp file has been completed. That call is on the FILE thread.
[email protected]73852b8f2010-05-14 00:38:1249// That, in turn, hops over to the UI thread to create an instance of
50// PrintDialogCloud.
51
52// The constructor for PrintDialogCloud creates a
53// CloudPrintHtmlDialogDelegate and asks the current active browser to
54// show an HTML dialog using that class as the delegate. That class
55// hands in the kCloudPrintResourcesURL as the URL to visit. That is
[email protected]80a8fad2011-01-29 04:02:3856// recognized by the GetWebUIFactoryFunction as a signal to create an
[email protected]73852b8f2010-05-14 00:38:1257// ExternalHtmlDialogUI.
58
59// CloudPrintHtmlDialogDelegate also temporarily owns a
60// CloudPrintFlowHandler, a class which is responsible for the actual
61// interactions with the dialog contents, including handing in the PDF
62// print data and getting any page setup parameters that the dialog
63// contents provides. As part of bringing up the dialog,
64// HtmlDialogUI::RenderViewCreated is called (an override of
65// DOMUI::RenderViewCreated). That routine, in turn, calls the
66// delegate's GetDOMMessageHandlers routine, at which point the
67// ownership of the CloudPrintFlowHandler is handed over. A pointer
68// to the flow handler is kept to facilitate communication back and
69// forth between the two classes.
70
71// The DOMUI continues dialog bring-up, calling
72// CloudPrintFlowHandler::RegisterMessages. This is where the
73// additional object model capabilities are registered for the dialog
74// contents to use. It is also at this time that capabilities for the
75// dialog contents are adjusted to allow the dialog contents to close
76// the window. In addition, the pending URL is redirected to the
77// actual cloud print service URL. The flow controller also registers
78// for notification of when the dialog contents finish loading, which
79// is currently used to send the PDF data to the dialog contents.
80
81// In order to send the PDF data to the dialog contents, the flow
82// handler uses a CloudPrintDataSender. It creates one, letting it
83// know the name of the temporary file containing the PDF data, and
84// posts the task of reading the file
85// (CloudPrintDataSender::ReadPrintDataFile) to the file thread. That
86// routine reads in the file, and then hops over to the IO thread to
87// send that data to the dialog contents.
88
89// When the dialog contents are finished (by either being cancelled or
90// hitting the print button), the delegate is notified, and responds
91// that the dialog should be closed, at which point things are torn
92// down and released.
93
94// TODO(scottbyer):
95// http://code.google.com/p/chromium/issues/detail?id=44093 The
96// high-level flow (where the PDF data is generated before even
97// bringing up the dialog) isn't what we want.
98
[email protected]73852b8f2010-05-14 00:38:1299namespace internal_cloud_print_helpers {
100
[email protected]fb534c92011-02-01 01:02:07101bool GetDoubleOrInt(const DictionaryValue& dictionary,
102 const std::string& path,
103 double* out_value) {
104 if (!dictionary.GetDouble(path, out_value)) {
[email protected]73852b8f2010-05-14 00:38:12105 int int_value = 0;
106 if (!dictionary.GetInteger(path, &int_value))
107 return false;
108 *out_value = int_value;
109 }
110 return true;
111}
112
113// From the JSON parsed value, get the entries for the page setup
114// parameters.
115bool GetPageSetupParameters(const std::string& json,
116 ViewMsg_Print_Params& parameters) {
117 scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false));
118 DLOG_IF(ERROR, (!parsed_value.get() ||
119 !parsed_value->IsType(Value::TYPE_DICTIONARY)))
120 << "PageSetup call didn't have expected contents";
121 if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY))
122 return false;
123
124 bool result = true;
125 DictionaryValue* params = static_cast<DictionaryValue*>(parsed_value.get());
[email protected]fb534c92011-02-01 01:02:07126 result &= GetDoubleOrInt(*params, "dpi", &parameters.dpi);
127 result &= GetDoubleOrInt(*params, "min_shrink", &parameters.min_shrink);
128 result &= GetDoubleOrInt(*params, "max_shrink", &parameters.max_shrink);
[email protected]a65175d2010-08-17 04:00:57129 result &= params->GetBoolean("selection_only", &parameters.selection_only);
[email protected]73852b8f2010-05-14 00:38:12130 return result;
131}
132
133void CloudPrintDataSenderHelper::CallJavascriptFunction(
134 const std::wstring& function_name) {
135 dom_ui_->CallJavascriptFunction(function_name);
136}
137
138void CloudPrintDataSenderHelper::CallJavascriptFunction(
139 const std::wstring& function_name, const Value& arg) {
140 dom_ui_->CallJavascriptFunction(function_name, arg);
141}
142
143void CloudPrintDataSenderHelper::CallJavascriptFunction(
144 const std::wstring& function_name, const Value& arg1, const Value& arg2) {
145 dom_ui_->CallJavascriptFunction(function_name, arg1, arg2);
146}
147
148// Clears out the pointer we're using to communicate. Either routine is
149// potentially expensive enough that stopping whatever is in progress
150// is worth it.
151void CloudPrintDataSender::CancelPrintDataFile() {
[email protected]20305ec2011-01-21 04:55:52152 base::AutoLock lock(lock_);
[email protected]73852b8f2010-05-14 00:38:12153 // We don't own helper, it was passed in to us, so no need to
154 // delete, just let it go.
155 helper_ = NULL;
156}
157
[email protected]38e08982010-10-22 17:28:43158CloudPrintDataSender::CloudPrintDataSender(CloudPrintDataSenderHelper* helper,
159 const string16& print_job_title)
160 : helper_(helper),
161 print_job_title_(print_job_title) {
162}
163
164CloudPrintDataSender::~CloudPrintDataSender() {}
165
[email protected]73852b8f2010-05-14 00:38:12166// Grab the raw PDF file contents and massage them into shape for
167// sending to the dialog contents (and up to the cloud print server)
168// by encoding it and prefixing it with the appropriate mime type.
169// Once that is done, kick off the next part of the task on the IO
170// thread.
171void CloudPrintDataSender::ReadPrintDataFile(const FilePath& path_to_pdf) {
[email protected]ba4f1132010-10-09 02:02:35172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]73852b8f2010-05-14 00:38:12173 int64 file_size = 0;
174 if (file_util::GetFileSize(path_to_pdf, &file_size) && file_size != 0) {
175 std::string file_data;
176 if (file_size < kuint32max) {
177 file_data.reserve(static_cast<unsigned int>(file_size));
178 } else {
179 DLOG(WARNING) << " print data file too large to reserve space";
180 }
181 if (helper_ && file_util::ReadFileToString(path_to_pdf, &file_data)) {
182 std::string base64_data;
183 base::Base64Encode(file_data, &base64_data);
184 std::string header("data:application/pdf;base64,");
185 base64_data.insert(0, header);
186 scoped_ptr<StringValue> new_data(new StringValue(base64_data));
187 print_data_.swap(new_data);
[email protected]ba4f1132010-10-09 02:02:35188 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
189 NewRunnableMethod(
190 this,
191 &CloudPrintDataSender::SendPrintDataFile));
[email protected]73852b8f2010-05-14 00:38:12192 }
193 }
194}
195
196// We have the data in hand that needs to be pushed into the dialog
197// contents; do so from the IO thread.
198
199// TODO(scottbyer): If the print data ends up being larger than the
200// upload limit (currently 10MB), what we need to do is upload that
201// large data to google docs and set the URL in the printing
202// JavaScript to that location, and make sure it gets deleted when not
203// needed. - 4/1/2010
204void CloudPrintDataSender::SendPrintDataFile() {
[email protected]ba4f1132010-10-09 02:02:35205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]20305ec2011-01-21 04:55:52206 base::AutoLock lock(lock_);
[email protected]73852b8f2010-05-14 00:38:12207 if (helper_ && print_data_.get()) {
[email protected]9848c7e2010-06-03 16:06:56208 StringValue title(print_job_title_);
[email protected]73852b8f2010-05-14 00:38:12209
210 // Send the print data to the dialog contents. The JavaScript
211 // function is a preliminary API for prototyping purposes and is
212 // subject to change.
213 const_cast<CloudPrintDataSenderHelper*>(helper_)->CallJavascriptFunction(
214 L"printApp._printDataUrl", *print_data_, title);
215 }
216}
217
218
[email protected]38e08982010-10-22 17:28:43219CloudPrintFlowHandler::CloudPrintFlowHandler(const FilePath& path_to_pdf,
220 const string16& print_job_title)
221 : path_to_pdf_(path_to_pdf),
222 print_job_title_(print_job_title) {
223}
224
225CloudPrintFlowHandler::~CloudPrintFlowHandler() {
226 // This will also cancel any task in flight.
227 CancelAnyRunningTask();
228}
229
230
[email protected]73852b8f2010-05-14 00:38:12231void CloudPrintFlowHandler::SetDialogDelegate(
232 CloudPrintHtmlDialogDelegate* delegate) {
233 // Even if setting a new dom_ui, it means any previous task needs
234 // to be cancelled, it's now invalid.
[email protected]ba4f1132010-10-09 02:02:35235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12236 CancelAnyRunningTask();
237 dialog_delegate_ = delegate;
238}
239
240// Cancels any print data sender we have in flight and removes our
241// reference to it, so when the task that is calling it finishes and
242// removes it's reference, it goes away.
243void CloudPrintFlowHandler::CancelAnyRunningTask() {
[email protected]ba4f1132010-10-09 02:02:35244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12245 if (print_data_sender_.get()) {
246 print_data_sender_->CancelPrintDataFile();
247 print_data_sender_ = NULL;
248 }
249}
250
[email protected]73852b8f2010-05-14 00:38:12251void CloudPrintFlowHandler::RegisterMessages() {
252 if (!dom_ui_)
253 return;
254
255 // TODO(scottbyer) - This is where we will register messages for the
256 // UI JS to use. Needed: Call to update page setup parameters.
257 dom_ui_->RegisterMessageCallback(
258 "ShowDebugger",
259 NewCallback(this, &CloudPrintFlowHandler::HandleShowDebugger));
260 dom_ui_->RegisterMessageCallback(
261 "SendPrintData",
262 NewCallback(this, &CloudPrintFlowHandler::HandleSendPrintData));
263 dom_ui_->RegisterMessageCallback(
264 "SetPageParameters",
265 NewCallback(this, &CloudPrintFlowHandler::HandleSetPageParameters));
266
267 if (dom_ui_->tab_contents()) {
268 // Also, take the opportunity to set some (minimal) additional
269 // script permissions required for the web UI.
270
271 // TODO(scottbyer): learn how to make sure we're talking to the
272 // right web site first.
273 RenderViewHost* rvh = dom_ui_->tab_contents()->render_view_host();
274 if (rvh && rvh->delegate()) {
275 WebPreferences webkit_prefs = rvh->delegate()->GetWebkitPrefs();
276 webkit_prefs.allow_scripts_to_close_windows = true;
277 rvh->UpdateWebPreferences(webkit_prefs);
278 }
279
280 // Register for appropriate notifications, and re-direct the URL
281 // to the real server URL, now that we've gotten an HTML dialog
282 // going.
283 NavigationController* controller = &dom_ui_->tab_contents()->controller();
284 NavigationEntry* pending_entry = controller->pending_entry();
285 if (pending_entry)
[email protected]2283eead2010-09-29 23:17:30286 pending_entry->set_url(CloudPrintURL(
[email protected]4baf1c42010-05-18 18:45:25287 dom_ui_->GetProfile()).GetCloudPrintServiceDialogURL());
[email protected]73852b8f2010-05-14 00:38:12288 registrar_.Add(this, NotificationType::LOAD_STOP,
289 Source<NavigationController>(controller));
290 }
291}
292
293void CloudPrintFlowHandler::Observe(NotificationType type,
294 const NotificationSource& source,
295 const NotificationDetails& details) {
296 if (type == NotificationType::LOAD_STOP) {
297 // Choose one or the other. If you need to debug, bring up the
298 // debugger. You can then use the various chrome.send()
299 // registrations above to kick of the various function calls,
300 // including chrome.send("SendPrintData") in the javaScript
301 // console and watch things happen with:
302 // HandleShowDebugger(NULL);
303 HandleSendPrintData(NULL);
304 }
305}
306
[email protected]88942a22010-08-19 20:34:43307void CloudPrintFlowHandler::HandleShowDebugger(const ListValue* args) {
[email protected]73852b8f2010-05-14 00:38:12308 ShowDebugger();
309}
310
311void CloudPrintFlowHandler::ShowDebugger() {
312 if (dom_ui_) {
313 RenderViewHost* rvh = dom_ui_->tab_contents()->render_view_host();
314 if (rvh)
315 DevToolsManager::GetInstance()->OpenDevToolsWindow(rvh);
316 }
317}
318
319scoped_refptr<CloudPrintDataSender>
320CloudPrintFlowHandler::CreateCloudPrintDataSender() {
321 DCHECK(dom_ui_);
322 print_data_helper_.reset(new CloudPrintDataSenderHelper(dom_ui_));
[email protected]9848c7e2010-06-03 16:06:56323 return new CloudPrintDataSender(print_data_helper_.get(), print_job_title_);
[email protected]73852b8f2010-05-14 00:38:12324}
325
[email protected]88942a22010-08-19 20:34:43326void CloudPrintFlowHandler::HandleSendPrintData(const ListValue* args) {
[email protected]ba4f1132010-10-09 02:02:35327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12328 // This will cancel any ReadPrintDataFile() or SendPrintDataFile()
329 // requests in flight (this is anticipation of when setting page
330 // setup parameters becomes asynchronous and may be set while some
331 // data is in flight). Then we can clear out the print data.
332 CancelAnyRunningTask();
333 if (dom_ui_) {
334 print_data_sender_ = CreateCloudPrintDataSender();
[email protected]ba4f1132010-10-09 02:02:35335 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
336 NewRunnableMethod(
337 print_data_sender_.get(),
338 &CloudPrintDataSender::ReadPrintDataFile,
339 path_to_pdf_));
[email protected]73852b8f2010-05-14 00:38:12340 }
341}
342
[email protected]88942a22010-08-19 20:34:43343void CloudPrintFlowHandler::HandleSetPageParameters(const ListValue* args) {
[email protected]e82abf32011-01-31 23:12:49344 std::string json(web_ui_util::GetJsonResponseFromFirstArgumentInList(args));
[email protected]73852b8f2010-05-14 00:38:12345 if (json.empty())
346 return;
347
348 // These are backstop default values - 72 dpi to match the screen,
349 // 8.5x11 inch paper with margins subtracted (1/4 inch top, left,
350 // right and 0.56 bottom), and the min page shrink and max page
351 // shrink values appear all over the place with no explanation.
352
353 // TODO(scottbyer): Get a Linux/ChromeOS edge for PrintSettings
354 // working so that we can get the default values from there. Fix up
355 // PrintWebViewHelper to do the same.
356 const int kDPI = 72;
357 const int kWidth = static_cast<int>((8.5-0.25-0.25)*kDPI);
358 const int kHeight = static_cast<int>((11-0.25-0.56)*kDPI);
359 const double kMinPageShrink = 1.25;
360 const double kMaxPageShrink = 2.0;
361
362 ViewMsg_Print_Params default_settings;
363 default_settings.printable_size = gfx::Size(kWidth, kHeight);
364 default_settings.dpi = kDPI;
365 default_settings.min_shrink = kMinPageShrink;
366 default_settings.max_shrink = kMaxPageShrink;
367 default_settings.desired_dpi = kDPI;
368 default_settings.document_cookie = 0;
369 default_settings.selection_only = false;
370
371 if (!GetPageSetupParameters(json, default_settings)) {
372 NOTREACHED();
373 return;
374 }
375
376 // TODO(scottbyer) - Here is where we would kick the originating
377 // renderer thread with these new parameters in order to get it to
378 // re-generate the PDF and hand it back to us. window.print() is
379 // currently synchronous, so there's a lot of work to do to get to
380 // that point.
381}
382
[email protected]ea161da2010-11-02 21:57:35383void CloudPrintFlowHandler::StoreDialogClientSize() const {
384 if (dom_ui_ && dom_ui_->tab_contents() && dom_ui_->tab_contents()->view()) {
385 gfx::Size size = dom_ui_->tab_contents()->view()->GetContainerSize();
386 dom_ui_->GetProfile()->GetPrefs()->SetInteger(
387 prefs::kCloudPrintDialogWidth, size.width());
388 dom_ui_->GetProfile()->GetPrefs()->SetInteger(
389 prefs::kCloudPrintDialogHeight, size.height());
390 }
391}
392
[email protected]73852b8f2010-05-14 00:38:12393CloudPrintHtmlDialogDelegate::CloudPrintHtmlDialogDelegate(
394 const FilePath& path_to_pdf,
395 int width, int height,
[email protected]9848c7e2010-06-03 16:06:56396 const std::string& json_arguments,
[email protected]e39027a2011-01-24 21:41:54397 const string16& print_job_title,
398 bool modal)
[email protected]9848c7e2010-06-03 16:06:56399 : flow_handler_(new CloudPrintFlowHandler(path_to_pdf, print_job_title)),
[email protected]e39027a2011-01-24 21:41:54400 modal_(modal),
[email protected]73852b8f2010-05-14 00:38:12401 owns_flow_handler_(true) {
402 Init(width, height, json_arguments);
403}
404
[email protected]05acb55472011-02-03 00:11:07405// For unit testing.
[email protected]73852b8f2010-05-14 00:38:12406CloudPrintHtmlDialogDelegate::CloudPrintHtmlDialogDelegate(
407 CloudPrintFlowHandler* flow_handler,
408 int width, int height,
[email protected]e39027a2011-01-24 21:41:54409 const std::string& json_arguments,
410 bool modal)
[email protected]73852b8f2010-05-14 00:38:12411 : flow_handler_(flow_handler),
[email protected]e39027a2011-01-24 21:41:54412 modal_(modal),
[email protected]18137e02010-05-25 21:10:35413 owns_flow_handler_(true) {
[email protected]73852b8f2010-05-14 00:38:12414 Init(width, height, json_arguments);
415}
416
[email protected]05acb55472011-02-03 00:11:07417void CloudPrintHtmlDialogDelegate::Init(int width, int height,
418 const std::string& json_arguments) {
[email protected]73852b8f2010-05-14 00:38:12419 // This information is needed to show the dialog HTML content.
[email protected]ba4f1132010-10-09 02:02:35420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]05acb55472011-02-03 00:11:07421 params_.url = GURL(chrome::kCloudPrintResourcesURL);
[email protected]73852b8f2010-05-14 00:38:12422 params_.height = height;
423 params_.width = width;
424 params_.json_input = json_arguments;
425
426 flow_handler_->SetDialogDelegate(this);
[email protected]e39027a2011-01-24 21:41:54427 // If we're not modal we can show the dialog with no browser.
428 // We need this to keep Chrome alive while our dialog is up.
429 if (!modal_)
430 BrowserList::StartKeepAlive();
[email protected]73852b8f2010-05-14 00:38:12431}
432
433CloudPrintHtmlDialogDelegate::~CloudPrintHtmlDialogDelegate() {
434 // If the flow_handler_ is about to outlive us because we don't own
435 // it anymore, we need to have it remove it's reference to us.
[email protected]ba4f1132010-10-09 02:02:35436 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12437 flow_handler_->SetDialogDelegate(NULL);
438 if (owns_flow_handler_) {
439 delete flow_handler_;
440 }
441}
442
443bool CloudPrintHtmlDialogDelegate::IsDialogModal() const {
[email protected]e39027a2011-01-24 21:41:54444 return modal_;
[email protected]73852b8f2010-05-14 00:38:12445}
446
447std::wstring CloudPrintHtmlDialogDelegate::GetDialogTitle() const {
[email protected]be559e442010-11-02 20:37:32448 return std::wstring();
[email protected]73852b8f2010-05-14 00:38:12449}
450
451GURL CloudPrintHtmlDialogDelegate::GetDialogContentURL() const {
452 return params_.url;
453}
454
455void CloudPrintHtmlDialogDelegate::GetDOMMessageHandlers(
456 std::vector<DOMMessageHandler*>* handlers) const {
457 handlers->push_back(flow_handler_);
458 // We don't own flow_handler_ anymore, but it sticks around until at
459 // least right after OnDialogClosed() is called (and this object is
460 // destroyed).
461 owns_flow_handler_ = false;
462}
463
464void CloudPrintHtmlDialogDelegate::GetDialogSize(gfx::Size* size) const {
465 size->set_width(params_.width);
466 size->set_height(params_.height);
467}
468
469std::string CloudPrintHtmlDialogDelegate::GetDialogArgs() const {
470 return params_.json_input;
471}
472
473void CloudPrintHtmlDialogDelegate::OnDialogClosed(
474 const std::string& json_retval) {
[email protected]ea161da2010-11-02 21:57:35475 // Get the final dialog size and store it.
476 flow_handler_->StoreDialogClientSize();
[email protected]e39027a2011-01-24 21:41:54477 // If we're modal we can show the dialog with no browser.
478 // End the keep-alive so that Chrome can exit.
479 if (!modal_)
480 BrowserList::EndKeepAlive();
[email protected]73852b8f2010-05-14 00:38:12481 delete this;
482}
483
[email protected]18137e02010-05-25 21:10:35484void CloudPrintHtmlDialogDelegate::OnCloseContents(TabContents* source,
485 bool* out_close_dialog) {
486 if (out_close_dialog)
487 *out_close_dialog = true;
488}
489
[email protected]ea161da2010-11-02 21:57:35490bool CloudPrintHtmlDialogDelegate::ShouldShowDialogTitle() const {
491 return false;
492}
493
[email protected]05acb55472011-02-03 00:11:07494} // namespace internal_cloud_print_helpers
[email protected]73852b8f2010-05-14 00:38:12495
496// static, called on the IO thread. This is the main entry point into
497// creating the dialog.
498
499// TODO(scottbyer): The signature here will need to change as the
500// workflow through the printing code changes to allow for dynamically
501// changing page setup parameters while the dialog is active.
[email protected]e39027a2011-01-24 21:41:54502void PrintDialogCloud::CreatePrintDialogForPdf(const FilePath& path_to_pdf,
503 const string16& print_job_title,
504 bool modal) {
505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE) ||
506 BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12507
[email protected]ba4f1132010-10-09 02:02:35508 BrowserThread::PostTask(
509 BrowserThread::UI, FROM_HERE,
[email protected]e39027a2011-01-24 21:41:54510 NewRunnableFunction(&PrintDialogCloud::CreateDialogImpl,
511 path_to_pdf,
512 print_job_title,
513 modal));
[email protected]73852b8f2010-05-14 00:38:12514}
515
516// static, called from the UI thread.
[email protected]e39027a2011-01-24 21:41:54517void PrintDialogCloud::CreateDialogImpl(const FilePath& path_to_pdf,
518 const string16& print_job_title,
519 bool modal) {
[email protected]ba4f1132010-10-09 02:02:35520 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]e39027a2011-01-24 21:41:54521 new PrintDialogCloud(path_to_pdf, print_job_title, modal);
[email protected]73852b8f2010-05-14 00:38:12522}
523
524// Initialize the print dialog. Called on the UI thread.
[email protected]e39027a2011-01-24 21:41:54525PrintDialogCloud::PrintDialogCloud(const FilePath& path_to_pdf,
526 const string16& print_job_title,
527 bool modal)
[email protected]05acb55472011-02-03 00:11:07528 : browser_(BrowserList::GetLastActive()) {
529 Init(path_to_pdf, print_job_title, modal);
530}
[email protected]73852b8f2010-05-14 00:38:12531
[email protected]05acb55472011-02-03 00:11:07532PrintDialogCloud::~PrintDialogCloud() {
533}
534
535void PrintDialogCloud::Init(const FilePath& path_to_pdf,
536 const string16& print_job_title,
537 bool modal) {
[email protected]73852b8f2010-05-14 00:38:12538 // TODO(scottbyer): Verify GAIA login valid, execute GAIA login if not (should
539 // be distilled out of bookmark sync.)
[email protected]ea161da2010-11-02 21:57:35540 const int kDefaultWidth = 497;
541 const int kDefaultHeight = 332;
[email protected]05acb55472011-02-03 00:11:07542 string16 job_title = print_job_title;
[email protected]e39027a2011-01-24 21:41:54543 Profile* profile = NULL;
[email protected]05acb55472011-02-03 00:11:07544 if (modal) {
[email protected]e39027a2011-01-24 21:41:54545 DCHECK(browser_);
[email protected]05acb55472011-02-03 00:11:07546 if (job_title.empty() && browser_->GetSelectedTabContents())
547 job_title = browser_->GetSelectedTabContents()->GetTitle();
[email protected]e39027a2011-01-24 21:41:54548 profile = browser_->GetProfile();
549 } else {
550 profile = ProfileManager::GetDefaultProfile();
551 }
552 DCHECK(profile);
[email protected]05acb55472011-02-03 00:11:07553 PrefService* pref_service = profile->GetPrefs();
[email protected]ea161da2010-11-02 21:57:35554 DCHECK(pref_service);
555 if (!pref_service->FindPreference(prefs::kCloudPrintDialogWidth)) {
556 pref_service->RegisterIntegerPref(prefs::kCloudPrintDialogWidth,
557 kDefaultWidth);
558 }
559 if (!pref_service->FindPreference(prefs::kCloudPrintDialogHeight)) {
560 pref_service->RegisterIntegerPref(prefs::kCloudPrintDialogHeight,
561 kDefaultHeight);
562 }
563
564 int width = pref_service->GetInteger(prefs::kCloudPrintDialogWidth);
565 int height = pref_service->GetInteger(prefs::kCloudPrintDialogHeight);
[email protected]e39027a2011-01-24 21:41:54566
[email protected]73852b8f2010-05-14 00:38:12567 HtmlDialogUIDelegate* dialog_delegate =
568 new internal_cloud_print_helpers::CloudPrintHtmlDialogDelegate(
[email protected]05acb55472011-02-03 00:11:07569 path_to_pdf, width, height, std::string(), job_title, modal);
570 if (modal) {
[email protected]e39027a2011-01-24 21:41:54571 DCHECK(browser_);
572 browser_->BrowserShowHtmlDialog(dialog_delegate, NULL);
573 } else {
[email protected]eb2d7902011-02-02 18:19:56574 browser::ShowHtmlDialog(NULL, profile, dialog_delegate);
[email protected]e39027a2011-01-24 21:41:54575 }
[email protected]73852b8f2010-05-14 00:38:12576}