Commit 16c5c869 authored by David Valleau's avatar David Valleau Committed by Commit Bot

Adding detections for ipp-over-usb printers

This change checks the interfaces on a detected USB printer to see if any of
them support ipp-over-usb. A new flag has been added to the Printer class to
indicate whether or not it does.

Once the printer has been detected, in the event that we don't have a PPD for it
and it supports ipp-over-usb then we set it up as an ipp everywhere printer.

R=justincarlson@chromium.org, skau@chromium.org

Bug: 768606
Change-Id: I38214e0ce4f8ecee262ae94ac548cd79626f8a82
Reviewed-on: https://chromium-review.googlesource.com/842691
Commit-Queue: David Valleau <valleau@chromium.org>
Reviewed-by: default avatarSean Kau <skau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551064}
parent 4689ad37
...@@ -423,9 +423,21 @@ class CupsPrintersManagerImpl : public CupsPrintersManager, ...@@ -423,9 +423,21 @@ class CupsPrintersManagerImpl : public CupsPrintersManager,
auto it = detected_printer_ppd_references_.find(detected.printer.id()); auto it = detected_printer_ppd_references_.find(detected.printer.id());
if (it != detected_printer_ppd_references_.end()) { if (it != detected_printer_ppd_references_.end()) {
if (it->second == nullptr) { if (it->second == nullptr) {
// If the detected printer supports ipp-over-usb and we could not find
// a ppd for it, then we switch to the ippusb scheme and mark it as
// autoconf.
auto printer = detected.printer;
if (printer.supports_ippusb()) {
printer.set_uri(
base::StringPrintf("ippusb://%04x_%04x/ipp/print",
detected.ppd_search_data.usb_vendor_id,
detected.ppd_search_data.usb_product_id));
printer.mutable_ppd_reference()->autoconf = true;
}
// We couldn't figure out this printer, so it's in the discovered // We couldn't figure out this printer, so it's in the discovered
// class. // class.
printers_[kDiscovered].push_back(detected.printer); printers_[kDiscovered].push_back(printer);
} else { } else {
// We have a ppd reference, so we think we can set this up // We have a ppd reference, so we think we can set this up
// automatically. // automatically.
......
...@@ -29,6 +29,14 @@ namespace { ...@@ -29,6 +29,14 @@ namespace {
// (https://www.usb.org/developers/defined_class). // (https://www.usb.org/developers/defined_class).
constexpr uint8_t kPrinterInterfaceClass = 7; constexpr uint8_t kPrinterInterfaceClass = 7;
// Subclass used for printers
// (http://www.usb.org/developers/docs/devclass_docs/usbprint11a021811.pdf).
constexpr uint8_t kPrinterInterfaceSubclass = 1;
// Protocol for ippusb printing.
// (http://www.usb.org/developers/docs/devclass_docs/IPP.zip).
constexpr uint8_t kPrinterIppusbProtocol = 4;
// Escape URI strings the same way cups does it, so we end up with a URI cups // Escape URI strings the same way cups does it, so we end up with a URI cups
// recognizes. Cups hex-encodes '%', ' ', and anything not in the standard // recognizes. Cups hex-encodes '%', ' ', and anything not in the standard
// ASCII range. CUPS lets everything else through unchanged. // ASCII range. CUPS lets everything else through unchanged.
...@@ -113,10 +121,27 @@ std::string UsbPrinterId(const device::UsbDevice& device) { ...@@ -113,10 +121,27 @@ std::string UsbPrinterId(const device::UsbDevice& device) {
} // namespace } // namespace
bool UsbDeviceIsPrinter(const device::UsbDevice& usb_device) { // Creates a mojom filter which can be used to identify a basic USB printer.
mojo::StructPtr<device::mojom::UsbDeviceFilter> CreatePrinterFilter() {
auto printer_filter = device::mojom::UsbDeviceFilter::New(); auto printer_filter = device::mojom::UsbDeviceFilter::New();
printer_filter->has_class_code = true; printer_filter->has_class_code = true;
printer_filter->class_code = kPrinterInterfaceClass; printer_filter->class_code = kPrinterInterfaceClass;
printer_filter->has_subclass_code = true;
printer_filter->subclass_code = kPrinterInterfaceSubclass;
return printer_filter;
}
bool UsbDeviceIsPrinter(const device::UsbDevice& usb_device) {
auto printer_filter = CreatePrinterFilter();
return UsbDeviceFilterMatches(*printer_filter, usb_device);
}
bool UsbDeviceSupportsIppusb(const device::UsbDevice& usb_device) {
auto printer_filter = CreatePrinterFilter();
printer_filter->has_protocol_code = true;
printer_filter->protocol_code = kPrinterIppusbProtocol;
return UsbDeviceFilterMatches(*printer_filter, usb_device); return UsbDeviceFilterMatches(*printer_filter, usb_device);
} }
...@@ -183,6 +208,7 @@ std::unique_ptr<Printer> UsbDeviceToPrinter(const device::UsbDevice& device) { ...@@ -183,6 +208,7 @@ std::unique_ptr<Printer> UsbDeviceToPrinter(const device::UsbDevice& device) {
printer->set_description(printer->display_name()); printer->set_description(printer->display_name());
printer->set_uri(UsbPrinterUri(device)); printer->set_uri(UsbPrinterUri(device));
printer->set_id(UsbPrinterId(device)); printer->set_id(UsbPrinterId(device));
printer->set_supports_ippusb(UsbDeviceSupportsIppusb(device));
return printer; return printer;
} }
......
...@@ -22,6 +22,8 @@ class Printer; ...@@ -22,6 +22,8 @@ class Printer;
bool UsbDeviceIsPrinter(const device::UsbDevice& usb_device); bool UsbDeviceIsPrinter(const device::UsbDevice& usb_device);
bool UsbDeviceSupportsIppusb(const device::UsbDevice& usb_device);
// Convert the interesting details of a device to a string, for // Convert the interesting details of a device to a string, for
// logging/debugging. // logging/debugging.
std::string UsbPrinterDeviceDetailsAsString(const device::UsbDevice& device); std::string UsbPrinterDeviceDetailsAsString(const device::UsbDevice& device);
......
...@@ -151,6 +151,9 @@ Printer::PrinterProtocol Printer::GetProtocol() const { ...@@ -151,6 +151,9 @@ Printer::PrinterProtocol Printer::GetProtocol() const {
if (uri.starts_with("lpd:")) if (uri.starts_with("lpd:"))
return PrinterProtocol::kLpd; return PrinterProtocol::kLpd;
if (uri.starts_with("ippusb:"))
return PrinterProtocol::kIppUsb;
return PrinterProtocol::kUnknown; return PrinterProtocol::kUnknown;
} }
......
...@@ -77,6 +77,7 @@ class CHROMEOS_EXPORT Printer { ...@@ -77,6 +77,7 @@ class CHROMEOS_EXPORT Printer {
kHttps = 5, kHttps = 5,
kSocket = 6, kSocket = 6,
kLpd = 7, kLpd = 7,
kIppUsb = 8,
kProtocolMax kProtocolMax
}; };
...@@ -133,6 +134,11 @@ class CHROMEOS_EXPORT Printer { ...@@ -133,6 +134,11 @@ class CHROMEOS_EXPORT Printer {
const PpdReference& ppd_reference() const { return ppd_reference_; } const PpdReference& ppd_reference() const { return ppd_reference_; }
PpdReference* mutable_ppd_reference() { return &ppd_reference_; } PpdReference* mutable_ppd_reference() { return &ppd_reference_; }
bool supports_ippusb() const { return supports_ippusb_; }
void set_supports_ippusb(bool supports_ippusb) {
supports_ippusb_ = supports_ippusb;
}
const std::string& uuid() const { return uuid_; } const std::string& uuid() const { return uuid_; }
void set_uuid(const std::string& uuid) { uuid_ = uuid; } void set_uuid(const std::string& uuid) { uuid_ = uuid; }
...@@ -206,6 +212,9 @@ class CHROMEOS_EXPORT Printer { ...@@ -206,6 +212,9 @@ class CHROMEOS_EXPORT Printer {
// How to find the associated postscript printer description. // How to find the associated postscript printer description.
PpdReference ppd_reference_; PpdReference ppd_reference_;
// Represents whether or not the printer supports printing using ipp-over-usb.
bool supports_ippusb_ = false;
// The UUID from an autoconf protocol for deduplication. Could be empty. // The UUID from an autoconf protocol for deduplication. Could be empty.
std::string uuid_; std::string uuid_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment