forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement a new backend for modern CUPS implementations
As of CUPS 1.6, CUPS has moved away from PPD attributes to IPP attributes. This new backend uses the IPP APIs and will be better suited to use with CUPS going forward. Until we can bump our minumum CUPS version to 1.7, the only client will be Chrome OS where the version is 2.1.3. BUG=607668 TEST=With --enable-native-cups enabled, print dialog will show available CUPS printers if any are configured. Review-Url: https://codereview.chromium.org/2105463002 Cr-Commit-Position: refs/heads/master@{#407011}
- Loading branch information
skau
authored and
Commit bot
committed
Jul 22, 2016
1 parent
dd157e1
commit b779ce6
Showing
14 changed files
with
1,431 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// Copyright 2016 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "printing/backend/cups_connection.h" | ||
|
||
#include <string> | ||
#include <utility> | ||
|
||
#include "base/logging.h" | ||
#include "base/memory/ptr_util.h" | ||
#include "base/strings/stringprintf.h" | ||
|
||
namespace printing { | ||
|
||
namespace { | ||
|
||
const int kTimeoutMs = 3000; | ||
|
||
class DestinationEnumerator { | ||
public: | ||
DestinationEnumerator() {} | ||
|
||
static int cups_callback(void* user_data, unsigned flags, cups_dest_t* dest) { | ||
cups_dest_t* copied_dest; | ||
cupsCopyDest(dest, 0, &copied_dest); | ||
reinterpret_cast<DestinationEnumerator*>(user_data)->store_dest( | ||
copied_dest); | ||
|
||
// keep going | ||
return 1; | ||
} | ||
|
||
void store_dest(cups_dest_t* dest) { dests_.emplace_back(dest); } | ||
|
||
// Returns the collected destinations. | ||
std::vector<std::unique_ptr<cups_dest_t, DestinationDeleter>>& get_dests() { | ||
return dests_; | ||
} | ||
|
||
private: | ||
std::vector<std::unique_ptr<cups_dest_t, DestinationDeleter>> dests_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(DestinationEnumerator); | ||
}; | ||
|
||
} // namespace | ||
|
||
CupsConnection::CupsConnection(const GURL& print_server_url, | ||
http_encryption_t encryption, | ||
bool blocking) | ||
: print_server_url_(print_server_url), | ||
cups_encryption_(encryption), | ||
blocking_(blocking), | ||
cups_http_(nullptr) {} | ||
|
||
CupsConnection::CupsConnection(CupsConnection&& connection) | ||
: print_server_url_(connection.print_server_url_), | ||
cups_encryption_(connection.cups_encryption_), | ||
blocking_(connection.blocking_), | ||
cups_http_(std::move(connection.cups_http_)) {} | ||
|
||
CupsConnection::~CupsConnection() {} | ||
|
||
bool CupsConnection::Connect() { | ||
if (cups_http_) | ||
return true; // we're already connected | ||
|
||
std::string host; | ||
int port; | ||
|
||
if (!print_server_url_.is_empty()) { | ||
host = print_server_url_.host(); | ||
port = print_server_url_.IntPort(); | ||
} else { | ||
host = cupsServer(); | ||
port = ippPort(); | ||
} | ||
|
||
cups_http_.reset(httpConnect2(host.c_str(), port, nullptr, AF_UNSPEC, | ||
cups_encryption_, blocking_ ? 1 : 0, kTimeoutMs, | ||
nullptr)); | ||
return !!cups_http_; | ||
} | ||
|
||
std::vector<CupsPrinter> CupsConnection::GetDests() { | ||
if (!Connect()) { | ||
LOG(WARNING) << "CUPS connection failed"; | ||
return std::vector<CupsPrinter>(); | ||
} | ||
|
||
DestinationEnumerator enumerator; | ||
int success = | ||
cupsEnumDests(CUPS_DEST_FLAGS_NONE, kTimeoutMs, | ||
nullptr, // no cancel signal | ||
0, // all the printers | ||
CUPS_PRINTER_SCANNER, // except the scanners | ||
&DestinationEnumerator::cups_callback, &enumerator); | ||
|
||
if (!success) { | ||
LOG(WARNING) << "Enumerating printers failed"; | ||
return std::vector<CupsPrinter>(); | ||
} | ||
|
||
auto dests = std::move(enumerator.get_dests()); | ||
std::vector<CupsPrinter> printers; | ||
for (auto& dest : dests) { | ||
printers.emplace_back(cups_http_.get(), std::move(dest), nullptr); | ||
} | ||
|
||
return printers; | ||
} | ||
|
||
std::unique_ptr<CupsPrinter> CupsConnection::GetPrinter( | ||
const std::string& name) { | ||
if (!Connect()) | ||
return nullptr; | ||
|
||
cups_dest_t* dest = cupsGetNamedDest(cups_http_.get(), name.c_str(), nullptr); | ||
if (!dest) | ||
return nullptr; | ||
|
||
cups_dinfo_t* info = cupsCopyDestInfo(cups_http_.get(), dest); | ||
return base::MakeUnique<CupsPrinter>( | ||
cups_http_.get(), std::unique_ptr<cups_dest_t, DestinationDeleter>(dest), | ||
std::unique_ptr<cups_dinfo_t, DestInfoDeleter>(info)); | ||
} | ||
|
||
std::string CupsConnection::server_name() const { | ||
return print_server_url_.host(); | ||
} | ||
|
||
int CupsConnection::last_error() const { | ||
return cupsLastError(); | ||
} | ||
|
||
} // namespace printing |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Copyright 2016 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef PRINTING_BACKEND_CUPS_CONNECTION_H_ | ||
#define PRINTING_BACKEND_CUPS_CONNECTION_H_ | ||
|
||
#include <cups/cups.h> | ||
|
||
#include <memory> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include "base/macros.h" | ||
#include "base/memory/weak_ptr.h" | ||
#include "printing/backend/cups_deleters.h" | ||
#include "printing/backend/cups_printer.h" | ||
#include "printing/printing_export.h" | ||
#include "url/gurl.h" | ||
|
||
namespace printing { | ||
|
||
// Represents a connection to a CUPS server. | ||
class PRINTING_EXPORT CupsConnection { | ||
public: | ||
CupsConnection(const GURL& print_server_url, | ||
http_encryption_t encryption, | ||
bool blocking); | ||
|
||
CupsConnection(CupsConnection&& connection); | ||
|
||
~CupsConnection(); | ||
|
||
// Returns a vector of all the printers configure on the CUPS server. | ||
std::vector<CupsPrinter> GetDests(); | ||
|
||
// Returns a printer for |printer_name| from the connected server. | ||
std::unique_ptr<CupsPrinter> GetPrinter(const std::string& printer_name); | ||
|
||
std::string server_name() const; | ||
|
||
int last_error() const; | ||
|
||
private: | ||
// lazily initialize http connection | ||
bool Connect(); | ||
|
||
GURL print_server_url_; | ||
http_encryption_t cups_encryption_; | ||
bool blocking_; | ||
|
||
std::unique_ptr<http_t, HttpDeleter> cups_http_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(CupsConnection); | ||
}; | ||
|
||
} // namespace printing | ||
|
||
#endif // PRINTING_BACKEND_CUPS_CONNECTION_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright 2016 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "printing/backend/cups_deleters.h" | ||
|
||
namespace printing { | ||
|
||
void HttpDeleter::operator()(http_t* http) const { | ||
httpClose(http); | ||
} | ||
|
||
void DestinationDeleter::operator()(cups_dest_t* dest) const { | ||
cupsFreeDests(1, dest); | ||
} | ||
|
||
void DestInfoDeleter::operator()(cups_dinfo_t* info) const { | ||
cupsFreeDestInfo(info); | ||
} | ||
|
||
} // namespace printing |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright 2016 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef PRINTING_BACKEND_CUPS_DELETERS_H_ | ||
#define PRINTING_BACKEND_CUPS_DELETERS_H_ | ||
|
||
#include <cups/cups.h> | ||
|
||
namespace printing { | ||
|
||
struct HttpDeleter { | ||
public: | ||
void operator()(http_t* http) const; | ||
}; | ||
|
||
struct DestinationDeleter { | ||
public: | ||
void operator()(cups_dest_t* dest) const; | ||
}; | ||
|
||
struct DestInfoDeleter { | ||
public: | ||
void operator()(cups_dinfo_t* info) const; | ||
}; | ||
|
||
} // namespace printing | ||
|
||
#endif // PRINTING_BACKEND_CUPS_DELETERS_H_ |
Oops, something went wrong.