blob: c5ebd4a75c429935b81f4c7796697666a8680bee [file] [log] [blame]
[email protected]87ab41e72012-01-04 18:45:111// Copyright (c) 2012 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"
[email protected]ba4fc242011-10-04 18:56:569#include "base/bind.h"
10#include "base/bind_helpers.h"
[email protected]65c9d89a2011-04-13 21:02:3911#include "base/command_line.h"
[email protected]73852b8f2010-05-14 00:38:1212#include "base/file_util.h"
13#include "base/json/json_reader.h"
[email protected]3853a4c2013-02-11 17:15:5714#include "base/prefs/pref_service.h"
[email protected]4b8852a2011-06-10 17:24:4615#include "base/utf_string_conversions.h"
[email protected]73852b8f2010-05-14 00:38:1216#include "base/values.h"
[email protected]70019152012-12-19 11:44:1917#include "chrome/browser/devtools/devtools_window.h"
[email protected]2e6389f2012-05-18 19:41:2518#include "chrome/browser/lifetime/application_lifetime.h"
[email protected]c753f142013-02-10 13:14:0419#include "chrome/browser/prefs/pref_registry_syncable.h"
[email protected]2283eead2010-09-29 23:17:3020#include "chrome/browser/printing/cloud_print/cloud_print_url.h"
[email protected]8ecad5e2010-12-02 21:18:3321#include "chrome/browser/profiles/profile.h"
[email protected]e39027a2011-01-24 21:41:5422#include "chrome/browser/profiles/profile_manager.h"
[email protected]508326df2012-05-23 16:01:1923#include "chrome/browser/ui/browser_dialogs.h"
[email protected]65c9d89a2011-04-13 21:02:3924#include "chrome/common/chrome_switches.h"
[email protected]ea161da2010-11-02 21:57:3525#include "chrome/common/pref_names.h"
[email protected]1375e3ab2011-03-24 17:07:2226#include "chrome/common/print_messages.h"
[email protected]73852b8f2010-05-14 00:38:1227#include "chrome/common/url_constants.h"
[email protected]c38831a12011-10-28 12:44:4928#include "content/public/browser/browser_thread.h"
[email protected]cdcb1dee2012-01-04 00:46:2029#include "content/public/browser/navigation_controller.h"
[email protected]022af742011-12-28 18:37:2530#include "content/public/browser/navigation_entry.h"
[email protected]6c2381d2011-10-19 02:52:5331#include "content/public/browser/notification_registrar.h"
32#include "content/public/browser/notification_source.h"
[email protected]0d6e9bd2011-10-18 04:29:1633#include "content/public/browser/notification_types.h"
[email protected]9c1662b2012-03-06 15:44:3334#include "content/public/browser/render_view_host.h"
[email protected]0ec4898e2011-12-30 21:09:2435#include "content/public/browser/web_contents.h"
[email protected]8643e6d2012-01-18 20:26:1036#include "content/public/browser/web_contents_view.h"
[email protected]01ec4ec2012-01-18 04:13:4737#include "content/public/browser/web_ui.h"
[email protected]fca6b9b2012-05-22 17:11:0538#include "grit/generated_resources.h"
[email protected]c051a1b2011-01-21 23:30:1739#include "ui/base/l10n/l10n_util.h"
[email protected]fca6b9b2012-05-22 17:11:0540#include "webkit/glue/webpreferences.h"
[email protected]520c2022012-03-15 00:13:1541
[email protected]88bfd25b2012-06-22 06:28:3342#if defined(USE_AURA)
43#include "ui/aura/root_window.h"
44#include "ui/aura/window.h"
45#endif
46
[email protected]520c2022012-03-15 00:13:1547#if defined(OS_WIN)
48#include "ui/base/win/foreground_helper.h"
49#endif
50
[email protected]73852b8f2010-05-14 00:38:1251// This module implements the UI support in Chrome for cloud printing.
52// This means hosting a dialog containing HTML/JavaScript and using
53// the published cloud print user interface integration APIs to get
54// page setup settings from the dialog contents and provide the
[email protected]a984bdf2011-03-15 20:17:1655// generated print data to the dialog contents for uploading to the
[email protected]73852b8f2010-05-14 00:38:1256// cloud print service.
57
58// Currently, the flow between these classes is as follows:
59
[email protected]a984bdf2011-03-15 20:17:1660// PrintDialogCloud::CreatePrintDialogForFile is called from
[email protected]73852b8f2010-05-14 00:38:1261// resource_message_filter_gtk.cc once the renderer has informed the
[email protected]a984bdf2011-03-15 20:17:1662// renderer host that print data generation into the renderer host provided
[email protected]032682b2011-01-12 22:05:0263// temp file has been completed. That call is on the FILE thread.
[email protected]73852b8f2010-05-14 00:38:1264// That, in turn, hops over to the UI thread to create an instance of
65// PrintDialogCloud.
66
67// The constructor for PrintDialogCloud creates a
[email protected]5835871a2012-04-25 21:56:5568// CloudPrintWebDialogDelegate and asks the current active browser to
[email protected]73852b8f2010-05-14 00:38:1269// show an HTML dialog using that class as the delegate. That class
[email protected]89f550b2011-06-08 18:34:0370// hands in the kChromeUICloudPrintResourcesURL as the URL to visit. That is
[email protected]80a8fad2011-01-29 04:02:3871// recognized by the GetWebUIFactoryFunction as a signal to create an
[email protected]02b5ccc2012-04-30 23:58:3172// ExternalWebDialogUI.
[email protected]73852b8f2010-05-14 00:38:1273
[email protected]5835871a2012-04-25 21:56:5574// CloudPrintWebDialogDelegate also temporarily owns a
[email protected]73852b8f2010-05-14 00:38:1275// CloudPrintFlowHandler, a class which is responsible for the actual
[email protected]a984bdf2011-03-15 20:17:1676// interactions with the dialog contents, including handing in the
[email protected]73852b8f2010-05-14 00:38:1277// print data and getting any page setup parameters that the dialog
78// contents provides. As part of bringing up the dialog,
[email protected]02b5ccc2012-04-30 23:58:3179// WebDialogUI::RenderViewCreated is called (an override of
[email protected]c39f9bf2011-02-12 00:43:5580// WebUI::RenderViewCreated). That routine, in turn, calls the
[email protected]36e12172011-02-08 23:46:0281// delegate's GetWebUIMessageHandlers routine, at which point the
[email protected]73852b8f2010-05-14 00:38:1282// ownership of the CloudPrintFlowHandler is handed over. A pointer
83// to the flow handler is kept to facilitate communication back and
84// forth between the two classes.
85
[email protected]c39f9bf2011-02-12 00:43:5586// The WebUI continues dialog bring-up, calling
[email protected]73852b8f2010-05-14 00:38:1287// CloudPrintFlowHandler::RegisterMessages. This is where the
88// additional object model capabilities are registered for the dialog
89// contents to use. It is also at this time that capabilities for the
90// dialog contents are adjusted to allow the dialog contents to close
91// the window. In addition, the pending URL is redirected to the
92// actual cloud print service URL. The flow controller also registers
93// for notification of when the dialog contents finish loading, which
[email protected]a984bdf2011-03-15 20:17:1694// is currently used to send the data to the dialog contents.
[email protected]73852b8f2010-05-14 00:38:1295
[email protected]a984bdf2011-03-15 20:17:1696// In order to send the data to the dialog contents, the flow
[email protected]73852b8f2010-05-14 00:38:1297// handler uses a CloudPrintDataSender. It creates one, letting it
[email protected]a984bdf2011-03-15 20:17:1698// know the name of the temporary file containing the data, and
[email protected]73852b8f2010-05-14 00:38:1299// posts the task of reading the file
100// (CloudPrintDataSender::ReadPrintDataFile) to the file thread. That
101// routine reads in the file, and then hops over to the IO thread to
102// send that data to the dialog contents.
103
104// When the dialog contents are finished (by either being cancelled or
105// hitting the print button), the delegate is notified, and responds
106// that the dialog should be closed, at which point things are torn
107// down and released.
108
109// TODO(scottbyer):
110// http://code.google.com/p/chromium/issues/detail?id=44093 The
[email protected]a984bdf2011-03-15 20:17:16111// high-level flow (where the data is generated before even
[email protected]73852b8f2010-05-14 00:38:12112// bringing up the dialog) isn't what we want.
113
[email protected]631bb742011-11-02 11:29:39114using content::BrowserThread;
[email protected]c5eed492012-01-04 17:07:50115using content::NavigationController;
[email protected]10f417c52011-12-28 21:04:23116using content::NavigationEntry;
[email protected]eaabba22012-03-07 15:02:11117using content::RenderViewHost;
[email protected]a81343d232011-12-27 07:39:20118using content::WebContents;
[email protected]26e2632a2011-12-31 04:02:55119using content::WebUIMessageHandler;
[email protected]20c07f8e2012-05-31 08:43:14120using ui::WebDialogDelegate;
[email protected]631bb742011-11-02 11:29:39121
[email protected]681958c2013-02-21 13:48:14122const int kDefaultWidth = 912;
123const int kDefaultHeight = 633;
124
[email protected]73852b8f2010-05-14 00:38:12125namespace internal_cloud_print_helpers {
126
[email protected]73852b8f2010-05-14 00:38:12127// From the JSON parsed value, get the entries for the page setup
128// parameters.
129bool GetPageSetupParameters(const std::string& json,
[email protected]1375e3ab2011-03-24 17:07:22130 PrintMsg_Print_Params& parameters) {
[email protected]cd5785752012-04-11 00:15:41131 scoped_ptr<Value> parsed_value(base::JSONReader::Read(json));
[email protected]73852b8f2010-05-14 00:38:12132 DLOG_IF(ERROR, (!parsed_value.get() ||
133 !parsed_value->IsType(Value::TYPE_DICTIONARY)))
134 << "PageSetup call didn't have expected contents";
135 if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY))
136 return false;
137
138 bool result = true;
139 DictionaryValue* params = static_cast<DictionaryValue*>(parsed_value.get());
[email protected]05c7da62011-05-05 17:23:56140 result &= params->GetDouble("dpi", &parameters.dpi);
141 result &= params->GetDouble("min_shrink", &parameters.min_shrink);
142 result &= params->GetDouble("max_shrink", &parameters.max_shrink);
[email protected]a65175d2010-08-17 04:00:57143 result &= params->GetBoolean("selection_only", &parameters.selection_only);
[email protected]73852b8f2010-05-14 00:38:12144 return result;
145}
146
[email protected]e8368e92011-08-20 04:05:56147string16 GetSwitchValueString16(const CommandLine& command_line,
148 const char* switchName) {
149#ifdef OS_WIN
150 CommandLine::StringType native_switch_val;
151 native_switch_val = command_line.GetSwitchValueNative(switchName);
152 return string16(native_switch_val);
153#elif defined(OS_POSIX)
154 // POSIX Command line string types are different.
155 CommandLine::StringType native_switch_val;
156 native_switch_val = command_line.GetSwitchValueASCII(switchName);
157 // Convert the ASCII string to UTF16 to prepare to pass.
158 return string16(ASCIIToUTF16(native_switch_val));
159#endif
160}
161
[email protected]73852b8f2010-05-14 00:38:12162void CloudPrintDataSenderHelper::CallJavascriptFunction(
163 const std::wstring& function_name) {
[email protected]adcf8492011-03-09 22:41:39164 web_ui_->CallJavascriptFunction(WideToASCII(function_name));
[email protected]73852b8f2010-05-14 00:38:12165}
166
167void CloudPrintDataSenderHelper::CallJavascriptFunction(
168 const std::wstring& function_name, const Value& arg) {
[email protected]adcf8492011-03-09 22:41:39169 web_ui_->CallJavascriptFunction(WideToASCII(function_name), arg);
[email protected]73852b8f2010-05-14 00:38:12170}
171
172void CloudPrintDataSenderHelper::CallJavascriptFunction(
173 const std::wstring& function_name, const Value& arg1, const Value& arg2) {
[email protected]adcf8492011-03-09 22:41:39174 web_ui_->CallJavascriptFunction(WideToASCII(function_name), arg1, arg2);
[email protected]73852b8f2010-05-14 00:38:12175}
176
[email protected]e8368e92011-08-20 04:05:56177void CloudPrintDataSenderHelper::CallJavascriptFunction(
178 const std::wstring& function_name,
179 const Value& arg1,
180 const Value& arg2,
181 const Value& arg3) {
[email protected]46adf7ff2011-12-30 00:53:09182 web_ui_->CallJavascriptFunction(
183 WideToASCII(function_name), arg1, arg2, arg3);
[email protected]e8368e92011-08-20 04:05:56184}
185
[email protected]73852b8f2010-05-14 00:38:12186// Clears out the pointer we're using to communicate. Either routine is
187// potentially expensive enough that stopping whatever is in progress
188// is worth it.
189void CloudPrintDataSender::CancelPrintDataFile() {
[email protected]20305ec2011-01-21 04:55:52190 base::AutoLock lock(lock_);
[email protected]73852b8f2010-05-14 00:38:12191 // We don't own helper, it was passed in to us, so no need to
192 // delete, just let it go.
193 helper_ = NULL;
194}
195
[email protected]38e08982010-10-22 17:28:43196CloudPrintDataSender::CloudPrintDataSender(CloudPrintDataSenderHelper* helper,
[email protected]a984bdf2011-03-15 20:17:16197 const string16& print_job_title,
[email protected]e8368e92011-08-20 04:05:56198 const string16& print_ticket,
[email protected]a984bdf2011-03-15 20:17:16199 const std::string& file_type)
[email protected]38e08982010-10-22 17:28:43200 : helper_(helper),
[email protected]a984bdf2011-03-15 20:17:16201 print_job_title_(print_job_title),
[email protected]e8368e92011-08-20 04:05:56202 print_ticket_(print_ticket),
[email protected]a984bdf2011-03-15 20:17:16203 file_type_(file_type) {
[email protected]38e08982010-10-22 17:28:43204}
205
206CloudPrintDataSender::~CloudPrintDataSender() {}
207
[email protected]a984bdf2011-03-15 20:17:16208// Grab the raw file contents and massage them into shape for
[email protected]73852b8f2010-05-14 00:38:12209// sending to the dialog contents (and up to the cloud print server)
210// by encoding it and prefixing it with the appropriate mime type.
211// Once that is done, kick off the next part of the task on the IO
212// thread.
[email protected]650b2d52013-02-10 03:41:45213void CloudPrintDataSender::ReadPrintDataFile(
214 const base::FilePath& path_to_file) {
[email protected]ba4f1132010-10-09 02:02:35215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]73852b8f2010-05-14 00:38:12216 int64 file_size = 0;
[email protected]a984bdf2011-03-15 20:17:16217 if (file_util::GetFileSize(path_to_file, &file_size) && file_size != 0) {
[email protected]73852b8f2010-05-14 00:38:12218 std::string file_data;
219 if (file_size < kuint32max) {
220 file_data.reserve(static_cast<unsigned int>(file_size));
221 } else {
222 DLOG(WARNING) << " print data file too large to reserve space";
223 }
[email protected]a984bdf2011-03-15 20:17:16224 if (helper_ && file_util::ReadFileToString(path_to_file, &file_data)) {
[email protected]73852b8f2010-05-14 00:38:12225 std::string base64_data;
226 base::Base64Encode(file_data, &base64_data);
[email protected]a984bdf2011-03-15 20:17:16227 std::string header("data:");
228 header.append(file_type_);
229 header.append(";base64,");
[email protected]73852b8f2010-05-14 00:38:12230 base64_data.insert(0, header);
231 scoped_ptr<StringValue> new_data(new StringValue(base64_data));
232 print_data_.swap(new_data);
[email protected]3e2dd4fa2011-11-10 06:06:40233 BrowserThread::PostTask(
234 BrowserThread::IO, FROM_HERE,
235 base::Bind(&CloudPrintDataSender::SendPrintDataFile, this));
[email protected]73852b8f2010-05-14 00:38:12236 }
237 }
238}
239
240// We have the data in hand that needs to be pushed into the dialog
241// contents; do so from the IO thread.
242
243// TODO(scottbyer): If the print data ends up being larger than the
244// upload limit (currently 10MB), what we need to do is upload that
245// large data to google docs and set the URL in the printing
246// JavaScript to that location, and make sure it gets deleted when not
247// needed. - 4/1/2010
248void CloudPrintDataSender::SendPrintDataFile() {
[email protected]ba4f1132010-10-09 02:02:35249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]20305ec2011-01-21 04:55:52250 base::AutoLock lock(lock_);
[email protected]73852b8f2010-05-14 00:38:12251 if (helper_ && print_data_.get()) {
[email protected]9848c7e2010-06-03 16:06:56252 StringValue title(print_job_title_);
[email protected]e8368e92011-08-20 04:05:56253 StringValue ticket(print_ticket_);
254 // TODO(abodenha): Change Javascript call to pass in print ticket
255 // after server side support is added. Add test for it.
[email protected]73852b8f2010-05-14 00:38:12256
257 // Send the print data to the dialog contents. The JavaScript
258 // function is a preliminary API for prototyping purposes and is
259 // subject to change.
260 const_cast<CloudPrintDataSenderHelper*>(helper_)->CallJavascriptFunction(
261 L"printApp._printDataUrl", *print_data_, title);
262 }
263}
264
265
[email protected]650b2d52013-02-10 03:41:45266CloudPrintFlowHandler::CloudPrintFlowHandler(const base::FilePath& path_to_file,
[email protected]a984bdf2011-03-15 20:17:16267 const string16& print_job_title,
[email protected]e8368e92011-08-20 04:05:56268 const string16& print_ticket,
[email protected]4cd49022012-01-19 20:37:37269 const std::string& file_type,
270 bool close_after_signin,
271 const base::Closure& callback)
[email protected]c7bf7452011-09-12 21:31:50272 : dialog_delegate_(NULL),
273 path_to_file_(path_to_file),
[email protected]a984bdf2011-03-15 20:17:16274 print_job_title_(print_job_title),
[email protected]e8368e92011-08-20 04:05:56275 print_ticket_(print_ticket),
[email protected]4cd49022012-01-19 20:37:37276 file_type_(file_type),
277 close_after_signin_(close_after_signin),
278 callback_(callback) {
[email protected]38e08982010-10-22 17:28:43279}
280
281CloudPrintFlowHandler::~CloudPrintFlowHandler() {
282 // This will also cancel any task in flight.
283 CancelAnyRunningTask();
284}
285
286
[email protected]73852b8f2010-05-14 00:38:12287void CloudPrintFlowHandler::SetDialogDelegate(
[email protected]5835871a2012-04-25 21:56:55288 CloudPrintWebDialogDelegate* delegate) {
[email protected]7b748982011-02-14 19:28:23289 // Even if setting a new WebUI, it means any previous task needs
[email protected]a2c92a1c2012-04-03 12:32:14290 // to be canceled, its now invalid.
[email protected]ba4f1132010-10-09 02:02:35291 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12292 CancelAnyRunningTask();
293 dialog_delegate_ = delegate;
294}
295
296// Cancels any print data sender we have in flight and removes our
297// reference to it, so when the task that is calling it finishes and
[email protected]a2c92a1c2012-04-03 12:32:14298// removes its reference, it goes away.
[email protected]73852b8f2010-05-14 00:38:12299void CloudPrintFlowHandler::CancelAnyRunningTask() {
[email protected]ba4f1132010-10-09 02:02:35300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12301 if (print_data_sender_.get()) {
302 print_data_sender_->CancelPrintDataFile();
303 print_data_sender_ = NULL;
304 }
305}
306
[email protected]73852b8f2010-05-14 00:38:12307void CloudPrintFlowHandler::RegisterMessages() {
[email protected]73852b8f2010-05-14 00:38:12308 // TODO(scottbyer) - This is where we will register messages for the
309 // UI JS to use. Needed: Call to update page setup parameters.
[email protected]46adf7ff2011-12-30 00:53:09310 web_ui()->RegisterMessageCallback("ShowDebugger",
[email protected]ba4fc242011-10-04 18:56:56311 base::Bind(&CloudPrintFlowHandler::HandleShowDebugger,
312 base::Unretained(this)));
[email protected]46adf7ff2011-12-30 00:53:09313 web_ui()->RegisterMessageCallback("SendPrintData",
[email protected]ba4fc242011-10-04 18:56:56314 base::Bind(&CloudPrintFlowHandler::HandleSendPrintData,
315 base::Unretained(this)));
[email protected]46adf7ff2011-12-30 00:53:09316 web_ui()->RegisterMessageCallback("SetPageParameters",
[email protected]ba4fc242011-10-04 18:56:56317 base::Bind(&CloudPrintFlowHandler::HandleSetPageParameters,
318 base::Unretained(this)));
[email protected]73852b8f2010-05-14 00:38:12319
[email protected]0eb25c42011-08-11 14:50:14320 // Register for appropriate notifications, and re-direct the URL
321 // to the real server URL, now that we've gotten an HTML dialog
322 // going.
[email protected]c5eed492012-01-04 17:07:50323 NavigationController* controller =
[email protected]01ec4ec2012-01-18 04:13:47324 &web_ui()->GetWebContents()->GetController();
[email protected]10f417c52011-12-28 21:04:23325 NavigationEntry* pending_entry = controller->GetPendingEntry();
[email protected]0eb25c42011-08-11 14:50:14326 if (pending_entry) {
[email protected]46adf7ff2011-12-30 00:53:09327 Profile* profile = Profile::FromWebUI(web_ui());
[email protected]4cd49022012-01-19 20:37:37328 if (close_after_signin_) {
329 pending_entry->SetURL(
330 CloudPrintURL(profile).GetCloudPrintSigninURL());
331 } else {
332 pending_entry->SetURL(
333 CloudPrintURL(profile).GetCloudPrintServiceDialogURL());
334 }
[email protected]73852b8f2010-05-14 00:38:12335 }
[email protected]0eb25c42011-08-11 14:50:14336 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50337 content::Source<NavigationController>(controller));
[email protected]73852b8f2010-05-14 00:38:12338}
339
[email protected]6c2381d2011-10-19 02:52:53340void CloudPrintFlowHandler::Observe(
341 int type,
342 const content::NotificationSource& source,
343 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:27344 if (type == content::NOTIFICATION_LOAD_STOP) {
[email protected]20c52d22011-06-20 22:42:42345 // Take the opportunity to set some (minimal) additional
346 // script permissions required for the web UI.
[email protected]01ec4ec2012-01-18 04:13:47347 GURL url = web_ui()->GetWebContents()->GetURL();
[email protected]20c52d22011-06-20 22:42:42348 GURL dialog_url = CloudPrintURL(
[email protected]46adf7ff2011-12-30 00:53:09349 Profile::FromWebUI(web_ui())).GetCloudPrintServiceDialogURL();
[email protected]20c52d22011-06-20 22:42:42350 if (url.host() == dialog_url.host() &&
351 url.path() == dialog_url.path() &&
352 url.scheme() == dialog_url.scheme()) {
[email protected]01ec4ec2012-01-18 04:13:47353 RenderViewHost* rvh = web_ui()->GetWebContents()->GetRenderViewHost();
[email protected]746d3052012-05-22 15:15:47354 if (rvh) {
355 webkit_glue::WebPreferences webkit_prefs = rvh->GetWebkitPreferences();
[email protected]20c52d22011-06-20 22:42:42356 webkit_prefs.allow_scripts_to_close_windows = true;
[email protected]9abd51f2011-09-21 19:11:35357 rvh->UpdateWebkitPreferences(webkit_prefs);
[email protected]20c52d22011-06-20 22:42:42358 } else {
[email protected]746d3052012-05-22 15:15:47359 NOTREACHED();
[email protected]20c52d22011-06-20 22:42:42360 }
361 }
362
[email protected]73852b8f2010-05-14 00:38:12363 // Choose one or the other. If you need to debug, bring up the
364 // debugger. You can then use the various chrome.send()
365 // registrations above to kick of the various function calls,
366 // including chrome.send("SendPrintData") in the javaScript
367 // console and watch things happen with:
368 // HandleShowDebugger(NULL);
369 HandleSendPrintData(NULL);
370 }
371}
372
[email protected]88942a22010-08-19 20:34:43373void CloudPrintFlowHandler::HandleShowDebugger(const ListValue* args) {
[email protected]73852b8f2010-05-14 00:38:12374 ShowDebugger();
375}
376
377void CloudPrintFlowHandler::ShowDebugger() {
[email protected]46adf7ff2011-12-30 00:53:09378 if (web_ui()) {
[email protected]01ec4ec2012-01-18 04:13:47379 RenderViewHost* rvh = web_ui()->GetWebContents()->GetRenderViewHost();
[email protected]73852b8f2010-05-14 00:38:12380 if (rvh)
[email protected]aebdd072011-07-07 12:36:59381 DevToolsWindow::OpenDevToolsWindow(rvh);
[email protected]73852b8f2010-05-14 00:38:12382 }
383}
384
385scoped_refptr<CloudPrintDataSender>
386CloudPrintFlowHandler::CreateCloudPrintDataSender() {
[email protected]46adf7ff2011-12-30 00:53:09387 DCHECK(web_ui());
388 print_data_helper_.reset(new CloudPrintDataSenderHelper(web_ui()));
[email protected]a984bdf2011-03-15 20:17:16389 return new CloudPrintDataSender(print_data_helper_.get(),
390 print_job_title_,
[email protected]e8368e92011-08-20 04:05:56391 print_ticket_,
[email protected]a984bdf2011-03-15 20:17:16392 file_type_);
[email protected]73852b8f2010-05-14 00:38:12393}
394
[email protected]88942a22010-08-19 20:34:43395void CloudPrintFlowHandler::HandleSendPrintData(const ListValue* args) {
[email protected]ba4f1132010-10-09 02:02:35396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12397 // This will cancel any ReadPrintDataFile() or SendPrintDataFile()
398 // requests in flight (this is anticipation of when setting page
399 // setup parameters becomes asynchronous and may be set while some
400 // data is in flight). Then we can clear out the print data.
401 CancelAnyRunningTask();
[email protected]46adf7ff2011-12-30 00:53:09402 if (web_ui()) {
[email protected]73852b8f2010-05-14 00:38:12403 print_data_sender_ = CreateCloudPrintDataSender();
[email protected]3e2dd4fa2011-11-10 06:06:40404 BrowserThread::PostTask(
405 BrowserThread::FILE, FROM_HERE,
406 base::Bind(&CloudPrintDataSender::ReadPrintDataFile,
407 print_data_sender_.get(), path_to_file_));
[email protected]73852b8f2010-05-14 00:38:12408 }
409}
410
[email protected]88942a22010-08-19 20:34:43411void CloudPrintFlowHandler::HandleSetPageParameters(const ListValue* args) {
[email protected]036056a32011-03-03 21:05:01412 std::string json;
[email protected]e675f7b2011-06-22 17:32:12413 bool ret = args->GetString(0, &json);
414 if (!ret || json.empty()) {
[email protected]036056a32011-03-03 21:05:01415 NOTREACHED() << "Empty json string";
[email protected]73852b8f2010-05-14 00:38:12416 return;
[email protected]036056a32011-03-03 21:05:01417 }
[email protected]73852b8f2010-05-14 00:38:12418
419 // These are backstop default values - 72 dpi to match the screen,
420 // 8.5x11 inch paper with margins subtracted (1/4 inch top, left,
421 // right and 0.56 bottom), and the min page shrink and max page
422 // shrink values appear all over the place with no explanation.
423
424 // TODO(scottbyer): Get a Linux/ChromeOS edge for PrintSettings
425 // working so that we can get the default values from there. Fix up
426 // PrintWebViewHelper to do the same.
427 const int kDPI = 72;
428 const int kWidth = static_cast<int>((8.5-0.25-0.25)*kDPI);
429 const int kHeight = static_cast<int>((11-0.25-0.56)*kDPI);
430 const double kMinPageShrink = 1.25;
431 const double kMaxPageShrink = 2.0;
432
[email protected]1375e3ab2011-03-24 17:07:22433 PrintMsg_Print_Params default_settings;
[email protected]10980442011-12-04 22:33:05434 default_settings.content_size = gfx::Size(kWidth, kHeight);
[email protected]732b8132012-01-10 23:17:32435 default_settings.printable_area = gfx::Rect(0, 0, kWidth, kHeight);
[email protected]73852b8f2010-05-14 00:38:12436 default_settings.dpi = kDPI;
437 default_settings.min_shrink = kMinPageShrink;
438 default_settings.max_shrink = kMaxPageShrink;
439 default_settings.desired_dpi = kDPI;
440 default_settings.document_cookie = 0;
441 default_settings.selection_only = false;
[email protected]718af822011-08-12 22:11:33442 default_settings.preview_request_id = 0;
443 default_settings.is_first_request = true;
[email protected]732b8132012-01-10 23:17:32444 default_settings.print_to_pdf = false;
[email protected]73852b8f2010-05-14 00:38:12445
446 if (!GetPageSetupParameters(json, default_settings)) {
447 NOTREACHED();
448 return;
449 }
450
451 // TODO(scottbyer) - Here is where we would kick the originating
452 // renderer thread with these new parameters in order to get it to
[email protected]a984bdf2011-03-15 20:17:16453 // re-generate the PDF data and hand it back to us. window.print() is
[email protected]73852b8f2010-05-14 00:38:12454 // currently synchronous, so there's a lot of work to do to get to
455 // that point.
456}
457
[email protected]ea161da2010-11-02 21:57:35458void CloudPrintFlowHandler::StoreDialogClientSize() const {
[email protected]01ec4ec2012-01-18 04:13:47459 if (web_ui() && web_ui()->GetWebContents() &&
460 web_ui()->GetWebContents()->GetView()) {
461 gfx::Size size = web_ui()->GetWebContents()->GetView()->GetContainerSize();
[email protected]46adf7ff2011-12-30 00:53:09462 Profile* profile = Profile::FromWebUI(web_ui());
[email protected]0eb25c42011-08-11 14:50:14463 profile->GetPrefs()->SetInteger(prefs::kCloudPrintDialogWidth,
464 size.width());
465 profile->GetPrefs()->SetInteger(prefs::kCloudPrintDialogHeight,
466 size.height());
[email protected]ea161da2010-11-02 21:57:35467 }
468}
469
[email protected]a911c4e2012-10-12 00:37:57470bool CloudPrintFlowHandler::NavigationToURLDidCloseDialog(const GURL& url) {
471 if (close_after_signin_) {
472 GURL dialog_url = CloudPrintURL(
473 Profile::FromWebUI(web_ui())).GetCloudPrintServiceURL();
474
475 if (url.host() == dialog_url.host() &&
[email protected]22f450492013-02-20 22:02:51476 StartsWithASCII(url.path(), dialog_url.path(), false) &&
[email protected]a911c4e2012-10-12 00:37:57477 url.scheme() == dialog_url.scheme()) {
478 StoreDialogClientSize();
479 web_ui()->GetWebContents()->GetRenderViewHost()->ClosePage();
480 callback_.Run();
481 return true;
482 }
483 }
484 return false;
485}
486
[email protected]5835871a2012-04-25 21:56:55487CloudPrintWebDialogDelegate::CloudPrintWebDialogDelegate(
[email protected]b5b79d72012-05-24 19:42:28488 content::BrowserContext* browser_context,
489 gfx::NativeWindow modal_parent,
[email protected]650b2d52013-02-10 03:41:45490 const base::FilePath& path_to_file,
[email protected]9848c7e2010-06-03 16:06:56491 const std::string& json_arguments,
[email protected]e39027a2011-01-24 21:41:54492 const string16& print_job_title,
[email protected]e8368e92011-08-20 04:05:56493 const string16& print_ticket,
[email protected]a984bdf2011-03-15 20:17:16494 const std::string& file_type,
[email protected]4cd49022012-01-19 20:37:37495 bool delete_on_close,
496 bool close_after_signin,
497 const base::Closure& callback)
[email protected]d955fc92011-09-19 20:49:03498 : delete_on_close_(delete_on_close),
499 flow_handler_(new CloudPrintFlowHandler(path_to_file,
[email protected]a984bdf2011-03-15 20:17:16500 print_job_title,
[email protected]e8368e92011-08-20 04:05:56501 print_ticket,
[email protected]4cd49022012-01-19 20:37:37502 file_type,
503 close_after_signin,
504 callback)),
[email protected]b5b79d72012-05-24 19:42:28505 modal_parent_(modal_parent),
[email protected]6ddda232011-04-22 15:41:47506 owns_flow_handler_(true),
[email protected]b5b79d72012-05-24 19:42:28507 path_to_file_(path_to_file),
508 keep_alive_when_non_modal_(true) {
509 Init(browser_context, json_arguments);
[email protected]73852b8f2010-05-14 00:38:12510}
511
[email protected]05acb55472011-02-03 00:11:07512// For unit testing.
[email protected]5835871a2012-04-25 21:56:55513CloudPrintWebDialogDelegate::CloudPrintWebDialogDelegate(
[email protected]650b2d52013-02-10 03:41:45514 const base::FilePath& path_to_file,
[email protected]73852b8f2010-05-14 00:38:12515 CloudPrintFlowHandler* flow_handler,
[email protected]e39027a2011-01-24 21:41:54516 const std::string& json_arguments,
[email protected]d955fc92011-09-19 20:49:03517 bool delete_on_close)
518 : delete_on_close_(delete_on_close),
519 flow_handler_(flow_handler),
[email protected]b5b79d72012-05-24 19:42:28520 modal_parent_(NULL),
521 owns_flow_handler_(true),
522 keep_alive_when_non_modal_(false) {
523 Init(NULL, json_arguments);
[email protected]73852b8f2010-05-14 00:38:12524}
525
[email protected]b5b79d72012-05-24 19:42:28526// Returns the persisted width/height for the print dialog.
527void GetDialogWidthAndHeightFromPrefs(content::BrowserContext* browser_context,
528 int* width,
529 int* height) {
[email protected]b5b79d72012-05-24 19:42:28530 if (!browser_context) {
531 *width = kDefaultWidth;
532 *height = kDefaultHeight;
533 return;
534 }
535
[email protected]c753f142013-02-10 13:14:04536 PrefService* prefs = Profile::FromBrowserContext(browser_context)->GetPrefs();
[email protected]c753f142013-02-10 13:14:04537 *width = prefs->GetInteger(prefs::kCloudPrintDialogWidth);
538 *height = prefs->GetInteger(prefs::kCloudPrintDialogHeight);
[email protected]b5b79d72012-05-24 19:42:28539}
540
541void CloudPrintWebDialogDelegate::Init(content::BrowserContext* browser_context,
[email protected]5835871a2012-04-25 21:56:55542 const std::string& json_arguments) {
[email protected]73852b8f2010-05-14 00:38:12543 // This information is needed to show the dialog HTML content.
[email protected]ba4f1132010-10-09 02:02:35544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]b5b79d72012-05-24 19:42:28545
[email protected]89f550b2011-06-08 18:34:03546 params_.url = GURL(chrome::kChromeUICloudPrintResourcesURL);
[email protected]b5b79d72012-05-24 19:42:28547 GetDialogWidthAndHeightFromPrefs(browser_context,
548 &params_.width,
549 &params_.height);
[email protected]73852b8f2010-05-14 00:38:12550 params_.json_input = json_arguments;
551
552 flow_handler_->SetDialogDelegate(this);
[email protected]e39027a2011-01-24 21:41:54553 // If we're not modal we can show the dialog with no browser.
554 // We need this to keep Chrome alive while our dialog is up.
[email protected]b5b79d72012-05-24 19:42:28555 if (!modal_parent_ && keep_alive_when_non_modal_)
[email protected]313fce12013-01-30 17:09:04556 chrome::StartKeepAlive();
[email protected]73852b8f2010-05-14 00:38:12557}
558
[email protected]5835871a2012-04-25 21:56:55559CloudPrintWebDialogDelegate::~CloudPrintWebDialogDelegate() {
[email protected]73852b8f2010-05-14 00:38:12560 // If the flow_handler_ is about to outlive us because we don't own
[email protected]a2c92a1c2012-04-03 12:32:14561 // it anymore, we need to have it remove its reference to us.
[email protected]ba4f1132010-10-09 02:02:35562 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]73852b8f2010-05-14 00:38:12563 flow_handler_->SetDialogDelegate(NULL);
564 if (owns_flow_handler_) {
565 delete flow_handler_;
566 }
567}
568
[email protected]5835871a2012-04-25 21:56:55569ui::ModalType CloudPrintWebDialogDelegate::GetDialogModalType() const {
[email protected]b5b79d72012-05-24 19:42:28570 return modal_parent_ ? ui::MODAL_TYPE_WINDOW : ui::MODAL_TYPE_NONE;
[email protected]73852b8f2010-05-14 00:38:12571}
572
[email protected]5835871a2012-04-25 21:56:55573string16 CloudPrintWebDialogDelegate::GetDialogTitle() const {
[email protected]bdae5c12011-08-05 21:49:06574 return string16();
[email protected]73852b8f2010-05-14 00:38:12575}
576
[email protected]5835871a2012-04-25 21:56:55577GURL CloudPrintWebDialogDelegate::GetDialogContentURL() const {
[email protected]73852b8f2010-05-14 00:38:12578 return params_.url;
579}
580
[email protected]5835871a2012-04-25 21:56:55581void CloudPrintWebDialogDelegate::GetWebUIMessageHandlers(
[email protected]36e12172011-02-08 23:46:02582 std::vector<WebUIMessageHandler*>* handlers) const {
[email protected]73852b8f2010-05-14 00:38:12583 handlers->push_back(flow_handler_);
584 // We don't own flow_handler_ anymore, but it sticks around until at
585 // least right after OnDialogClosed() is called (and this object is
586 // destroyed).
587 owns_flow_handler_ = false;
588}
589
[email protected]5835871a2012-04-25 21:56:55590void CloudPrintWebDialogDelegate::GetDialogSize(gfx::Size* size) const {
[email protected]73852b8f2010-05-14 00:38:12591 size->set_width(params_.width);
592 size->set_height(params_.height);
593}
594
[email protected]5835871a2012-04-25 21:56:55595std::string CloudPrintWebDialogDelegate::GetDialogArgs() const {
[email protected]73852b8f2010-05-14 00:38:12596 return params_.json_input;
597}
598
[email protected]5835871a2012-04-25 21:56:55599void CloudPrintWebDialogDelegate::OnDialogClosed(
[email protected]73852b8f2010-05-14 00:38:12600 const std::string& json_retval) {
[email protected]ea161da2010-11-02 21:57:35601 // Get the final dialog size and store it.
602 flow_handler_->StoreDialogClientSize();
[email protected]6ddda232011-04-22 15:41:47603
[email protected]d955fc92011-09-19 20:49:03604 if (delete_on_close_) {
[email protected]3e2dd4fa2011-11-10 06:06:40605 BrowserThread::PostTask(
606 BrowserThread::FILE, FROM_HERE,
607 base::Bind(&internal_cloud_print_helpers::Delete, path_to_file_));
[email protected]6ddda232011-04-22 15:41:47608 }
609
[email protected]e39027a2011-01-24 21:41:54610 // If we're modal we can show the dialog with no browser.
611 // End the keep-alive so that Chrome can exit.
[email protected]b5b79d72012-05-24 19:42:28612 if (!modal_parent_ && keep_alive_when_non_modal_)
[email protected]313fce12013-01-30 17:09:04613 chrome::EndKeepAlive();
[email protected]73852b8f2010-05-14 00:38:12614 delete this;
615}
616
[email protected]5835871a2012-04-25 21:56:55617void CloudPrintWebDialogDelegate::OnCloseContents(WebContents* source,
618 bool* out_close_dialog) {
[email protected]18137e02010-05-25 21:10:35619 if (out_close_dialog)
620 *out_close_dialog = true;
621}
622
[email protected]5835871a2012-04-25 21:56:55623bool CloudPrintWebDialogDelegate::ShouldShowDialogTitle() const {
[email protected]ea161da2010-11-02 21:57:35624 return false;
625}
626
[email protected]5835871a2012-04-25 21:56:55627bool CloudPrintWebDialogDelegate::HandleContextMenu(
[email protected]35be7ec2012-02-12 20:42:51628 const content::ContextMenuParams& params) {
[email protected]34478212011-04-19 01:35:46629 return true;
630}
631
[email protected]a911c4e2012-10-12 00:37:57632bool CloudPrintWebDialogDelegate::HandleOpenURLFromTab(
633 content::WebContents* source,
634 const content::OpenURLParams& params,
635 content::WebContents** out_new_contents) {
636 return flow_handler_->NavigationToURLDidCloseDialog(params.url);
637}
638
[email protected]b5b79d72012-05-24 19:42:28639void CreatePrintDialogForBytesImpl(content::BrowserContext* browser_context,
640 gfx::NativeWindow modal_parent,
641 scoped_refptr<base::RefCountedBytes> data,
[email protected]d955fc92011-09-19 20:49:03642 const string16& print_job_title,
643 const string16& print_ticket,
[email protected]b5b79d72012-05-24 19:42:28644 const std::string& file_type) {
[email protected]d955fc92011-09-19 20:49:03645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
646 // TODO([email protected]) Writing the PDF to a file before printing
647 // is wasteful. Modify the dialog flow to pull PDF data from memory.
648 // See http://code.google.com/p/chromium/issues/detail?id=44093
[email protected]650b2d52013-02-10 03:41:45649 base::FilePath path;
[email protected]d955fc92011-09-19 20:49:03650 if (file_util::CreateTemporaryFile(&path)) {
651 file_util::WriteFile(path,
652 reinterpret_cast<const char*>(data->front()),
653 data->size());
654 }
[email protected]b5b79d72012-05-24 19:42:28655 print_dialog_cloud::CreatePrintDialogForFile(browser_context,
656 modal_parent,
657 path,
[email protected]d955fc92011-09-19 20:49:03658 print_job_title,
659 print_ticket,
660 file_type,
[email protected]d955fc92011-09-19 20:49:03661 true);
662}
663
[email protected]6085c70d2011-03-22 22:51:07664// Called from the UI thread, starts up the dialog.
[email protected]b5b79d72012-05-24 19:42:28665void CreateDialogImpl(content::BrowserContext* browser_context,
666 gfx::NativeWindow modal_parent,
[email protected]650b2d52013-02-10 03:41:45667 const base::FilePath& path_to_file,
[email protected]6085c70d2011-03-22 22:51:07668 const string16& print_job_title,
[email protected]e8368e92011-08-20 04:05:56669 const string16& print_ticket,
[email protected]6085c70d2011-03-22 22:51:07670 const std::string& file_type,
[email protected]4cd49022012-01-19 20:37:37671 bool delete_on_close,
672 bool close_after_signin,
673 const base::Closure& callback) {
[email protected]ba4f1132010-10-09 02:02:35674 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]5835871a2012-04-25 21:56:55675 WebDialogDelegate* dialog_delegate =
676 new internal_cloud_print_helpers::CloudPrintWebDialogDelegate(
[email protected]b5b79d72012-05-24 19:42:28677 browser_context,
678 modal_parent,
679 path_to_file,
680 std::string(),
681 print_job_title,
682 print_ticket,
683 file_type,
684 delete_on_close,
685 close_after_signin,
[email protected]4cd49022012-01-19 20:37:37686 callback);
[email protected]88bfd25b2012-06-22 06:28:33687#if defined(OS_WIN)
688 gfx::NativeWindow window =
689#endif
[email protected]87586fb72012-07-02 13:15:02690 chrome::ShowWebDialog(modal_parent,
691 Profile::FromBrowserContext(browser_context),
692 dialog_delegate);
[email protected]88bfd25b2012-06-22 06:28:33693#if defined(OS_WIN)
694 if (!path_to_file.empty() && window) {
695 HWND dialog_handle;
696#if defined(USE_AURA)
697 dialog_handle = window->GetRootWindow()->GetAcceleratedWidget();
698#else
699 dialog_handle = window;
700#endif
701 if (::GetForegroundWindow() != dialog_handle) {
702 ui::ForegroundHelper::SetForeground(dialog_handle);
703 }
704 }
705#endif
[email protected]73852b8f2010-05-14 00:38:12706}
[email protected]6085c70d2011-03-22 22:51:07707
[email protected]b5b79d72012-05-24 19:42:28708void CreateDialogSigninImpl(content::BrowserContext* browser_context,
709 gfx::NativeWindow modal_parent,
710 const base::Closure& callback) {
[email protected]650b2d52013-02-10 03:41:45711 CreateDialogImpl(browser_context, modal_parent, base::FilePath(), string16(),
[email protected]b5b79d72012-05-24 19:42:28712 string16(), std::string(), false, true, callback);
[email protected]4cd49022012-01-19 20:37:37713}
714
[email protected]b5b79d72012-05-24 19:42:28715void CreateDialogFullImpl(content::BrowserContext* browser_context,
716 gfx::NativeWindow modal_parent,
[email protected]650b2d52013-02-10 03:41:45717 const base::FilePath& path_to_file,
[email protected]b5b79d72012-05-24 19:42:28718 const string16& print_job_title,
719 const string16& print_ticket,
720 const std::string& file_type,
721 bool delete_on_close) {
722 CreateDialogImpl(browser_context, modal_parent, path_to_file, print_job_title,
723 print_ticket, file_type, delete_on_close, false,
724 base::Closure());
[email protected]4cd49022012-01-19 20:37:37725}
726
727
728
[email protected]6ddda232011-04-22 15:41:47729// Provides a runnable function to delete a file.
[email protected]650b2d52013-02-10 03:41:45730void Delete(const base::FilePath& file_path) {
[email protected]6ddda232011-04-22 15:41:47731 file_util::Delete(file_path, false);
732}
733
[email protected]6085c70d2011-03-22 22:51:07734} // namespace internal_cloud_print_helpers
735
736namespace print_dialog_cloud {
737
[email protected]681958c2013-02-21 13:48:14738void RegisterUserPrefs(PrefRegistrySyncable* registry) {
739 registry->RegisterIntegerPref(
740 prefs::kCloudPrintDialogWidth,
741 kDefaultWidth,
742 PrefRegistrySyncable::UNSYNCABLE_PREF);
743 registry->RegisterIntegerPref(
744 prefs::kCloudPrintDialogHeight,
745 kDefaultHeight,
746 PrefRegistrySyncable::UNSYNCABLE_PREF);
747}
748
[email protected]6085c70d2011-03-22 22:51:07749// Called on the FILE or UI thread. This is the main entry point into creating
750// the dialog.
751
752// TODO(scottbyer): The signature here will need to change as the
753// workflow through the printing code changes to allow for dynamically
754// changing page setup parameters while the dialog is active.
[email protected]b5b79d72012-05-24 19:42:28755void CreatePrintDialogForFile(content::BrowserContext* browser_context,
756 gfx::NativeWindow modal_parent,
[email protected]650b2d52013-02-10 03:41:45757 const base::FilePath& path_to_file,
[email protected]6085c70d2011-03-22 22:51:07758 const string16& print_job_title,
[email protected]e8368e92011-08-20 04:05:56759 const string16& print_ticket,
[email protected]6085c70d2011-03-22 22:51:07760 const std::string& file_type,
[email protected]d955fc92011-09-19 20:49:03761 bool delete_on_close) {
[email protected]6085c70d2011-03-22 22:51:07762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE) ||
763 BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]6085c70d2011-03-22 22:51:07764 BrowserThread::PostTask(
765 BrowserThread::UI, FROM_HERE,
[email protected]4cd49022012-01-19 20:37:37766 base::Bind(&internal_cloud_print_helpers::CreateDialogFullImpl,
[email protected]b5b79d72012-05-24 19:42:28767 browser_context, modal_parent, path_to_file, print_job_title,
768 print_ticket, file_type, delete_on_close));
[email protected]d955fc92011-09-19 20:49:03769}
770
[email protected]b5b79d72012-05-24 19:42:28771void CreateCloudPrintSigninDialog(content::BrowserContext* browser_context,
772 gfx::NativeWindow modal_parent,
773 const base::Closure& callback) {
[email protected]4cd49022012-01-19 20:37:37774 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
775
776 BrowserThread::PostTask(
777 BrowserThread::UI, FROM_HERE,
778 base::Bind(&internal_cloud_print_helpers::CreateDialogSigninImpl,
[email protected]b5b79d72012-05-24 19:42:28779 browser_context,
780 modal_parent,
[email protected]4cd49022012-01-19 20:37:37781 callback));
782}
783
[email protected]b5b79d72012-05-24 19:42:28784void CreatePrintDialogForBytes(content::BrowserContext* browser_context,
785 gfx::NativeWindow modal_parent,
[email protected]60b6a2532013-01-21 08:08:31786 const base::RefCountedBytes* data,
[email protected]d955fc92011-09-19 20:49:03787 const string16& print_job_title,
788 const string16& print_ticket,
[email protected]b5b79d72012-05-24 19:42:28789 const std::string& file_type) {
[email protected]d955fc92011-09-19 20:49:03790 // TODO([email protected]) Avoid cloning the PDF data. Make use of a
791 // shared memory object instead.
792 // http://code.google.com/p/chromium/issues/detail?id=44093
[email protected]ebbccb952012-04-20 09:51:31793 scoped_refptr<base::RefCountedBytes> cloned_data =
794 new base::RefCountedBytes(data->data());
[email protected]d955fc92011-09-19 20:49:03795 BrowserThread::PostTask(
796 BrowserThread::FILE, FROM_HERE,
[email protected]3e2dd4fa2011-11-10 06:06:40797 base::Bind(&internal_cloud_print_helpers::CreatePrintDialogForBytesImpl,
[email protected]b5b79d72012-05-24 19:42:28798 browser_context, modal_parent, cloned_data, print_job_title,
799 print_ticket, file_type));
[email protected]6085c70d2011-03-22 22:51:07800}
801
[email protected]65c9d89a2011-04-13 21:02:39802bool CreatePrintDialogFromCommandLine(const CommandLine& command_line) {
[email protected]87ab41e72012-01-04 18:45:11803 DCHECK(command_line.HasSwitch(switches::kCloudPrintFile));
[email protected]65c9d89a2011-04-13 21:02:39804 if (!command_line.GetSwitchValuePath(switches::kCloudPrintFile).empty()) {
[email protected]650b2d52013-02-10 03:41:45805 base::FilePath cloud_print_file;
[email protected]65c9d89a2011-04-13 21:02:39806 cloud_print_file =
807 command_line.GetSwitchValuePath(switches::kCloudPrintFile);
808 if (!cloud_print_file.empty()) {
809 string16 print_job_title;
[email protected]e8368e92011-08-20 04:05:56810 string16 print_job_print_ticket;
[email protected]65c9d89a2011-04-13 21:02:39811 if (command_line.HasSwitch(switches::kCloudPrintJobTitle)) {
[email protected]e8368e92011-08-20 04:05:56812 print_job_title =
813 internal_cloud_print_helpers::GetSwitchValueString16(
814 command_line, switches::kCloudPrintJobTitle);
815 }
816 if (command_line.HasSwitch(switches::kCloudPrintPrintTicket)) {
817 print_job_print_ticket =
818 internal_cloud_print_helpers::GetSwitchValueString16(
819 command_line, switches::kCloudPrintPrintTicket);
[email protected]65c9d89a2011-04-13 21:02:39820 }
821 std::string file_type = "application/pdf";
822 if (command_line.HasSwitch(switches::kCloudPrintFileType)) {
823 file_type = command_line.GetSwitchValueASCII(
824 switches::kCloudPrintFileType);
825 }
[email protected]e8368e92011-08-20 04:05:56826
[email protected]d955fc92011-09-19 20:49:03827 bool delete_on_close = CommandLine::ForCurrentProcess()->HasSwitch(
828 switches::kCloudPrintDeleteFile);
829
[email protected]b5b79d72012-05-24 19:42:28830 print_dialog_cloud::CreatePrintDialogForFile(
831 ProfileManager::GetDefaultProfile(),
832 NULL,
833 cloud_print_file,
834 print_job_title,
835 print_job_print_ticket,
836 file_type,
837 delete_on_close);
[email protected]65c9d89a2011-04-13 21:02:39838 return true;
839 }
840 }
841 return false;
842}
843
[email protected]6085c70d2011-03-22 22:51:07844} // end namespace