summaryrefslogtreecommitdiffstats
path: root/chrome/service/cloud_print
diff options
context:
space:
mode:
authorvitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-09 22:51:37 +0000
committervitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-09 22:51:37 +0000
commit07834e5a7510157c9f2cd8e707c80bc0aa4e720f (patch)
tree031597aea87c8b90e7d011e0bc383bba1a1644f3 /chrome/service/cloud_print
parent3dff2efd9274c6b14a69b9b0dd14d730badaae33 (diff)
downloadchromium_src-07834e5a7510157c9f2cd8e707c80bc0aa4e720f.zip
chromium_src-07834e5a7510157c9f2cd8e707c80bc0aa4e720f.tar.gz
chromium_src-07834e5a7510157c9f2cd8e707c80bc0aa4e720f.tar.bz2
Fallback to CDD/CJT if connector can't initialize XPS API.
BUG=313274 Review URL: https://codereview.chromium.org/147953009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250018 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/service/cloud_print')
-rw-r--r--chrome/service/cloud_print/cdd_conversion_win.cc118
-rw-r--r--chrome/service/cloud_print/cdd_conversion_win.h9
-rw-r--r--chrome/service/cloud_print/cloud_print_connector.cc2
-rw-r--r--chrome/service/cloud_print/print_system.h4
-rw-r--r--chrome/service/cloud_print/print_system_cups.cc5
-rw-r--r--chrome/service/cloud_print/print_system_win.cc57
-rw-r--r--chrome/service/cloud_print/printer_job_handler.cc18
-rw-r--r--chrome/service/cloud_print/printer_job_handler_unittest.cc1
8 files changed, 185 insertions, 29 deletions
diff --git a/chrome/service/cloud_print/cdd_conversion_win.cc b/chrome/service/cloud_print/cdd_conversion_win.cc
index 2c7a9a4..f1e8ffd 100644
--- a/chrome/service/cloud_print/cdd_conversion_win.cc
+++ b/chrome/service/cloud_print/cdd_conversion_win.cc
@@ -10,6 +10,124 @@
namespace cloud_print {
+bool IsValidCjt(const std::string& print_ticket_data) {
+ cloud_devices::CloudDeviceDescription description;
+ return description.InitFromString(print_ticket_data);
+}
+
+scoped_ptr<DEVMODE[]> CjtToDevMode(const base::string16& printer_name,
+ const std::string& print_ticket) {
+ cloud_devices::CloudDeviceDescription description;
+ if (!description.InitFromString(print_ticket))
+ return scoped_ptr<DEVMODE[]>();
+
+ printing::ScopedPrinterHandle printer;
+ if (!printer.OpenPrinter(printer_name.c_str()))
+ return scoped_ptr<DEVMODE[]>();
+
+ wchar_t* mutable_name = const_cast<wchar_t*>(printer_name.c_str());
+ LONG buffer_size =
+ DocumentProperties(NULL, printer, mutable_name, NULL, NULL, 0);
+ if (buffer_size <= 0)
+ return scoped_ptr<DEVMODE[]>();
+
+ scoped_ptr<DEVMODE[]> scoped_dev_mode(
+ reinterpret_cast<DEVMODE*>(new uint8[buffer_size]));
+ DEVMODE* dev_mode = scoped_dev_mode.get();
+ if (DocumentProperties(NULL, printer, mutable_name, dev_mode, NULL,
+ DM_OUT_BUFFER) != IDOK) {
+ return scoped_ptr<DEVMODE[]>();
+ }
+
+ using namespace cloud_devices::printer;
+ ColorTicketItem color;
+ DuplexTicketItem duplex;
+ OrientationTicketItem orientation;
+ MarginsTicketItem margins;
+ DpiTicketItem dpi;
+ FitToPageTicketItem fit_to_page;
+ MediaTicketItem media;
+ CopiesTicketItem copies;
+ PageRangeTicketItem page_range;
+ CollateTicketItem collate;
+ ReverseTicketItem reverse;
+
+ if (orientation.LoadFrom(description)) {
+ dev_mode->dmFields |= DM_ORIENTATION;
+ if (orientation.value() == LANDSCAPE) {
+ dev_mode->dmOrientation = DMORIENT_LANDSCAPE;
+ } else {
+ dev_mode->dmOrientation = DMORIENT_PORTRAIT;
+ }
+ }
+
+ if (color.LoadFrom(description)) {
+ dev_mode->dmFields |= DM_COLOR;
+ if (color.value().type == STANDARD_MONOCHROME) {
+ dev_mode->dmColor = DMCOLOR_MONOCHROME;
+ } else if (color.value().type == STANDARD_COLOR) {
+ dev_mode->dmColor = DMCOLOR_COLOR;
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ if (duplex.LoadFrom(description)) {
+ dev_mode->dmFields |= DM_DUPLEX;
+ if (duplex.value() == NO_DUPLEX) {
+ dev_mode->dmDuplex = DMDUP_SIMPLEX;
+ } else if (duplex.value() == LONG_EDGE) {
+ dev_mode->dmDuplex = DMDUP_VERTICAL;
+ } else if (duplex.value() == SHORT_EDGE) {
+ dev_mode->dmDuplex = DMDUP_HORIZONTAL;
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ if (copies.LoadFrom(description)) {
+ dev_mode->dmFields |= DM_COPIES;
+ dev_mode->dmCopies = copies.value();
+ }
+
+ if (dpi.LoadFrom(description)) {
+ if (dpi.value().horizontal > 0) {
+ dev_mode->dmFields |= DM_PRINTQUALITY;
+ dev_mode->dmPrintQuality = dpi.value().horizontal;
+ }
+ if (dpi.value().vertical > 0) {
+ dev_mode->dmFields |= DM_YRESOLUTION;
+ dev_mode->dmYResolution = dpi.value().vertical;
+ }
+ }
+
+ if (collate.LoadFrom(description)) {
+ dev_mode->dmFields |= DM_COLLATE;
+ dev_mode->dmCollate = (collate.value() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE);
+ }
+
+ if (media.LoadFrom(description)) {
+ static const size_t kFromUm = 100; // Windows uses 0.1mm.
+ int width = media.value().width_um / kFromUm;
+ int height = media.value().height_um / kFromUm;
+ if (width > 0) {
+ dev_mode->dmFields |= DM_PAPERWIDTH;
+ dev_mode->dmPaperWidth = width;
+ }
+ if (height > 0) {
+ dev_mode->dmFields |= DM_PAPERLENGTH;
+ dev_mode->dmPaperLength = height;
+ }
+ }
+
+ if (DocumentProperties(NULL, printer, mutable_name, dev_mode, dev_mode,
+ DM_OUT_BUFFER | DM_IN_BUFFER) != IDOK) {
+ return scoped_ptr<DEVMODE[]>();
+ }
+
+ return scoped_dev_mode.Pass();
+}
+
std::string CapabilitiesToCdd(
const printing::PrinterSemanticCapsAndDefaults& semantic_info) {
using namespace cloud_devices::printer;
diff --git a/chrome/service/cloud_print/cdd_conversion_win.h b/chrome/service/cloud_print/cdd_conversion_win.h
index 0855922..cd751c4 100644
--- a/chrome/service/cloud_print/cdd_conversion_win.h
+++ b/chrome/service/cloud_print/cdd_conversion_win.h
@@ -6,6 +6,10 @@
#define CHROME_SERVICE_CLOUD_PRINT_CDD_CONVERSION_WIN_H_
#include <string>
+#include <windows.h>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
namespace printing {
struct PrinterSemanticCapsAndDefaults;
@@ -13,6 +17,11 @@ struct PrinterSemanticCapsAndDefaults;
namespace cloud_print {
+bool IsValidCjt(const std::string& print_ticket);
+
+scoped_ptr<DEVMODE[]> CjtToDevMode(const base::string16& printer_name,
+ const std::string& print_ticket);
+
std::string CapabilitiesToCdd(
const printing::PrinterSemanticCapsAndDefaults& semantic_info);
diff --git a/chrome/service/cloud_print/cloud_print_connector.cc b/chrome/service/cloud_print/cloud_print_connector.cc
index 94c18f0..59aa5dd 100644
--- a/chrome/service/cloud_print/cloud_print_connector.cc
+++ b/chrome/service/cloud_print/cloud_print_connector.cc
@@ -622,7 +622,7 @@ void CloudPrintConnector::OnReceivePrinterCaps(
settings_.xmpp_ping_timeout_sec()),
mime_boundary, std::string(), &post_data);
post_data += GetPostDataForPrinterInfo(info, mime_boundary);
- if (caps_and_defaults.caps_mime_type == kContentTypeCDD) {
+ if (caps_and_defaults.caps_mime_type == kContentTypeJSON) {
net::AddMultipartValueForUpload(kUseCDD, "true", mime_boundary,
std::string(), &post_data);
}
diff --git a/chrome/service/cloud_print/print_system.h b/chrome/service/cloud_print/print_system.h
index 4181363..2da5f31 100644
--- a/chrome/service/cloud_print/print_system.h
+++ b/chrome/service/cloud_print/print_system.h
@@ -195,6 +195,10 @@ class PrintSystem : public base::RefCountedThreadSafe<PrintSystem> {
const std::string& printer_name) = 0;
virtual JobSpooler* CreateJobSpooler() = 0;
+ // Returns a true if connector should use CDD for capabilities and CJT as
+ // print ticket.
+ virtual bool UseCddAndCjt() = 0;
+
// Returns a comma separated list of mimetypes for print data that are
// supported by this print system. The format of this string is the same as
// that used for the HTTP Accept: header.
diff --git a/chrome/service/cloud_print/print_system_cups.cc b/chrome/service/cloud_print/print_system_cups.cc
index 9b14861..9b3ec23 100644
--- a/chrome/service/cloud_print/print_system_cups.cc
+++ b/chrome/service/cloud_print/print_system_cups.cc
@@ -96,6 +96,7 @@ class PrintSystemCUPS : public PrintSystem {
virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher(
const std::string& printer_name) OVERRIDE;
virtual PrintSystem::JobSpooler* CreateJobSpooler() OVERRIDE;
+ virtual bool UseCddAndCjt() OVERRIDE;
virtual std::string GetSupportedMimeTypes() OVERRIDE;
// Helper functions.
@@ -728,6 +729,10 @@ PrintSystem::JobSpooler* PrintSystemCUPS::CreateJobSpooler() {
return new JobSpoolerCUPS(this);
}
+bool PrintSystemCUPS::UseCddAndCjt() {
+ return false;
+}
+
std::string PrintSystemCUPS::GetSupportedMimeTypes() {
return supported_mime_types_;
}
diff --git a/chrome/service/cloud_print/print_system_win.cc b/chrome/service/cloud_print/print_system_win.cc
index 36891b8..765ea0f 100644
--- a/chrome/service/cloud_print/print_system_win.cc
+++ b/chrome/service/cloud_print/print_system_win.cc
@@ -77,18 +77,14 @@ scoped_ptr<DEVMODE[]> XpsTicketToDevMode(const base::string16& printer_name,
if (SUCCEEDED(hr)) {
// Correct DEVMODE using DocumentProperties. See documentation for
// PTConvertPrintTicketToDevMode.
- LONG buffer_size =
- DocumentProperties(NULL, printer,
- const_cast<LPWSTR>(printer_name.c_str()), NULL, dm,
- DM_IN_BUFFER);
+ wchar_t* mutable_name = const_cast<wchar_t*>(printer_name.c_str());
+ LONG buffer_size = DocumentProperties(NULL, printer, mutable_name, NULL,
+ dm, DM_IN_BUFFER);
if (buffer_size <= 0)
return scoped_ptr<DEVMODE[]>();
-
scoped_dev_mode.reset(reinterpret_cast<DEVMODE*>(new uint8[buffer_size]));
- if (DocumentProperties(NULL, printer,
- const_cast<LPWSTR>(printer_name.c_str()),
- scoped_dev_mode.get(), dm,
- DM_OUT_BUFFER | DM_IN_BUFFER) != IDOK) {
+ if (DocumentProperties(NULL, printer, mutable_name, scoped_dev_mode.get(),
+ dm, DM_OUT_BUFFER | DM_IN_BUFFER) != IDOK) {
scoped_dev_mode.reset();
}
printing::XPSModule::ReleaseMemory(dm);
@@ -338,9 +334,14 @@ class JobSpoolerWin : public PrintSystem::JobSpooler {
last_page_printed_ = -1;
// We only support PDF and XPS documents for now.
if (print_data_mime_type == kContentTypePDF) {
- DCHECK(print_ticket_mime_type == kContentTypeXML);
- scoped_ptr<DEVMODE[]> dev_mode =
- XpsTicketToDevMode(base::UTF8ToWide(printer_name), print_ticket);
+ scoped_ptr<DEVMODE[]> dev_mode;
+ if (print_ticket_mime_type == kContentTypeJSON) {
+ dev_mode = CjtToDevMode(base::UTF8ToWide(printer_name), print_ticket);
+ } else {
+ DCHECK(print_ticket_mime_type == kContentTypeXML);
+ dev_mode = XpsTicketToDevMode(base::UTF8ToWide(printer_name),
+ print_ticket);
+ }
if (!dev_mode) {
NOTREACHED();
@@ -368,6 +369,7 @@ class JobSpoolerWin : public PrintSystem::JobSpooler {
delegate_ = delegate;
RenderNextPDFPages();
} else if (print_data_mime_type == kContentTypeXPS) {
+ DCHECK(print_ticket_mime_type == kContentTypeXML);
bool ret = PrintXPSDocument(printer_name,
job_title,
print_data_file_path,
@@ -627,7 +629,7 @@ class PrinterCapsHandler : public ServiceUtilityProcessHost::Client {
const printing::PrinterSemanticCapsAndDefaults& semantic_info) OVERRIDE {
printing::PrinterCapsAndDefaults printer_info;
if (succeeded) {
- printer_info.caps_mime_type = kContentTypeCDD;
+ printer_info.caps_mime_type = kContentTypeJSON;
printer_info.printer_capabilities = CapabilitiesToCdd(semantic_info);
}
callback_.Run(succeeded, printer_name, printer_info);
@@ -711,6 +713,7 @@ class PrintSystemWin : public PrintSystem {
virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher(
const std::string& printer_name) OVERRIDE;
virtual PrintSystem::JobSpooler* CreateJobSpooler() OVERRIDE;
+ virtual bool UseCddAndCjt() OVERRIDE;
virtual std::string GetSupportedMimeTypes() OVERRIDE;
private:
@@ -718,22 +721,16 @@ class PrintSystemWin : public PrintSystem {
const std::string& printer_name) const;
scoped_refptr<printing::PrintBackend> print_backend_;
- bool use_xps_;
+ bool use_cdd_;
DISALLOW_COPY_AND_ASSIGN(PrintSystemWin);
};
-PrintSystemWin::PrintSystemWin() : use_xps_(false) {
+PrintSystemWin::PrintSystemWin() : use_cdd_(false) {
print_backend_ = printing::PrintBackend::CreateInstance(NULL);
}
PrintSystem::PrintSystemResult PrintSystemWin::Init() {
- use_xps_ = printing::XPSModule::Init();
- if (!use_xps_) {
- std::string message = l10n_util::GetStringFUTF8(
- IDS_CLOUD_PRINT_XPS_UNAVAILABLE,
- l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT));
- return PrintSystemResult(false, message);
- }
+ use_cdd_ = !printing::XPSModule::Init();
return PrintSystemResult(true, std::string());
}
@@ -752,7 +749,10 @@ void PrintSystemWin::GetPrinterCapsAndDefaults(
PrinterCapsHandler* handler =
new PrinterCapsHandler(printer_name, callback);
handler->AddRef();
- handler->StartGetPrinterCapsAndDefaults();
+ if (use_cdd_)
+ handler->StartGetPrinterSemanticCapsAndDefaults();
+ else
+ handler->StartGetPrinterCapsAndDefaults();
}
bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) {
@@ -764,6 +764,11 @@ bool PrintSystemWin::ValidatePrintTicket(
const std::string& print_ticket_data,
const std::string& print_ticket_data_mime_type) {
crash_keys::ScopedPrinterInfo crash_key(GetPrinterDriverInfo(printer_name));
+
+ if (use_cdd_) {
+ return print_ticket_data_mime_type == kContentTypeJSON &&
+ IsValidCjt(print_ticket_data);
+ }
DCHECK(print_ticket_data_mime_type == kContentTypeXML);
printing::ScopedXPSInitializer xps_initializer;
@@ -862,9 +867,13 @@ PrintSystem::JobSpooler* PrintSystemWin::CreateJobSpooler() {
return new JobSpoolerWin();
}
+bool PrintSystemWin::UseCddAndCjt() {
+ return use_cdd_;
+}
+
std::string PrintSystemWin::GetSupportedMimeTypes() {
std::string result;
- if (use_xps_) {
+ if (!use_cdd_) {
result = kContentTypeXPS;
result += ",";
}
diff --git a/chrome/service/cloud_print/printer_job_handler.cc b/chrome/service/cloud_print/printer_job_handler.cc
index 0e8a3f8..bb13def 100644
--- a/chrome/service/cloud_print/printer_job_handler.cc
+++ b/chrome/service/cloud_print/printer_job_handler.cc
@@ -316,9 +316,18 @@ PrinterJobHandler::HandleJobMetadataResponse(
JOB_HANDLER_JOB_STARTED, JOB_HANDLER_MAX);
SetNextDataHandler(&PrinterJobHandler::HandlePrintTicketResponse);
request_ = CloudPrintURLFetcher::Create();
- request_->StartGetRequest(CloudPrintURLFetcher::REQUEST_TICKET,
- GURL(job_details_.print_ticket_url_), this, kJobDataMaxRetryCount,
- std::string());
+ if (print_system_->UseCddAndCjt()) {
+ request_->StartGetRequest(
+ CloudPrintURLFetcher::REQUEST_TICKET,
+ GetUrlForJobCjt(cloud_print_server_url_, job_details_.job_id_,
+ job_fetch_reason_),
+ this, kJobDataMaxRetryCount, std::string());
+ } else {
+ request_->StartGetRequest(
+ CloudPrintURLFetcher::REQUEST_TICKET,
+ GURL(job_details_.print_ticket_url_), this, kJobDataMaxRetryCount,
+ std::string());
+ }
} else {
job_available = false;
base::MessageLoop::current()->PostDelayedTask(
@@ -683,7 +692,8 @@ void PrinterJobHandler::OnReceivePrinterCaps(
// Hashes don't match, we need to upload new capabilities (the defaults
// go for free along with the capabilities)
printer_info_cloud_.caps_hash = caps_hash;
- if (caps_and_defaults.caps_mime_type == kContentTypeCDD) {
+ if (caps_and_defaults.caps_mime_type == kContentTypeJSON) {
+ DCHECK(print_system_->UseCddAndCjt());
net::AddMultipartValueForUpload(kUseCDD, "true", mime_boundary,
std::string(), &post_data);
}
diff --git a/chrome/service/cloud_print/printer_job_handler_unittest.cc b/chrome/service/cloud_print/printer_job_handler_unittest.cc
index ddaa1fe..38b67e7 100644
--- a/chrome/service/cloud_print/printer_job_handler_unittest.cc
+++ b/chrome/service/cloud_print/printer_job_handler_unittest.cc
@@ -421,6 +421,7 @@ class MockPrintSystem : public PrintSystem {
PrintSystem::PrinterWatcher*(const std::string& printer_name));
MOCK_METHOD0(CreateJobSpooler, PrintSystem::JobSpooler*());
+ MOCK_METHOD0(UseCddAndCjt, bool());
MOCK_METHOD0(GetSupportedMimeTypes, std::string());
friend class scoped_refptr<NiceMock<MockPrintSystem> >;