diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-05-20 09:47:09 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-06-07 11:15:42 +0000 |
commit | 189d4fd8fad9e3c776873be51938cd31a42b6177 (patch) | |
tree | 6497caeff5e383937996768766ab3bb2081a40b2 /chromium/printing | |
parent | 8bc75099d364490b22f43a7ce366b366c08f4164 (diff) | |
download | qtwebengine-chromium-189d4fd8fad9e3c776873be51938cd31a42b6177.tar.gz |
BASELINE: Update Chromium to 90.0.4430.221
Change-Id: Iff4d9d18d2fcf1a576f3b1f453010f744a232920
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/printing')
52 files changed, 1276 insertions, 607 deletions
diff --git a/chromium/printing/BUILD.gn b/chromium/printing/BUILD.gn index 3e70dc1d46a..31e651d8e3f 100644 --- a/chromium/printing/BUILD.gn +++ b/chromium/printing/BUILD.gn @@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//build/config/features.gni") import("//build/config/sysroot.gni") import("//build/config/ui.gni") @@ -14,7 +15,7 @@ if (is_mac) { if (is_android) { import("//build/config/android/rules.gni") } -if (use_cups && is_chromeos) { +if (use_cups && is_chromeos_ash) { import("//printing/backend/tools/code_generator.gni") } @@ -28,7 +29,7 @@ if ((enable_basic_printing && is_win) || enable_print_preview) { # Enable the CUPS IPP printing backend. # TODO(crbug.com/226176): Remove this after CUPS PPD API calls are removed. declare_args() { - use_cups_ipp = use_cups && !is_linux + use_cups_ipp = use_cups && !(is_linux || is_chromeos_lacros) } # Several targets want to include this header file. We separate it out @@ -37,7 +38,7 @@ source_set("printing_export") { sources = [ "printing_export.h" ] } -if (use_cups_ipp && is_chromeos) { +if (use_cups_ipp && is_chromeos_ash) { ipp_handler_map_path = "$target_gen_dir/backend/ipp_handler_map.cc" ipp_code_generate("ipp_handlers_generate") { @@ -125,7 +126,7 @@ component("printing") { ] } - if (is_chromeos) { + if (is_chromeos_ash) { defines += [ "PRINT_BACKEND_AVAILABLE" ] sources += [ @@ -136,7 +137,7 @@ component("printing") { ] } - if (is_linux) { + if (is_linux || is_chromeos_lacros) { sources += [ "printed_document_linux.cc", "printing_context_linux.cc", @@ -239,7 +240,7 @@ component("printing") { ] } - if (is_chromeos) { + if (is_chromeos_ash) { deps += [ ":ipp_handlers_generate" ] sources += [ @@ -272,7 +273,7 @@ component("printing") { } } - if (use_cups_ipp || is_chromeos) { + if (use_cups_ipp || is_chromeos_ash) { sources += [ "printer_query_result.h", "printer_status.cc", @@ -322,6 +323,7 @@ static_library("test_support") { test("printing_unittests") { sources = [ "backend/mojom/print_backend_mojom_traits_unittest.cc", + "backend/test_print_backend_unittest.cc", "metafile_skia_unittest.cc", "nup_parameters_unittest.cc", "page_number_unittest.cc", @@ -337,6 +339,7 @@ test("printing_unittests") { configs += [ "//build/config/compiler:noshadowing" ] deps = [ ":printing", + ":test_support", "//base/test:test_support", "//build:chromeos_buildflags", "//mojo/core/test:run_all_unittests", @@ -379,7 +382,7 @@ test("printing_unittests") { sources += [ "backend/cups_ipp_helper_unittest.cc" ] } - if (is_chromeos) { + if (is_chromeos_ash) { sources += [ "printing_context_chromeos_unittest.cc" ] } else { sources += [ @@ -423,7 +426,7 @@ if (is_android) { deps = [ "//base:base_java", "//base:jni_java", - "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_annotation_annotation_java", "//ui/android:ui_java", ] sources = [ diff --git a/chromium/printing/OWNERS b/chromium/printing/OWNERS index eb3f8066888..6d26dfe6200 100644 --- a/chromium/printing/OWNERS +++ b/chromium/printing/OWNERS @@ -1,3 +1,4 @@ +set noparent rbpotter@chromium.org thestig@chromium.org weili@chromium.org diff --git a/chromium/printing/backend/cups_connection.cc b/chromium/printing/backend/cups_connection.cc index 8a8bc0a2b70..cced585d68a 100644 --- a/chromium/printing/backend/cups_connection.cc +++ b/chromium/printing/backend/cups_connection.cc @@ -63,142 +63,157 @@ QueueStatus::QueueStatus(const QueueStatus& other) = default; QueueStatus::~QueueStatus() = default; -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_; -} +class CupsConnectionImpl : public CupsConnection { + public: + CupsConnectionImpl(const GURL& print_server_url, + http_encryption_t encryption, + bool blocking) + : print_server_url_(print_server_url), + cups_encryption_(encryption), + blocking_(false), + cups_http_(nullptr) {} + + CupsConnectionImpl(CupsConnectionImpl&& connection) + : print_server_url_(connection.print_server_url_), + cups_encryption_(connection.cups_encryption_), + blocking_(connection.blocking_), + cups_http_(std::move(connection.cups_http_)) {} + + ~CupsConnectionImpl() override {} + + std::vector<std::unique_ptr<CupsPrinter>> GetDests() override { + if (!Connect()) { + LOG(WARNING) << "CUPS connection failed"; + return std::vector<std::unique_ptr<CupsPrinter>>(); + } -std::vector<CupsPrinter> CupsConnection::GetDests() { - if (!Connect()) { - LOG(WARNING) << "CUPS connection failed"; - return std::vector<CupsPrinter>(); - } + // On macOS, AirPrint destinations show up even if they're not added to the + // system, and their capabilities cannot be read in that situation + // (crbug.com/1027834). Therefore, only show discovered destinations that + // have been added locally. Also exclude fax and scanner devices. + constexpr cups_ptype_t kMask = + CUPS_PRINTER_FAX | CUPS_PRINTER_SCANNER | CUPS_PRINTER_DISCOVERED; + DestinationEnumerator enumerator; + const int success = + cupsEnumDests(CUPS_DEST_FLAGS_NONE, kTimeoutMs, + /*cancel=*/nullptr, + /*type=*/CUPS_PRINTER_LOCAL, kMask, + &DestinationEnumerator::cups_callback, &enumerator); + + if (!success) { + LOG(WARNING) << "Enumerating printers failed"; + return std::vector<std::unique_ptr<CupsPrinter>>(); + } - // On macOS, AirPrint destinations show up even if they're not added to the - // system, and their capabilities cannot be read in that situation - // (crbug.com/1027834). Therefore, only show discovered destinations that have - // been added locally. Also exclude fax and scanner devices. - constexpr cups_ptype_t kMask = - CUPS_PRINTER_FAX | CUPS_PRINTER_SCANNER | CUPS_PRINTER_DISCOVERED; - DestinationEnumerator enumerator; - const int success = - cupsEnumDests(CUPS_DEST_FLAGS_NONE, kTimeoutMs, - /*cancel=*/nullptr, - /*type=*/CUPS_PRINTER_LOCAL, kMask, - &DestinationEnumerator::cups_callback, &enumerator); - - if (!success) { - LOG(WARNING) << "Enumerating printers failed"; - return std::vector<CupsPrinter>(); - } + auto dests = std::move(enumerator.get_dests()); + std::vector<std::unique_ptr<CupsPrinter>> printers; + for (auto& dest : dests) { + printers.push_back( + CupsPrinter::Create(cups_http_.get(), std::move(dest))); + } - auto dests = std::move(enumerator.get_dests()); - std::vector<CupsPrinter> printers; - for (auto& dest : dests) { - printers.emplace_back(cups_http_.get(), std::move(dest)); + return printers; } - return printers; -} - -std::unique_ptr<CupsPrinter> CupsConnection::GetPrinter( - const std::string& name) { - if (!Connect()) - return nullptr; + std::unique_ptr<CupsPrinter> GetPrinter(const std::string& name) override { + if (!Connect()) + return nullptr; - cups_dest_t* dest = cupsGetNamedDest(cups_http_.get(), name.c_str(), nullptr); - if (!dest) - return nullptr; + cups_dest_t* dest = + cupsGetNamedDest(cups_http_.get(), name.c_str(), nullptr); + if (!dest) + return nullptr; - return std::make_unique<CupsPrinter>(cups_http_.get(), - ScopedDestination(dest)); -} - -bool CupsConnection::GetJobs(const std::vector<std::string>& printer_ids, - std::vector<QueueStatus>* queues) { - DCHECK(queues); - if (!Connect()) { - LOG(ERROR) << "Could not establish connection to CUPS"; - return false; + return CupsPrinter::Create(cups_http_.get(), ScopedDestination(dest)); } - std::vector<QueueStatus> temp_queues; - - for (const std::string& id : printer_ids) { - temp_queues.emplace_back(); - QueueStatus* queue_status = &temp_queues.back(); - - if (!printing::GetPrinterStatus(cups_http_.get(), id, - &queue_status->printer_status)) { - LOG(WARNING) << "Could not retrieve printer status for " << id; + bool GetJobs(const std::vector<std::string>& printer_ids, + std::vector<QueueStatus>* queues) override { + DCHECK(queues); + if (!Connect()) { + LOG(ERROR) << "Could not establish connection to CUPS"; return false; } - if (!GetCupsJobs(cups_http_.get(), id, kCompletedJobsLimit, COMPLETED, - &queue_status->jobs)) { - LOG(WARNING) << "Could not get completed jobs for " << id; - return false; + std::vector<QueueStatus> temp_queues; + + for (const std::string& id : printer_ids) { + temp_queues.emplace_back(); + QueueStatus* queue_status = &temp_queues.back(); + + if (!printing::GetPrinterStatus(cups_http_.get(), id, + &queue_status->printer_status)) { + LOG(WARNING) << "Could not retrieve printer status for " << id; + return false; + } + + if (!GetCupsJobs(cups_http_.get(), id, kCompletedJobsLimit, COMPLETED, + &queue_status->jobs)) { + LOG(WARNING) << "Could not get completed jobs for " << id; + return false; + } + + if (!GetCupsJobs(cups_http_.get(), id, kProcessingJobsLimit, PROCESSING, + &queue_status->jobs)) { + LOG(WARNING) << "Could not get in progress jobs for " << id; + return false; + } } + queues->insert(queues->end(), temp_queues.begin(), temp_queues.end()); + + return true; + } - if (!GetCupsJobs(cups_http_.get(), id, kProcessingJobsLimit, PROCESSING, - &queue_status->jobs)) { - LOG(WARNING) << "Could not get in progress jobs for " << id; + bool GetPrinterStatus(const std::string& printer_id, + PrinterStatus* printer_status) override { + if (!Connect()) { + LOG(ERROR) << "Could not establish connection to CUPS"; return false; } + return printing::GetPrinterStatus(cups_http_.get(), printer_id, + printer_status); } - queues->insert(queues->end(), temp_queues.begin(), temp_queues.end()); - return true; -} + std::string server_name() const override { return print_server_url_.host(); } + + int last_error() const override { return cupsLastError(); } -bool CupsConnection::GetPrinterStatus(const std::string& printer_id, - PrinterStatus* printer_status) { - if (!Connect()) { - LOG(ERROR) << "Could not establish connection to CUPS"; - return false; + private: + // lazily initialize http connection + bool 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_; } - return printing::GetPrinterStatus(cups_http_.get(), printer_id, - printer_status); -} -std::string CupsConnection::server_name() const { - return print_server_url_.host(); -} + GURL print_server_url_; + http_encryption_t cups_encryption_; + bool blocking_; + + ScopedHttpPtr cups_http_; +}; -int CupsConnection::last_error() const { - return cupsLastError(); +std::unique_ptr<CupsConnection> CupsConnection::Create( + const GURL& print_server_url, + http_encryption_t encryption, + bool blocking) { + return std::make_unique<CupsConnectionImpl>(print_server_url, encryption, + blocking); } } // namespace printing diff --git a/chromium/printing/backend/cups_connection.h b/chromium/printing/backend/cups_connection.h index b83e230d380..14f8fb96891 100644 --- a/chromium/printing/backend/cups_connection.h +++ b/chromium/printing/backend/cups_connection.h @@ -34,45 +34,34 @@ struct PRINTING_EXPORT QueueStatus { // 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(const CupsConnection&) = delete; - CupsConnection& operator=(const CupsConnection&) = delete; - ~CupsConnection(); + virtual ~CupsConnection() = default; + + static std::unique_ptr<CupsConnection> Create(const GURL& print_server_url, + http_encryption_t encryption, + bool blocking); // Returns a vector of all the printers configure on the CUPS server. - std::vector<CupsPrinter> GetDests(); + virtual std::vector<std::unique_ptr<CupsPrinter>> GetDests() = 0; // Returns a printer for |printer_name| from the connected server. - std::unique_ptr<CupsPrinter> GetPrinter(const std::string& printer_name); + virtual std::unique_ptr<CupsPrinter> GetPrinter( + const std::string& printer_name) = 0; // Queries CUPS for printer queue status for |printer_ids|. Populates |jobs| // with said information with one QueueStatus per printer_id. Returns true if // all the queries were successful. In the event of failure, |jobs| will be // unchanged. - bool GetJobs(const std::vector<std::string>& printer_ids, - std::vector<QueueStatus>* jobs); + virtual bool GetJobs(const std::vector<std::string>& printer_ids, + std::vector<QueueStatus>* jobs) = 0; // Queries CUPS for printer status for |printer_id|. // Returns true if the query was successful. - bool GetPrinterStatus(const std::string& printer_id, - PrinterStatus* printer_status); - - std::string server_name() const; - - int last_error() const; - - private: - // lazily initialize http connection - bool Connect(); + virtual bool GetPrinterStatus(const std::string& printer_id, + PrinterStatus* printer_status) = 0; - GURL print_server_url_; - http_encryption_t cups_encryption_; - bool blocking_; + virtual std::string server_name() const = 0; - ScopedHttpPtr cups_http_; + virtual int last_error() const = 0; }; } // namespace printing diff --git a/chromium/printing/backend/cups_helper.cc b/chromium/printing/backend/cups_helper.cc index 09ebdbd3dae..62adb78ce2f 100644 --- a/chromium/printing/backend/cups_helper.cc +++ b/chromium/printing/backend/cups_helper.cc @@ -586,6 +586,7 @@ bool ParsePpdCapabilities(cups_dest_t* dest, << line << ", " << ppdErrorString(ppd_status); return false; } + ppdMarkDefaults(ppd); if (dest) cupsMarkOptions(ppd, dest->num_options, dest->options); diff --git a/chromium/printing/backend/cups_ipp_constants.cc b/chromium/printing/backend/cups_ipp_constants.cc index 5981f8d6f1d..1473d483a63 100644 --- a/chromium/printing/backend/cups_ipp_constants.cc +++ b/chromium/printing/backend/cups_ipp_constants.cc @@ -24,7 +24,7 @@ constexpr char kIppPinEncryption[] = "job-password-encryption"; // PWG 5100.11 constexpr char kCollated[] = "separate-documents-collated-copies"; constexpr char kUncollated[] = "separate-documents-uncollated-copies"; -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) constexpr char kIppDocumentAttributes[] = "document-creation-attributes"; // PWG 5100.5 @@ -35,6 +35,6 @@ constexpr char kPinEncryptionNone[] = "none"; constexpr char kOptionFalse[] = "false"; constexpr char kOptionTrue[] = "true"; -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } // namespace printing diff --git a/chromium/printing/backend/cups_ipp_constants.h b/chromium/printing/backend/cups_ipp_constants.h index 83fa9a25f92..38d1c46a8c8 100644 --- a/chromium/printing/backend/cups_ipp_constants.h +++ b/chromium/printing/backend/cups_ipp_constants.h @@ -25,7 +25,7 @@ PRINTING_EXPORT extern const char kIppPinEncryption[]; PRINTING_EXPORT extern const char kCollated[]; PRINTING_EXPORT extern const char kUncollated[]; -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) PRINTING_EXPORT extern const char kIppDocumentAttributes[]; PRINTING_EXPORT extern const char kIppJobAttributes[]; @@ -35,7 +35,7 @@ PRINTING_EXPORT extern const char kPinEncryptionNone[]; PRINTING_EXPORT extern const char kOptionFalse[]; PRINTING_EXPORT extern const char kOptionTrue[]; -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } // namespace printing diff --git a/chromium/printing/backend/cups_ipp_helper.cc b/chromium/printing/backend/cups_ipp_helper.cc index 4e86ba71cd6..6e66d620902 100644 --- a/chromium/printing/backend/cups_ipp_helper.cc +++ b/chromium/printing/backend/cups_ipp_helper.cc @@ -24,19 +24,19 @@ #include "printing/printing_utils.h" #include "printing/units.h" -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) #include "base/callback.h" #include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" #include "printing/backend/ipp_handler_map.h" #include "printing/printing_features.h" -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) namespace printing { -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) constexpr int kPinMinimumLength = 4; -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) namespace { @@ -256,7 +256,7 @@ bool CollateDefault(const CupsOptionProvider& printer) { return name && !base::StringPiece(name).compare(kCollated); } -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) bool PinSupported(const CupsOptionProvider& printer) { ipp_attribute_t* attr = printer.GetSupportedOptionValues(kIppPin); if (!attr) @@ -311,7 +311,7 @@ void ExtractAdvancedCapabilities(const CupsOptionProvider& printer, attr_count += AddAttributes(printer, kIppDocumentAttributes, options); base::UmaHistogramCounts1000("Printing.CUPS.IppAttributesCount", attr_count); } -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } // namespace @@ -334,11 +334,10 @@ void CapsAndDefaultsFromPrinter(const CupsOptionProvider& printer, printer_info->default_paper = DefaultPaper(printer); printer_info->papers = SupportedPapers(printer); -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) printer_info->pin_supported = PinSupported(printer); - if (base::FeatureList::IsEnabled(printing::features::kAdvancedPpdAttributes)) - ExtractAdvancedCapabilities(printer, printer_info); -#endif // BUILDFLAG(IS_ASH) + ExtractAdvancedCapabilities(printer, printer_info); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) ExtractCopies(printer, printer_info); ExtractColor(printer, printer_info); diff --git a/chromium/printing/backend/cups_ipp_helper_unittest.cc b/chromium/printing/backend/cups_ipp_helper_unittest.cc index 0713dc5e92d..3a1fb8b9068 100644 --- a/chromium/printing/backend/cups_ipp_helper_unittest.cc +++ b/chromium/printing/backend/cups_ipp_helper_unittest.cc @@ -11,12 +11,9 @@ #include "base/notreached.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "printing/backend/cups_printer.h" #include "printing/mojom/print.mojom.h" -#include "printing/printing_features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -198,7 +195,7 @@ TEST_F(PrintBackendCupsIppHelperTest, A4PaperSupported) { PrinterSemanticCapsAndDefaults::Paper paper = caps.papers[0]; // media display name localization is handled more fully in - // GetPrinterCapabilitiesOnBlockingTaskRunner(). + // AssemblePrinterSettings(). EXPECT_EQ("iso a4", paper.display_name); EXPECT_EQ("iso_a4_210x297mm", paper.vendor_id); EXPECT_EQ(210000, paper.size_um.width()); @@ -211,7 +208,7 @@ TEST_F(PrintBackendCupsIppHelperTest, LegalPaperDefault) { PrinterSemanticCapsAndDefaults caps; CapsAndDefaultsFromPrinter(*printer_, &caps); // media display name localization is handled more fully in - // GetPrinterCapabilitiesOnBlockingTaskRunner(). + // AssemblePrinterSettings(). EXPECT_EQ("na legal", caps.default_paper.display_name); EXPECT_EQ("na_legal_8.5x14in", caps.default_paper.vendor_id); EXPECT_EQ(215900, caps.default_paper.size_um.width()); @@ -285,7 +282,7 @@ TEST_F(PrintBackendCupsIppHelperTest, OmitPapersWithSpecialVendorIds) { "iso b0"))); } -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(PrintBackendCupsIppHelperTest, PinSupported) { printer_->SetSupportedOptions("job-password", MakeInteger(ipp_, 4)); printer_->SetSupportedOptions("job-password-encryption", @@ -327,8 +324,6 @@ TEST_F(PrintBackendCupsIppHelperTest, PinTooShort) { TEST_F(PrintBackendCupsIppHelperTest, AdvancedCaps) { base::HistogramTester histograms; - base::test::ScopedFeatureList features; - features.InitAndEnableFeature(printing::features::kAdvancedPpdAttributes); printer_->SetSupportedOptions( "job-creation-attributes", @@ -364,6 +359,6 @@ TEST_F(PrintBackendCupsIppHelperTest, AdvancedCaps) { EXPECT_EQ(3u, caps.advanced_capabilities[5].values.size()); histograms.ExpectUniqueSample("Printing.CUPS.IppAttributesCount", 5, 1); } -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } // namespace printing diff --git a/chromium/printing/backend/cups_ipp_utils.cc b/chromium/printing/backend/cups_ipp_utils.cc index f37e7e8afe5..1f8f325cfc9 100644 --- a/chromium/printing/backend/cups_ipp_utils.cc +++ b/chromium/printing/backend/cups_ipp_utils.cc @@ -40,9 +40,9 @@ std::unique_ptr<CupsConnection> CreateConnection( GURL print_server_url = GURL(print_server_url_str); bool cups_blocking = cups_blocking_str == kValueTrue; - return std::make_unique<CupsConnection>( - print_server_url, static_cast<http_encryption_t>(encryption), - cups_blocking); + return CupsConnection::Create(print_server_url, + static_cast<http_encryption_t>(encryption), + cups_blocking); } } // namespace printing diff --git a/chromium/printing/backend/cups_jobs.cc b/chromium/printing/backend/cups_jobs.cc index 492a7433382..06334a7e674 100644 --- a/chromium/printing/backend/cups_jobs.cc +++ b/chromium/printing/backend/cups_jobs.cc @@ -12,8 +12,8 @@ #include <memory> #include <string> +#include "base/containers/contains.h" #include "base/logging.h" -#include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/threading/scoped_blocking_call.h" diff --git a/chromium/printing/backend/cups_printer.cc b/chromium/printing/backend/cups_printer.cc index a52cd5b8f25..f0786578adb 100644 --- a/chromium/printing/backend/cups_printer.cc +++ b/chromium/printing/backend/cups_printer.cc @@ -17,221 +17,242 @@ namespace printing { -CupsPrinter::CupsPrinter(http_t* http, ScopedDestination dest) - : cups_http_(http), destination_(std::move(dest)) { - DCHECK(cups_http_); - DCHECK(destination_); -} +class CupsPrinterImpl : public CupsPrinter { + public: + CupsPrinterImpl(http_t* http, ScopedDestination dest) + : cups_http_(http), destination_(std::move(dest)) { + DCHECK(cups_http_); + DCHECK(destination_); + } -CupsPrinter::CupsPrinter(CupsPrinter&& printer) = default; + CupsPrinterImpl(const CupsPrinterImpl&) = delete; + CupsPrinterImpl& operator=(const CupsPrinterImpl&) = delete; -CupsPrinter::~CupsPrinter() = default; + ~CupsPrinterImpl() override = default; -bool CupsPrinter::is_default() const { - return destination_->is_default; -} + bool is_default() const override { return destination_->is_default; } -ipp_attribute_t* CupsPrinter::GetSupportedOptionValues( - const char* option_name) const { - if (!EnsureDestInfo()) - return nullptr; + // CupsOptionProvider + ipp_attribute_t* GetSupportedOptionValues( + const char* option_name) const override { + if (!EnsureDestInfo()) + return nullptr; - return cupsFindDestSupported(cups_http_, destination_.get(), dest_info_.get(), - option_name); -} - -std::vector<base::StringPiece> CupsPrinter::GetSupportedOptionValueStrings( - const char* option_name) const { - std::vector<base::StringPiece> values; - ipp_attribute_t* attr = GetSupportedOptionValues(option_name); - if (!attr) - return values; + return cupsFindDestSupported(cups_http_, destination_.get(), + dest_info_.get(), option_name); + } - int num_options = ippGetCount(attr); - for (int i = 0; i < num_options; ++i) { - const char* const value = ippGetString(attr, i, nullptr); - if (!value) { - continue; + // CupsOptionProvider + std::vector<base::StringPiece> GetSupportedOptionValueStrings( + const char* option_name) const override { + std::vector<base::StringPiece> values; + ipp_attribute_t* attr = GetSupportedOptionValues(option_name); + if (!attr) + return values; + + int num_options = ippGetCount(attr); + for (int i = 0; i < num_options; ++i) { + const char* const value = ippGetString(attr, i, nullptr); + if (!value) { + continue; + } + values.push_back(value); } - values.push_back(value); - } - return values; -} + return values; + } -ipp_attribute_t* CupsPrinter::GetDefaultOptionValue( - const char* option_name) const { - if (!EnsureDestInfo()) - return nullptr; + // CupsOptionProvider + ipp_attribute_t* GetDefaultOptionValue( + const char* option_name) const override { + if (!EnsureDestInfo()) + return nullptr; - return cupsFindDestDefault(cups_http_, destination_.get(), dest_info_.get(), - option_name); -} + return cupsFindDestDefault(cups_http_, destination_.get(), dest_info_.get(), + option_name); + } -bool CupsPrinter::CheckOptionSupported(const char* name, - const char* value) const { - if (!EnsureDestInfo()) - return false; + // CupsOptionProvider + bool CheckOptionSupported(const char* name, + const char* value) const override { + if (!EnsureDestInfo()) + return false; - int supported = cupsCheckDestSupported(cups_http_, destination_.get(), - dest_info_.get(), name, value); - return supported == 1; -} + int supported = cupsCheckDestSupported(cups_http_, destination_.get(), + dest_info_.get(), name, value); + return supported == 1; + } -bool CupsPrinter::ToPrinterInfo(PrinterBasicInfo* printer_info) const { - const cups_dest_t* printer = destination_.get(); + bool ToPrinterInfo(PrinterBasicInfo* printer_info) const override { + const cups_dest_t* printer = destination_.get(); - printer_info->printer_name = printer->name; - printer_info->is_default = printer->is_default; + printer_info->printer_name = printer->name; + printer_info->is_default = printer->is_default; - const std::string info = GetInfo(); - const std::string make_and_model = GetMakeAndModel(); + const std::string info = GetInfo(); + const std::string make_and_model = GetMakeAndModel(); #if defined(OS_MAC) - // On Mac, "printer-info" option specifies the human-readable printer name, - // while "printer-make-and-model" specifies the printer description. - printer_info->display_name = info; - printer_info->printer_description = make_and_model; + // On Mac, "printer-info" option specifies the human-readable printer name, + // while "printer-make-and-model" specifies the printer description. + printer_info->display_name = info; + printer_info->printer_description = make_and_model; #else - // On other platforms, "printer-info" specifies the printer description. - printer_info->display_name = printer->name; - printer_info->printer_description = info; + // On other platforms, "printer-info" specifies the printer description. + printer_info->display_name = printer->name; + printer_info->printer_description = info; #endif // defined(OS_MAC) - const char* state = cupsGetOption(kCUPSOptPrinterState, printer->num_options, - printer->options); - if (state) - base::StringToInt(state, &printer_info->printer_status); + const char* state = cupsGetOption(kCUPSOptPrinterState, + printer->num_options, printer->options); + if (state) + base::StringToInt(state, &printer_info->printer_status); - printer_info->options[kDriverInfoTagName] = make_and_model; + printer_info->options[kDriverInfoTagName] = make_and_model; - // Store printer options. - for (int opt_index = 0; opt_index < printer->num_options; ++opt_index) { - printer_info->options[printer->options[opt_index].name] = - printer->options[opt_index].value; - } + // Store printer options. + for (int opt_index = 0; opt_index < printer->num_options; ++opt_index) { + printer_info->options[printer->options[opt_index].name] = + printer->options[opt_index].value; + } - return true; -} + return true; + } -std::string CupsPrinter::GetName() const { - return std::string(destination_->name); -} + std::string GetName() const override { + return std::string(destination_->name); + } -std::string CupsPrinter::GetMakeAndModel() const { - const char* make_and_model = - cupsGetOption(kCUPSOptPrinterMakeAndModel, destination_->num_options, - destination_->options); + std::string GetMakeAndModel() const override { + const char* make_and_model = + cupsGetOption(kCUPSOptPrinterMakeAndModel, destination_->num_options, + destination_->options); - return make_and_model ? std::string(make_and_model) : std::string(); -} + return make_and_model ? std::string(make_and_model) : std::string(); + } -std::string CupsPrinter::GetInfo() const { - const char* info = cupsGetOption( - kCUPSOptPrinterInfo, destination_->num_options, destination_->options); + std::string GetInfo() const override { + const char* info = cupsGetOption( + kCUPSOptPrinterInfo, destination_->num_options, destination_->options); - return info ? std::string(info) : std::string(); -} + return info ? std::string(info) : std::string(); + } -std::string CupsPrinter::GetUri() const { - const char* uri = cupsGetOption(kCUPSOptDeviceUri, destination_->num_options, - destination_->options); - return uri ? std::string(uri) : std::string(); -} + std::string GetUri() const override { + const char* uri = cupsGetOption( + kCUPSOptDeviceUri, destination_->num_options, destination_->options); + return uri ? std::string(uri) : std::string(); + } -bool CupsPrinter::EnsureDestInfo() const { - if (dest_info_) - return true; + bool EnsureDestInfo() const override { + if (dest_info_) + return true; - dest_info_.reset(cupsCopyDestInfo(cups_http_, destination_.get())); - return !!dest_info_; -} + dest_info_.reset(cupsCopyDestInfo(cups_http_, destination_.get())); + return !!dest_info_; + } -ipp_status_t CupsPrinter::CreateJob(int* job_id, - const std::string& title, - const std::string& username, - const std::vector<cups_option_t>& options) { - DCHECK(dest_info_) << "Verify availability before starting a print job"; - - cups_option_t* data = const_cast<cups_option_t*>( - options.data()); // createDestJob will not modify the data - if (!username.empty()) - cupsSetUser(username.c_str()); - - ipp_status_t create_status = cupsCreateDestJob( - cups_http_, destination_.get(), dest_info_.get(), job_id, - title.empty() ? nullptr : title.c_str(), options.size(), data); - cupsSetUser(nullptr); // reset to default username ("anonymous") - return create_status; -} + ipp_status_t CreateJob(int* job_id, + const std::string& title, + const std::string& username, + const std::vector<cups_option_t>& options) override { + DCHECK(dest_info_) << "Verify availability before starting a print job"; + + cups_option_t* data = const_cast<cups_option_t*>( + options.data()); // createDestJob will not modify the data + if (!username.empty()) + cupsSetUser(username.c_str()); + + ipp_status_t create_status = cupsCreateDestJob( + cups_http_, destination_.get(), dest_info_.get(), job_id, + title.empty() ? nullptr : title.c_str(), options.size(), data); + cupsSetUser(nullptr); // reset to default username ("anonymous") + return create_status; + } -bool CupsPrinter::StartDocument(int job_id, - const std::string& docname, - bool last_document, - const std::string& username, - const std::vector<cups_option_t>& options) { - DCHECK(dest_info_); - DCHECK(job_id); - if (!username.empty()) - cupsSetUser(username.c_str()); - - cups_option_t* data = const_cast<cups_option_t*>( - options.data()); // createStartDestDocument will not modify the data - http_status_t start_doc_status = cupsStartDestDocument( - cups_http_, destination_.get(), dest_info_.get(), job_id, - docname.empty() ? nullptr : docname.c_str(), CUPS_FORMAT_PDF, - options.size(), data, last_document ? 1 : 0); - - cupsSetUser(nullptr); // reset to default username ("anonymous") - return start_doc_status == HTTP_CONTINUE; -} + bool StartDocument(int job_id, + const std::string& docname, + bool last_document, + const std::string& username, + const std::vector<cups_option_t>& options) override { + DCHECK(dest_info_); + DCHECK(job_id); + if (!username.empty()) + cupsSetUser(username.c_str()); + + cups_option_t* data = const_cast<cups_option_t*>( + options.data()); // createStartDestDocument will not modify the data + http_status_t start_doc_status = cupsStartDestDocument( + cups_http_, destination_.get(), dest_info_.get(), job_id, + docname.empty() ? nullptr : docname.c_str(), CUPS_FORMAT_PDF, + options.size(), data, last_document ? 1 : 0); + + cupsSetUser(nullptr); // reset to default username ("anonymous") + return start_doc_status == HTTP_CONTINUE; + } -bool CupsPrinter::StreamData(const std::vector<char>& buffer) { - http_status_t status = - cupsWriteRequestData(cups_http_, buffer.data(), buffer.size()); - return status == HTTP_STATUS_CONTINUE; -} + bool StreamData(const std::vector<char>& buffer) override { + http_status_t status = + cupsWriteRequestData(cups_http_, buffer.data(), buffer.size()); + return status == HTTP_STATUS_CONTINUE; + } -bool CupsPrinter::FinishDocument() { - DCHECK(dest_info_); + bool FinishDocument() override { + DCHECK(dest_info_); - ipp_status_t status = - cupsFinishDestDocument(cups_http_, destination_.get(), dest_info_.get()); + ipp_status_t status = cupsFinishDestDocument(cups_http_, destination_.get(), + dest_info_.get()); - return status == IPP_STATUS_OK; -} + return status == IPP_STATUS_OK; + } -ipp_status_t CupsPrinter::CloseJob(int job_id, const std::string& username) { - DCHECK(dest_info_); - DCHECK(job_id); - if (!username.empty()) - cupsSetUser(username.c_str()); + ipp_status_t CloseJob(int job_id, const std::string& username) override { + DCHECK(dest_info_); + DCHECK(job_id); + if (!username.empty()) + cupsSetUser(username.c_str()); - ipp_status_t result = cupsCloseDestJob(cups_http_, destination_.get(), - dest_info_.get(), job_id); - cupsSetUser(nullptr); // reset to default username ("anonymous") - return result; -} + ipp_status_t result = cupsCloseDestJob(cups_http_, destination_.get(), + dest_info_.get(), job_id); + cupsSetUser(nullptr); // reset to default username ("anonymous") + return result; + } -bool CupsPrinter::CancelJob(int job_id) { - DCHECK(job_id); + bool CancelJob(int job_id) override { + DCHECK(job_id); - // TODO(skau): Try to change back to cupsCancelDestJob(). - ipp_status_t status = - cupsCancelJob2(cups_http_, destination_->name, job_id, 0 /*cancel*/); - return status == IPP_STATUS_OK; -} + // TODO(skau): Try to change back to cupsCancelDestJob(). + ipp_status_t status = + cupsCancelJob2(cups_http_, destination_->name, job_id, 0 /*cancel*/); + return status == IPP_STATUS_OK; + } -CupsPrinter::CupsMediaMargins CupsPrinter::GetMediaMarginsByName( - const std::string& media_id) { - cups_size_t cups_media; - if (!EnsureDestInfo() || - !cupsGetDestMediaByName(cups_http_, destination_.get(), dest_info_.get(), - media_id.c_str(), CUPS_MEDIA_FLAGS_DEFAULT, - &cups_media)) { - return {0, 0, 0, 0}; + CupsMediaMargins GetMediaMarginsByName(const std::string& media_id) override { + cups_size_t cups_media; + if (!EnsureDestInfo() || + !cupsGetDestMediaByName(cups_http_, destination_.get(), + dest_info_.get(), media_id.c_str(), + CUPS_MEDIA_FLAGS_DEFAULT, &cups_media)) { + return {0, 0, 0, 0}; + } + return {cups_media.bottom, cups_media.left, cups_media.right, + cups_media.top}; } - return {cups_media.bottom, cups_media.left, cups_media.right, cups_media.top}; + + private: + // http connection owned by the CupsConnection which created this object + http_t* const cups_http_; + + // information to identify a printer + ScopedDestination destination_; + + // opaque object containing printer attributes and options + mutable ScopedDestInfo dest_info_; +}; + +std::unique_ptr<CupsPrinter> CupsPrinter::Create(http_t* http, + ScopedDestination dest) { + return std::make_unique<CupsPrinterImpl>(http, std::move(dest)); } } // namespace printing diff --git a/chromium/printing/backend/cups_printer.h b/chromium/printing/backend/cups_printer.h index c61d0b00339..b4ef8240c31 100644 --- a/chromium/printing/backend/cups_printer.h +++ b/chromium/printing/backend/cups_printer.h @@ -60,80 +60,67 @@ class PRINTING_EXPORT CupsPrinter : public CupsOptionProvider { int top; }; + ~CupsPrinter() override = default; + // Create a printer with a connection defined by |http| and |dest|. - CupsPrinter(http_t* http, ScopedDestination dest); - CupsPrinter(CupsPrinter&& printer); - CupsPrinter(const CupsPrinter&) = delete; - CupsPrinter& operator=(const CupsPrinter&) = delete; - ~CupsPrinter() override; + static std::unique_ptr<CupsPrinter> Create(http_t* http, + ScopedDestination dest); // Returns true if this is the default printer - bool is_default() const; - - // CupsOptionProvider - ipp_attribute_t* GetSupportedOptionValues( - const char* option_name) const override; - std::vector<base::StringPiece> GetSupportedOptionValueStrings( - const char* option_name) const override; - ipp_attribute_t* GetDefaultOptionValue( - const char* option_name) const override; - bool CheckOptionSupported(const char* name, const char* value) const override; - - // Returns the contents of the PPD retrieved from the print server. - std::string GetPPD() const; + virtual bool is_default() const = 0; // Returns the name of the printer as configured in CUPS - std::string GetName() const; + virtual std::string GetName() const = 0; - std::string GetMakeAndModel() const; + virtual std::string GetMakeAndModel() const = 0; // Returns the "printer-info" option of the printer as configured in CUPS. - std::string GetInfo() const; + virtual std::string GetInfo() const = 0; - std::string GetUri() const; + virtual std::string GetUri() const = 0; // Lazily initialize dest info as it can require a network call - bool EnsureDestInfo() const; + virtual bool EnsureDestInfo() const = 0; // Populates |basic_info| with the relevant information about the printer - bool ToPrinterInfo(PrinterBasicInfo* basic_info) const; + virtual bool ToPrinterInfo(PrinterBasicInfo* basic_info) const = 0; // Start a print job. Writes the id of the started job to |job_id|. |job_id| // is 0 if there is an error. |title| is not sent if empty. |username| is // not sent if empty. Check availability before using this operation. Usage // on an unavailable printer is undefined. - ipp_status_t CreateJob(int* job_id, - const std::string& title, - const std::string& username, - const std::vector<cups_option_t>& options); + virtual ipp_status_t CreateJob(int* job_id, + const std::string& title, + const std::string& username, + const std::vector<cups_option_t>& options) = 0; // Add a document to a print job. |job_id| must be non-zero and refer to a // job started with CreateJob. |docname| will be displayed in print status // if not empty. |last_doc| should be true if this is the last document for // this print job. |username| is not sent if empty. |options| should be IPP // key value pairs for the Send-Document operation. - bool StartDocument(int job_id, - const std::string& docname, - bool last_doc, - const std::string& username, - const std::vector<cups_option_t>& options); + virtual bool StartDocument(int job_id, + const std::string& docname, + bool last_doc, + const std::string& username, + const std::vector<cups_option_t>& options) = 0; // Add data to the current document started by StartDocument. Calling this // without a started document will fail. - bool StreamData(const std::vector<char>& buffer); + virtual bool StreamData(const std::vector<char>& buffer) = 0; // Finish the current document. Another document can be added or the job can // be closed to complete printing. - bool FinishDocument(); + virtual bool FinishDocument() = 0; // Close the job. If the job is not closed, the documents will not be // printed. |job_id| should match the id from CreateJob. |username| is not // sent if empty. - ipp_status_t CloseJob(int job_id, const std::string& username); + virtual ipp_status_t CloseJob(int job_id, const std::string& username) = 0; // Cancel the print job |job_id|. Returns true if the operation succeeded. // Returns false if it failed for any reason. - bool CancelJob(int job_id); + virtual bool CancelJob(int job_id) = 0; // Queries CUPS for the margins of the media named by |media_id|. // @@ -142,17 +129,8 @@ class PRINTING_EXPORT CupsPrinter : public CupsOptionProvider { // print_media_l10n.cc. // // Returns all zeroes if the CUPS API call fails. - CupsMediaMargins GetMediaMarginsByName(const std::string& media_id); - - private: - // http connection owned by the CupsConnection which created this object - http_t* const cups_http_; - - // information to identify a printer - ScopedDestination destination_; - - // opaque object containing printer attributes and options - mutable ScopedDestInfo dest_info_; + virtual CupsMediaMargins GetMediaMarginsByName( + const std::string& media_id) = 0; }; } // namespace printing diff --git a/chromium/printing/backend/mojom/BUILD.gn b/chromium/printing/backend/mojom/BUILD.gn index cc937be7447..5a4fdc6abfd 100644 --- a/chromium/printing/backend/mojom/BUILD.gn +++ b/chromium/printing/backend/mojom/BUILD.gn @@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { @@ -16,6 +17,10 @@ mojom("mojom") { { types = [ { + mojom = "printing.mojom.PrinterBasicInfo" + cpp = "::printing::PrinterBasicInfo" + }, + { mojom = "printing.mojom.Paper" cpp = "::printing::PrinterSemanticCapsAndDefaults::Paper" }, @@ -26,11 +31,14 @@ mojom("mojom") { ] traits_sources = [ "print_backend_mojom_traits.cc" ] traits_headers = [ "print_backend_mojom_traits.h" ] - traits_deps = [ "//printing:printing" ] + traits_deps = [ + "//build:chromeos_buildflags", + "//printing:printing", + ] }, ] - if (is_chromeos) { + if (is_chromeos_ash) { cpp_typemaps += [ { types = [ diff --git a/chromium/printing/backend/mojom/print_backend.mojom b/chromium/printing/backend/mojom/print_backend.mojom index fc1a95cad48..0cafbedae19 100644 --- a/chromium/printing/backend/mojom/print_backend.mojom +++ b/chromium/printing/backend/mojom/print_backend.mojom @@ -7,6 +7,16 @@ module printing.mojom; import "printing/mojom/print.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; +// Basic information for a specific printer. +struct PrinterBasicInfo { + string printer_name; + string display_name; + string printer_description; + int32 printer_status; + bool is_default; + map<string, string> options; +}; + // Paper used by printer semantic capabilities and defaults. struct Paper { string display_name; diff --git a/chromium/printing/backend/mojom/print_backend_mojom_traits.cc b/chromium/printing/backend/mojom/print_backend_mojom_traits.cc index f8509135c86..ca7a99e5182 100644 --- a/chromium/printing/backend/mojom/print_backend_mojom_traits.cc +++ b/chromium/printing/backend/mojom/print_backend_mojom_traits.cc @@ -7,6 +7,7 @@ #include <map> #include "base/logging.h" +#include "build/chromeos_buildflags.h" #include "ui/gfx/geometry/mojom/geometry.mojom-shared.h" #include "ui/gfx/geometry/mojom/geometry_mojom_traits.h" @@ -38,7 +39,7 @@ struct less<::printing::PrinterSemanticCapsAndDefaults::Paper> { } }; -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) template <> struct less<::printing::AdvancedCapability> { bool operator()(const ::printing::AdvancedCapability& lhs, @@ -48,7 +49,7 @@ struct less<::printing::AdvancedCapability> { return lhs.display_name < rhs.display_name; } }; -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } // namespace std @@ -73,6 +74,39 @@ class DuplicateChecker { } // namespace // static +bool StructTraits<printing::mojom::PrinterBasicInfoDataView, + printing::PrinterBasicInfo>:: + Read(printing::mojom::PrinterBasicInfoDataView data, + printing::PrinterBasicInfo* out) { + if (!data.ReadPrinterName(&out->printer_name) || + !data.ReadDisplayName(&out->display_name) || + !data.ReadPrinterDescription(&out->printer_description)) { + return false; + } + out->printer_status = data.printer_status(); + out->is_default = data.is_default(); + if (!data.ReadOptions(&out->options)) + return false; + + // There should be a non-empty value for `printer_name` since it needs to + // uniquely identify the printer with the operating system among multiple + // possible destinations. + if (out->printer_name.empty()) { + DLOG(ERROR) << "The printer name must not be empty."; + return false; + } + // There should be a non-empty value for `display_name` since it needs to + // uniquely identify the printer in user dialogs among multiple possible + // destinations. + if (out->display_name.empty()) { + DLOG(ERROR) << "The printer's display name must not be empty."; + return false; + } + + return true; +} + +// static bool StructTraits<printing::mojom::PaperDataView, printing::PrinterSemanticCapsAndDefaults::Paper>:: Read(printing::mojom::PaperDataView data, @@ -81,7 +115,7 @@ bool StructTraits<printing::mojom::PaperDataView, data.ReadVendorId(&out->vendor_id) && data.ReadSizeUm(&out->size_um); } -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) // static printing::mojom::AdvancedCapabilityType EnumTraits<printing::mojom::AdvancedCapabilityType, @@ -143,7 +177,7 @@ bool StructTraits<printing::mojom::AdvancedCapabilityDataView, data.ReadDefaultValue(&out->default_value) && data.ReadValues(&out->values); } -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) // static bool StructTraits<printing::mojom::PrinterSemanticCapsAndDefaultsDataView, @@ -167,11 +201,11 @@ bool StructTraits<printing::mojom::PrinterSemanticCapsAndDefaultsDataView, return false; } -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) out->pin_supported = data.pin_supported(); if (!data.ReadAdvancedCapabilities(&out->advanced_capabilities)) return false; -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) // Extra validity checks. @@ -214,7 +248,7 @@ bool StructTraits<printing::mojom::PrinterSemanticCapsAndDefaultsDataView, return false; } -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) DuplicateChecker<printing::AdvancedCapability> advanced_capabilities_dup_checker; if (advanced_capabilities_dup_checker.HasDuplicates( @@ -222,7 +256,7 @@ bool StructTraits<printing::mojom::PrinterSemanticCapsAndDefaultsDataView, DLOG(ERROR) << "Duplicate advanced_capabilities detected."; return false; } -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) return true; } diff --git a/chromium/printing/backend/mojom/print_backend_mojom_traits.h b/chromium/printing/backend/mojom/print_backend_mojom_traits.h index f64ce2268c4..13b3249f0ab 100644 --- a/chromium/printing/backend/mojom/print_backend_mojom_traits.h +++ b/chromium/printing/backend/mojom/print_backend_mojom_traits.h @@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "build/chromeos_buildflags.h" #include "printing/backend/mojom/print_backend.mojom-shared.h" #include "printing/backend/print_backend.h" #include "printing/mojom/print.mojom.h" @@ -16,6 +17,34 @@ namespace mojo { template <> +struct StructTraits<printing::mojom::PrinterBasicInfoDataView, + printing::PrinterBasicInfo> { + static const std::string& printer_name(const printing::PrinterBasicInfo& i) { + return i.printer_name; + } + static const std::string& display_name(const printing::PrinterBasicInfo& i) { + return i.display_name; + } + static const std::string& printer_description( + const printing::PrinterBasicInfo& i) { + return i.printer_description; + } + static int printer_status(const printing::PrinterBasicInfo& i) { + return i.printer_status; + } + static bool is_default(const printing::PrinterBasicInfo& i) { + return i.is_default; + } + static const printing::PrinterBasicInfoOptions& options( + const printing::PrinterBasicInfo& i) { + return i.options; + } + + static bool Read(printing::mojom::PrinterBasicInfoDataView data, + printing::PrinterBasicInfo* out); +}; + +template <> struct StructTraits<printing::mojom::PaperDataView, printing::PrinterSemanticCapsAndDefaults::Paper> { static const std::string& display_name( @@ -35,7 +64,7 @@ struct StructTraits<printing::mojom::PaperDataView, printing::PrinterSemanticCapsAndDefaults::Paper* out); }; -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) template <> struct EnumTraits<printing::mojom::AdvancedCapabilityType, ::printing::AdvancedCapability::Type> { @@ -86,7 +115,7 @@ struct StructTraits<printing::mojom::AdvancedCapabilityDataView, static bool Read(printing::mojom::AdvancedCapabilityDataView data, ::printing::AdvancedCapability* out); }; -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) template <> struct StructTraits<printing::mojom::PrinterSemanticCapsAndDefaultsDataView, @@ -146,7 +175,7 @@ struct StructTraits<printing::mojom::PrinterSemanticCapsAndDefaultsDataView, return p.default_dpi; } -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) static bool pin_supported(const printing::PrinterSemanticCapsAndDefaults& p) { return p.pin_supported; } @@ -154,7 +183,7 @@ struct StructTraits<printing::mojom::PrinterSemanticCapsAndDefaultsDataView, const printing::PrinterSemanticCapsAndDefaults& p) { return p.advanced_capabilities; } -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) static bool Read(printing::mojom::PrinterSemanticCapsAndDefaultsDataView data, printing::PrinterSemanticCapsAndDefaults* out); diff --git a/chromium/printing/backend/mojom/print_backend_mojom_traits_unittest.cc b/chromium/printing/backend/mojom/print_backend_mojom_traits_unittest.cc index a514521c62d..1457d636516 100644 --- a/chromium/printing/backend/mojom/print_backend_mojom_traits_unittest.cc +++ b/chromium/printing/backend/mojom/print_backend_mojom_traits_unittest.cc @@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <map> +#include <string> #include <vector> +#include "build/chromeos_buildflags.h" #include "mojo/public/cpp/test_support/test_utils.h" #include "printing/backend/mojom/print_backend.mojom.h" #include "printing/backend/print_backend.h" @@ -27,7 +30,7 @@ const printing::PrinterSemanticCapsAndDefaults::Paper kPaperLedger{ /*display_name=*/"Ledger", /*vendor_id=*/"89", /*size_um=*/gfx::Size(6600, 10200)}; -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) const printing::AdvancedCapability kAdvancedCapability1( /*name=*/"advanced_cap_bool", /*display_name=*/"Advanced Capability #1 (bool)", @@ -53,7 +56,7 @@ const printing::AdvancedCapability kAdvancedCapability2( }); const printing::AdvancedCapabilities kAdvancedCapabilities{ kAdvancedCapability1, kAdvancedCapability2}; -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) static constexpr bool kCollateCapable = true; static constexpr bool kCollateDefault = true; @@ -81,7 +84,7 @@ static constexpr gfx::Size kDpi1200(1200, 1200); static constexpr gfx::Size kDpi1200x600(1200, 600); const std::vector<gfx::Size> kDpis{kDpi600, kDpi1200, kDpi1200x600}; static constexpr gfx::Size kDefaultDpi = kDpi600; -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) static constexpr bool kPinSupported = true; #endif @@ -103,38 +106,102 @@ GenerateSamplePrinterSemanticCapsAndDefaults() { caps.default_paper = kPaperLetter; caps.dpis = kDpis; caps.default_dpi = kDefaultDpi; -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) caps.pin_supported = kPinSupported; caps.advanced_capabilities = kAdvancedCapabilities; -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) return caps; } } // namespace +TEST(PrintBackendMojomTraitsTest, TestSerializeAndDeserializePrinterBasicInfo) { + static const printing::PrinterBasicInfo kPrinterBasicInfo1( + /*printer_name=*/"test printer name 1", + /*display_name=*/"test display name 1", + /*printer_description=*/"This is printer #1 for unit testing.", + /*printer_status=*/0, + /*is_default=*/true, + /*options=*/ + std::map<std::string, std::string>{{"opt1", "123"}, {"opt2", "456"}}); + static const printing::PrinterBasicInfo kPrinterBasicInfo2( + /*printer_name=*/"test printer name 2", + /*display_name=*/"test display name 2", + /*printer_description=*/"This is printer #2 for unit testing.", + /*printer_status=*/1, + /*is_default=*/false, + /*options=*/std::map<std::string, std::string>{}); + static const printing::PrinterBasicInfo kPrinterBasicInfo3( + /*printer_name=*/"test printer name 2", + /*display_name=*/"test display name 2", + /*printer_description=*/"", + /*printer_status=*/9, + /*is_default=*/false, + /*options=*/std::map<std::string, std::string>{}); + static const PrinterList kPrinterList{kPrinterBasicInfo1, kPrinterBasicInfo2, + kPrinterBasicInfo3}; + + for (auto info : kPrinterList) { + printing::PrinterBasicInfo input = info; + printing::PrinterBasicInfo output; + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<printing::mojom::PrinterBasicInfo>( + input, output)); + EXPECT_EQ(info, output); + } +} + +TEST(PrintBackendMojomTraitsTest, + TestSerializeAndDeserializePrinterBasicInfoEmptyNames) { + static const printing::PrinterBasicInfo kPrinterBasicInfoEmptyPrinterName( + /*printer_name=*/"", + /*display_name=*/"test display name", + /*printer_description=*/"", + /*printer_status=*/0, + /*is_default=*/true, + /*options=*/std::map<std::string, std::string>{}); + static const printing::PrinterBasicInfo kPrinterBasicInfoEmptyDisplayName( + /*printer_name=*/"test printer name", + /*display_name=*/"", + /*printer_description=*/"", + /*printer_status=*/0, + /*is_default=*/true, + /*options=*/std::map<std::string, std::string>{}); + static const PrinterList kPrinterList{kPrinterBasicInfoEmptyPrinterName, + kPrinterBasicInfoEmptyDisplayName}; + + for (auto info : kPrinterList) { + printing::PrinterBasicInfo input = info; + printing::PrinterBasicInfo output; + EXPECT_FALSE( + mojo::test::SerializeAndDeserialize<printing::mojom::PrinterBasicInfo>( + input, output)); + } +} + TEST(PrintBackendMojomTraitsTest, TestSerializeAndDeserializePaper) { for (const auto& paper : kPapers) { printing::PrinterSemanticCapsAndDefaults::Paper input = paper; printing::PrinterSemanticCapsAndDefaults::Paper output; EXPECT_TRUE(mojo::test::SerializeAndDeserialize<printing::mojom::Paper>( - &input, &output)); + input, output)); EXPECT_EQ(paper, output); } } -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) TEST(PrintBackendMojomTraitsTest, TestSerializeAndDeserializeAdvancedCapability) { for (const auto& advanced_capability : kAdvancedCapabilities) { printing::AdvancedCapability input = advanced_capability; printing::AdvancedCapability output; EXPECT_TRUE(mojo::test::SerializeAndDeserialize< - printing::mojom::AdvancedCapability>(&input, &output)); + printing::mojom::AdvancedCapability>(input, output)); EXPECT_EQ(advanced_capability, output); } } -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) TEST(PrintBackendMojomTraitsTest, TestSerializeAndDeserializePrinterSemanticCapsAndDefaults) { @@ -142,9 +209,8 @@ TEST(PrintBackendMojomTraitsTest, GenerateSamplePrinterSemanticCapsAndDefaults(); printing::PrinterSemanticCapsAndDefaults output; - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize< - printing::mojom::PrinterSemanticCapsAndDefaults>(&input, &output)); + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + printing::mojom::PrinterSemanticCapsAndDefaults>(input, output)); EXPECT_EQ(kCollateCapable, output.collate_capable); EXPECT_EQ(kCollateDefault, output.collate_default); @@ -160,10 +226,10 @@ TEST(PrintBackendMojomTraitsTest, EXPECT_TRUE(kDefaultPaper == output.default_paper); EXPECT_EQ(kDpis, output.dpis); EXPECT_EQ(kDefaultDpi, output.default_dpi); -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) EXPECT_EQ(kPinSupported, output.pin_supported); EXPECT_EQ(kAdvancedCapabilities, output.advanced_capabilities); -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } TEST(PrintBackendMojomTraitsTest, @@ -175,9 +241,8 @@ TEST(PrintBackendMojomTraitsTest, // Override sample with no copies. input.copies_max = 0; - EXPECT_FALSE( - mojo::test::SerializeAndDeserialize< - printing::mojom::PrinterSemanticCapsAndDefaults>(&input, &output)); + EXPECT_FALSE(mojo::test::SerializeAndDeserialize< + printing::mojom::PrinterSemanticCapsAndDefaults>(input, output)); } TEST( @@ -193,25 +258,24 @@ TEST( const printing::PrinterSemanticCapsAndDefaults::Papers kEmptyUserDefinedPapers{}; const std::vector<gfx::Size> kEmptyDpis{}; -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) const printing::AdvancedCapabilities kEmptyAdvancedCapabilities{}; #endif input.duplex_modes = kEmptyDuplexModes; input.user_defined_papers = kEmptyUserDefinedPapers; input.dpis = kEmptyDpis; -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) input.advanced_capabilities = kEmptyAdvancedCapabilities; #endif - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize< - printing::mojom::PrinterSemanticCapsAndDefaults>(&input, &output)); + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + printing::mojom::PrinterSemanticCapsAndDefaults>(input, output)); EXPECT_EQ(kEmptyDuplexModes, output.duplex_modes); EXPECT_EQ(kEmptyUserDefinedPapers, output.user_defined_papers); EXPECT_EQ(kEmptyDpis, output.dpis); -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) EXPECT_EQ(kEmptyAdvancedCapabilities, output.advanced_capabilities); #endif } @@ -225,9 +289,8 @@ TEST(PrintBackendMojomTraitsTest, // Override sample with empty `papers`, which is not allowed. input.papers = printing::PrinterSemanticCapsAndDefaults::Papers{}; - EXPECT_FALSE( - mojo::test::SerializeAndDeserialize< - printing::mojom::PrinterSemanticCapsAndDefaults>(&input, &output)); + EXPECT_FALSE(mojo::test::SerializeAndDeserialize< + printing::mojom::PrinterSemanticCapsAndDefaults>(input, output)); } TEST( @@ -243,9 +306,8 @@ TEST( printing::mojom::DuplexMode::kSimplex, printing::mojom::DuplexMode::kSimplex}; - EXPECT_FALSE( - mojo::test::SerializeAndDeserialize< - printing::mojom::PrinterSemanticCapsAndDefaults>(&input, &output)); + EXPECT_FALSE(mojo::test::SerializeAndDeserialize< + printing::mojom::PrinterSemanticCapsAndDefaults>(input, output)); // Use a paper with same name but different size. printing::PrinterSemanticCapsAndDefaults::Paper paperA4Prime = kPaperA4; @@ -254,26 +316,23 @@ TEST( input.papers = printing::PrinterSemanticCapsAndDefaults::Papers{ kPaperA4, kPaperLetter, kPaperLedger, paperA4Prime}; - EXPECT_FALSE( - mojo::test::SerializeAndDeserialize< - printing::mojom::PrinterSemanticCapsAndDefaults>(&input, &output)); + EXPECT_FALSE(mojo::test::SerializeAndDeserialize< + printing::mojom::PrinterSemanticCapsAndDefaults>(input, output)); input = GenerateSamplePrinterSemanticCapsAndDefaults(); input.user_defined_papers = printing::PrinterSemanticCapsAndDefaults::Papers{ kPaperLetter, kPaperLetter}; - EXPECT_FALSE( - mojo::test::SerializeAndDeserialize< - printing::mojom::PrinterSemanticCapsAndDefaults>(&input, &output)); + EXPECT_FALSE(mojo::test::SerializeAndDeserialize< + printing::mojom::PrinterSemanticCapsAndDefaults>(input, output)); input = GenerateSamplePrinterSemanticCapsAndDefaults(); input.dpis = std::vector<gfx::Size>{kDpi600, kDpi600, kDpi1200}; - EXPECT_FALSE( - mojo::test::SerializeAndDeserialize< - printing::mojom::PrinterSemanticCapsAndDefaults>(&input, &output)); + EXPECT_FALSE(mojo::test::SerializeAndDeserialize< + printing::mojom::PrinterSemanticCapsAndDefaults>(input, output)); -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) // Use an advanced capability with same name but different other fields. printing::AdvancedCapability advancedCapability1Prime = kAdvancedCapability1; advancedCapability1Prime.type = printing::AdvancedCapability::Type::kInteger; @@ -282,9 +341,8 @@ TEST( input.advanced_capabilities = printing::AdvancedCapabilities{ kAdvancedCapability1, advancedCapability1Prime}; - EXPECT_FALSE( - mojo::test::SerializeAndDeserialize< - printing::mojom::PrinterSemanticCapsAndDefaults>(&input, &output)); + EXPECT_FALSE(mojo::test::SerializeAndDeserialize< + printing::mojom::PrinterSemanticCapsAndDefaults>(input, output)); #endif } diff --git a/chromium/printing/backend/print_backend.cc b/chromium/printing/backend/print_backend.cc index 7176a773032..9e5820fa387 100644 --- a/chromium/printing/backend/print_backend.cc +++ b/chromium/printing/backend/print_backend.cc @@ -4,6 +4,9 @@ #include "printing/backend/print_backend.h" +#include <string> + +#include "base/memory/scoped_refptr.h" #include "build/chromeos_buildflags.h" namespace { @@ -17,11 +20,32 @@ namespace printing { PrinterBasicInfo::PrinterBasicInfo() = default; +PrinterBasicInfo::PrinterBasicInfo(const std::string& printer_name, + const std::string& display_name, + const std::string& printer_description, + int printer_status, + bool is_default, + const PrinterBasicInfoOptions& options) + : printer_name(printer_name), + display_name(display_name), + printer_description(printer_description), + printer_status(printer_status), + is_default(is_default), + options(options) {} + PrinterBasicInfo::PrinterBasicInfo(const PrinterBasicInfo& other) = default; PrinterBasicInfo::~PrinterBasicInfo() = default; -#if BUILDFLAG(IS_ASH) +bool PrinterBasicInfo::operator==(const PrinterBasicInfo& other) const { + return printer_name == other.printer_name && + display_name == other.display_name && + printer_description == other.printer_description && + printer_status == other.printer_status && + is_default == other.is_default && options == other.options; +} + +#if BUILDFLAG(IS_CHROMEOS_ASH) AdvancedCapabilityValue::AdvancedCapabilityValue() = default; @@ -65,7 +89,7 @@ bool AdvancedCapability::operator==(const AdvancedCapability& other) const { values == other.values; } -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) bool PrinterSemanticCapsAndDefaults::Paper::operator==( const PrinterSemanticCapsAndDefaults::Paper& other) const { diff --git a/chromium/printing/backend/print_backend.h b/chromium/printing/backend/print_backend.h index b8b46ff2fac..e853381d2af 100644 --- a/chromium/printing/backend/print_backend.h +++ b/chromium/printing/backend/print_backend.h @@ -20,7 +20,7 @@ #include "printing/printing_export.h" #include "ui/gfx/geometry/size.h" -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) #include <stdint.h> #endif @@ -35,9 +35,17 @@ using PrinterBasicInfoOptions = std::map<std::string, std::string>; struct PRINTING_EXPORT PrinterBasicInfo { PrinterBasicInfo(); + PrinterBasicInfo(const std::string& printer_name, + const std::string& display_name, + const std::string& printer_description, + int printer_status, + bool is_default, + const PrinterBasicInfoOptions& options); PrinterBasicInfo(const PrinterBasicInfo& other); ~PrinterBasicInfo(); + bool operator==(const PrinterBasicInfo& other) const; + // The name of the printer as understood by OS. std::string printer_name; @@ -53,7 +61,7 @@ struct PRINTING_EXPORT PrinterBasicInfo { using PrinterList = std::vector<PrinterBasicInfo>; -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) struct PRINTING_EXPORT AdvancedCapabilityValue { AdvancedCapabilityValue(); @@ -103,7 +111,7 @@ struct PRINTING_EXPORT AdvancedCapability { using AdvancedCapabilities = std::vector<AdvancedCapability>; -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) struct PRINTING_EXPORT PrinterSemanticCapsAndDefaults { PrinterSemanticCapsAndDefaults(); @@ -141,10 +149,10 @@ struct PRINTING_EXPORT PrinterSemanticCapsAndDefaults { std::vector<gfx::Size> dpis; gfx::Size default_dpi; -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) bool pin_supported = false; AdvancedCapabilities advanced_capabilities; -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) }; struct PRINTING_EXPORT PrinterCapsAndDefaults { diff --git a/chromium/printing/backend/print_backend_cups_ipp.cc b/chromium/printing/backend/print_backend_cups_ipp.cc index 173b9858adc..2ad1d5b74d0 100644 --- a/chromium/printing/backend/print_backend_cups_ipp.cc +++ b/chromium/printing/backend/print_backend_cups_ipp.cc @@ -32,7 +32,8 @@ bool PrintBackendCupsIpp::EnumeratePrinters(PrinterList* printer_list) { DCHECK(printer_list); printer_list->clear(); - std::vector<CupsPrinter> printers = cups_connection_->GetDests(); + std::vector<std::unique_ptr<CupsPrinter>> printers = + cups_connection_->GetDests(); if (printers.empty()) { LOG(WARNING) << "CUPS: Error getting printers from CUPS server" << ", server: " << cups_connection_->server_name() @@ -44,7 +45,7 @@ bool PrintBackendCupsIpp::EnumeratePrinters(PrinterList* printer_list) { for (const auto& printer : printers) { PrinterBasicInfo basic_info; - if (printer.ToPrinterInfo(&basic_info)) { + if (printer->ToPrinterInfo(&basic_info)) { printer_list->push_back(basic_info); } } @@ -53,10 +54,11 @@ bool PrintBackendCupsIpp::EnumeratePrinters(PrinterList* printer_list) { } std::string PrintBackendCupsIpp::GetDefaultPrinterName() { - std::vector<CupsPrinter> printers = cups_connection_->GetDests(); + std::vector<std::unique_ptr<CupsPrinter>> printers = + cups_connection_->GetDests(); for (const auto& printer : printers) { - if (printer.is_default()) { - return printer.GetName(); + if (printer->is_default()) { + return printer->GetName(); } } diff --git a/chromium/printing/backend/print_backend_win.cc b/chromium/printing/backend/print_backend_win.cc index 74aaafc74e8..ed7eccc84cb 100644 --- a/chromium/printing/backend/print_backend_win.cc +++ b/chromium/printing/backend/print_backend_win.cc @@ -15,6 +15,7 @@ #include "base/numerics/safe_conversions.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" +#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/scoped_blocking_call.h" #include "base/win/scoped_bstr.h" @@ -104,7 +105,7 @@ void LoadPaper(const wchar_t* printer, paper.size_um.SetSize(sizes[i].x * kToUm, sizes[i].y * kToUm); if (!names.empty()) { const wchar_t* name_start = names[i].chars; - base::string16 tmp_name(name_start, kMaxPaperName); + std::wstring tmp_name(name_start, kMaxPaperName); // Trim trailing zeros. tmp_name = tmp_name.c_str(); paper.display_name = base::WideToUTF8(tmp_name); @@ -259,7 +260,7 @@ bool PrintBackendWin::GetPrinterSemanticCapsAndDefaults( return false; const wchar_t* name = info_5.get()->pPrinterName; const wchar_t* port = info_5.get()->pPortName; - DCHECK_EQ(name, base::UTF8ToUTF16(printer_name)); + DCHECK_EQ(name, base::UTF8ToWide(printer_name)); PrinterSemanticCapsAndDefaults caps; @@ -330,8 +331,8 @@ bool PrintBackendWin::GetPrinterCapsAndDefaults( return false; HPTPROVIDER provider = nullptr; - std::wstring printer_name_wide = base::UTF8ToWide(printer_name); - HRESULT hr = XPSModule::OpenProvider(printer_name_wide, 1, &provider); + std::wstring wide_printer_name = base::UTF8ToWide(printer_name); + HRESULT hr = XPSModule::OpenProvider(wide_printer_name, 1, &provider); if (!provider) return true; @@ -353,7 +354,7 @@ bool PrintBackendWin::GetPrinterCapsAndDefaults( printer_info->caps_mime_type = "text/xml"; } ScopedPrinterHandle printer_handle; - if (printer_handle.OpenPrinterWithName(printer_name_wide.c_str())) { + if (printer_handle.OpenPrinterWithName(wide_printer_name.c_str())) { std::unique_ptr<DEVMODE, base::FreeDeleter> devmode_out( CreateDevMode(printer_handle.Get(), nullptr)); if (!devmode_out) diff --git a/chromium/printing/backend/printing_restrictions.cc b/chromium/printing/backend/printing_restrictions.cc index 17a4c949d52..b23f89f7eda 100644 --- a/chromium/printing/backend/printing_restrictions.cc +++ b/chromium/printing/backend/printing_restrictions.cc @@ -8,14 +8,14 @@ namespace printing { -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) const char kAllowedColorModes[] = "allowedColorModes"; const char kAllowedDuplexModes[] = "allowedDuplexModes"; const char kAllowedPinModes[] = "allowedPinModes"; const char kDefaultColorMode[] = "defaultColorMode"; const char kDefaultDuplexMode[] = "defaultDuplexMode"; const char kDefaultPinMode[] = "defaultPinMode"; -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) const char kPaperSizeName[] = "name"; const char kPaperSizeNameCustomOption[] = "custom"; diff --git a/chromium/printing/backend/printing_restrictions.h b/chromium/printing/backend/printing_restrictions.h index 99d281e245d..c1c206d341f 100644 --- a/chromium/printing/backend/printing_restrictions.h +++ b/chromium/printing/backend/printing_restrictions.h @@ -10,7 +10,7 @@ namespace printing { -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) // Allowed printing modes as a bitmask. // This is used in pref file and should never change. enum class ColorModeRestriction { @@ -46,7 +46,7 @@ PRINTING_EXPORT extern const char kAllowedPinModes[]; PRINTING_EXPORT extern const char kDefaultColorMode[]; PRINTING_EXPORT extern const char kDefaultDuplexMode[]; PRINTING_EXPORT extern const char kDefaultPinMode[]; -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) // Allowed background graphics modes. // This is used in pref file and should never change. diff --git a/chromium/printing/backend/test_print_backend.cc b/chromium/printing/backend/test_print_backend.cc index 2eff8c9a335..5e438889c13 100644 --- a/chromium/printing/backend/test_print_backend.cc +++ b/chromium/printing/backend/test_print_backend.cc @@ -5,9 +5,12 @@ #include "printing/backend/test_print_backend.h" #include <memory> +#include <string> #include <utility> -#include "base/stl_util.h" +#include "base/check.h" +#include "base/containers/contains.h" +#include "base/logging.h" #include "printing/backend/print_backend.h" namespace printing { @@ -17,11 +20,17 @@ TestPrintBackend::TestPrintBackend() : PrintBackend(/*locale=*/std::string()) {} TestPrintBackend::~TestPrintBackend() = default; bool TestPrintBackend::EnumeratePrinters(PrinterList* printer_list) { - // TODO(crbug.com/809738) There was never a call to provide a list of - // printers for the environment, so this would always be empty. - // This needs to be updated as part of a larger cleanup to make - // TestPrintBackend have consistent behavior across its APIs. - return false; + if (printer_map_.empty()) + return false; + + for (const auto& entry : printer_map_) { + const std::unique_ptr<PrinterData>& data = entry.second; + + // Can only return basic info for printers which have registered info. + if (data->info) + printer_list->emplace_back(*data->info); + } + return true; } std::string TestPrintBackend::GetDefaultPrinterName() { @@ -30,53 +39,97 @@ std::string TestPrintBackend::GetDefaultPrinterName() { bool TestPrintBackend::GetPrinterBasicInfo(const std::string& printer_name, PrinterBasicInfo* printer_info) { - NOTREACHED() << "Not implemented"; - return false; + auto found = printer_map_.find(printer_name); + if (found == printer_map_.end()) + return false; // Matching entry not found. + + // Basic info might not have been provided. + const std::unique_ptr<PrinterData>& data = found->second; + if (!data->info) + return false; + + *printer_info = *data->info; + return true; } bool TestPrintBackend::GetPrinterSemanticCapsAndDefaults( const std::string& printer_name, - PrinterSemanticCapsAndDefaults* printer_info) { - auto found = valid_printers_.find(printer_name); - if (found == valid_printers_.end()) + PrinterSemanticCapsAndDefaults* printer_caps) { + auto found = printer_map_.find(printer_name); + if (found == printer_map_.end()) return false; - const std::unique_ptr<PrinterSemanticCapsAndDefaults>& caps = found->second; - if (!caps) + // Capabilities might not have been provided. + const std::unique_ptr<PrinterData>& data = found->second; + if (!data->caps) return false; - *printer_info = *(found->second); + *printer_caps = *data->caps; return true; } bool TestPrintBackend::GetPrinterCapsAndDefaults( const std::string& printer_name, - PrinterCapsAndDefaults* printer_info) { + PrinterCapsAndDefaults* printer_caps) { // not implemented return false; } std::string TestPrintBackend::GetPrinterDriverInfo( - const std::string& printr_name) { + const std::string& printer_name) { // not implemented return ""; } bool TestPrintBackend::IsValidPrinter(const std::string& printer_name) { - return base::Contains(valid_printers_, printer_name); + return base::Contains(printer_map_, printer_name); } void TestPrintBackend::SetDefaultPrinterName(const std::string& printer_name) { + if (default_printer_name_ == printer_name) + return; + + auto found = printer_map_.find(printer_name); + if (found == printer_map_.end()) { + DLOG(ERROR) << "Unable to set an unknown printer as the default. Unknown " + << "printer name: " << printer_name; + return; + } + + // Previous default printer is no longer the default. + const std::unique_ptr<PrinterData>& new_default_data = found->second; + if (!default_printer_name_.empty()) + printer_map_[default_printer_name_]->info->is_default = false; + + // Now update new printer as default. default_printer_name_ = printer_name; + if (!default_printer_name_.empty()) + new_default_data->info->is_default = true; } void TestPrintBackend::AddValidPrinter( const std::string& printer_name, std::unique_ptr<PrinterSemanticCapsAndDefaults> caps, std::unique_ptr<PrinterBasicInfo> info) { - // TODO(crbug.com/809738) Utilize the extra `info` parameter to improve - // TestPrintBackend internal consistency. - valid_printers_[printer_name] = std::move(caps); + DCHECK(!printer_name.empty()); + + const bool is_default = info && info->is_default; + printer_map_[printer_name] = + std::make_unique<PrinterData>(std::move(caps), std::move(info)); + + // Ensure that default settings are honored if more than one is attempted to + // be marked as default or if this prior default should no longer be so. + if (is_default) + SetDefaultPrinterName(printer_name); + else if (default_printer_name_ == printer_name) + default_printer_name_.clear(); } +TestPrintBackend::PrinterData::PrinterData( + std::unique_ptr<PrinterSemanticCapsAndDefaults> caps, + std::unique_ptr<PrinterBasicInfo> info) + : caps(std::move(caps)), info(std::move(info)) {} + +TestPrintBackend::PrinterData::~PrinterData() = default; + } // namespace printing diff --git a/chromium/printing/backend/test_print_backend.h b/chromium/printing/backend/test_print_backend.h index c80b8b01f18..17ff0742046 100644 --- a/chromium/printing/backend/test_print_backend.h +++ b/chromium/printing/backend/test_print_backend.h @@ -5,11 +5,10 @@ #ifndef PRINTING_BACKEND_TEST_PRINT_BACKEND_H_ #define PRINTING_BACKEND_TEST_PRINT_BACKEND_H_ -#include <map> #include <memory> #include <string> -#include <vector> +#include "base/containers/flat_map.h" #include "printing/backend/print_backend.h" namespace printing { @@ -33,17 +32,18 @@ class TestPrintBackend : public PrintBackend { std::string GetPrinterDriverInfo(const std::string& printer_name) override; bool IsValidPrinter(const std::string& printer_name) override; - // Set a default printer. The default is the empty string. + // Methods for test setup: + + // Sets a default printer. The default is the empty string. void SetDefaultPrinterName(const std::string& printer_name); - // Add a printer to satisfy IsValidPrinter(), EnumeratePrinters(), + // Adds a printer to satisfy IsValidPrinter(), EnumeratePrinters(), // GetPrinterBasicInfo(), and GetPrinterSemanticCapsAndDefaults(). // While `caps` can be null, it will cause queries for the capabilities to // fail, and thus is likely not of interest for most tests. IsValidPrinter() // will still show true even if `caps` is null, which provides the benefit of // simulating a printer that exists in the system but cannot be queried. - // `info` can be null, which will result in empty information being provided - // for any queries. + // `info` can be null, which will result in queries for basic info to fail. // Calling EnumeratePrinters() will include the identified `printer_name` // even if either parameter is null. void AddValidPrinter(const std::string& printer_name, @@ -54,9 +54,21 @@ class TestPrintBackend : public PrintBackend { ~TestPrintBackend() override; private: + struct PrinterData { + PrinterData(std::unique_ptr<PrinterSemanticCapsAndDefaults> caps, + std::unique_ptr<PrinterBasicInfo> info); + ~PrinterData(); + + std::unique_ptr<PrinterSemanticCapsAndDefaults> caps; + std::unique_ptr<PrinterBasicInfo> info; + }; + std::string default_printer_name_; - std::map<std::string, std::unique_ptr<PrinterSemanticCapsAndDefaults>> - valid_printers_; + // The values in `printer_map_` will not be null. The use of a pointer to + // PrinterData is just a workaround for the deleted copy assignment operator + // for the `caps` field, as that prevents the PrinterData container from + // being copied into the map. + base::flat_map<std::string, std::unique_ptr<PrinterData>> printer_map_; }; } // namespace printing diff --git a/chromium/printing/backend/test_print_backend_unittest.cc b/chromium/printing/backend/test_print_backend_unittest.cc new file mode 100644 index 00000000000..5628819df83 --- /dev/null +++ b/chromium/printing/backend/test_print_backend_unittest.cc @@ -0,0 +1,232 @@ +// Copyright 2020 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/test_print_backend.h" + +#include <stdint.h> + +#include <string> +#include <utility> +#include <vector> + +#include "base/memory/scoped_refptr.h" +#include "base/stl_util.h" +#include "base/test/gtest_util.h" +#include "printing/backend/print_backend.h" +#include "printing/mojom/print.mojom.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/size.h" + +namespace printing { + +namespace { + +constexpr char kDefaultPrinterName[] = "default-test-printer"; +constexpr char kAlternatePrinterName[] = "alternate-test-printer"; +constexpr char kNullDataPrinterName[] = "null-data-test-printer"; +constexpr char kInvalidPrinterName[] = "invalid-test-printer"; + +constexpr int kDefaultPrinterStatus = 0; +constexpr int kAlternatePrinterStatus = 1; + +const PrinterBasicInfo kDefaultPrinterInfo( + /*printer_name=*/kDefaultPrinterName, + /*display_name=*/"default test printer", + /*printer_description=*/"Default printer for testing.", + /*printer_status=*/kDefaultPrinterStatus, + /*is_default=*/true, + /*options=*/PrinterBasicInfoOptions{}); +const PrinterBasicInfo kAlternatePrinterInfo( + /*printer_name=*/kAlternatePrinterName, + /*display_name=*/"alternate test printer", + /*printer_description=*/"Alternate printer for testing.", + /*printer_status=*/kAlternatePrinterStatus, + /*is_default=*/false, + /*options=*/PrinterBasicInfoOptions{}); + +constexpr int32_t kDefaultCopiesMax = 123; +constexpr int32_t kAlternateCopiesMax = 456; + +} // namespace + +class TestPrintBackendTest : public testing::Test { + public: + void SetUp() override { + test_print_backend_ = base::MakeRefCounted<TestPrintBackend>(); + } + + void AddPrinters() { + // Add some printers; only bother to set one capabilities field that will + // be paid attention to in the tests as way of knowing it has provided the + // real capabilities. + auto caps = std::make_unique<PrinterSemanticCapsAndDefaults>(); + caps->copies_max = kDefaultCopiesMax; + test_print_backend_->AddValidPrinter( + kDefaultPrinterName, std::move(caps), + std::make_unique<PrinterBasicInfo>(kDefaultPrinterInfo)); + + caps = std::make_unique<PrinterSemanticCapsAndDefaults>(); + caps->copies_max = kAlternateCopiesMax; + test_print_backend_->AddValidPrinter( + kAlternatePrinterName, std::move(caps), + std::make_unique<PrinterBasicInfo>(kAlternatePrinterInfo)); + + test_print_backend_->AddValidPrinter(kNullDataPrinterName, /*caps=*/nullptr, + /*info=*/nullptr); + } + + // Get the test print backend. + TestPrintBackend* GetPrintBackend() const { + return test_print_backend_.get(); + } + + private: + scoped_refptr<TestPrintBackend> test_print_backend_; +}; + +TEST_F(TestPrintBackendTest, EnumeratePrinters) { + const PrinterList kPrinterList{kAlternatePrinterInfo, kDefaultPrinterInfo}; + PrinterList printer_list; + + // Should return false when there are no printers in the environment. + EXPECT_FALSE(GetPrintBackend()->EnumeratePrinters(&printer_list)); + + AddPrinters(); + + EXPECT_TRUE(GetPrintBackend()->EnumeratePrinters(&printer_list)); + EXPECT_THAT(printer_list, testing::ContainerEq(kPrinterList)); +} + +TEST_F(TestPrintBackendTest, DefaultPrinterName) { + // If no printers added then no default. + EXPECT_TRUE(GetPrintBackend()->GetDefaultPrinterName().empty()); + + // Once printers are available, should be a default. + AddPrinters(); + EXPECT_EQ(GetPrintBackend()->GetDefaultPrinterName(), kDefaultPrinterName); + + // Changing default should be reflected on next query. + GetPrintBackend()->SetDefaultPrinterName(kAlternatePrinterName); + EXPECT_EQ(GetPrintBackend()->GetDefaultPrinterName(), kAlternatePrinterName); + + // Adding a new printer to environment which is marked as default should + // automatically make it the new default. + static constexpr char kNewDefaultPrinterName[] = "new-default-test-printer"; + auto caps = std::make_unique<PrinterSemanticCapsAndDefaults>(); + auto printer_info = std::make_unique<PrinterBasicInfo>(); + printer_info->printer_name = kNewDefaultPrinterName; + printer_info->is_default = true; + GetPrintBackend()->AddValidPrinter(kNewDefaultPrinterName, std::move(caps), + std::move(printer_info)); + EXPECT_EQ(GetPrintBackend()->GetDefaultPrinterName(), kNewDefaultPrinterName); + + // Requesting an invalid printer name to be a default should have no effect. + GetPrintBackend()->SetDefaultPrinterName(kInvalidPrinterName); + EXPECT_EQ(GetPrintBackend()->GetDefaultPrinterName(), kNewDefaultPrinterName); + + // Verify that re-adding a printer that was previously the default with null + // basic info results in no default printer anymore. + GetPrintBackend()->AddValidPrinter(kNewDefaultPrinterName, /*caps=*/nullptr, + /*info=*/nullptr); + EXPECT_TRUE(GetPrintBackend()->GetDefaultPrinterName().empty()); +} + +TEST_F(TestPrintBackendTest, PrinterBasicInfo) { + PrinterBasicInfo printer_info; + + AddPrinters(); + + EXPECT_TRUE(GetPrintBackend()->GetPrinterBasicInfo(kDefaultPrinterName, + &printer_info)); + EXPECT_EQ(printer_info.printer_name, kDefaultPrinterName); + EXPECT_EQ(printer_info.printer_status, kDefaultPrinterStatus); + EXPECT_TRUE(printer_info.is_default); + + EXPECT_TRUE(GetPrintBackend()->GetPrinterBasicInfo(kAlternatePrinterName, + &printer_info)); + EXPECT_EQ(printer_info.printer_name, kAlternatePrinterName); + EXPECT_EQ(printer_info.printer_status, kAlternatePrinterStatus); + EXPECT_FALSE(printer_info.is_default); + + EXPECT_FALSE(GetPrintBackend()->GetPrinterBasicInfo(kInvalidPrinterName, + &printer_info)); + + // Changing default should be reflected on next query. + GetPrintBackend()->SetDefaultPrinterName(kAlternatePrinterName); + EXPECT_TRUE(GetPrintBackend()->GetPrinterBasicInfo(kAlternatePrinterName, + &printer_info)); + EXPECT_TRUE(printer_info.is_default); + EXPECT_TRUE(GetPrintBackend()->GetPrinterBasicInfo(kDefaultPrinterName, + &printer_info)); + EXPECT_FALSE(printer_info.is_default); + + // Printers added with null basic info fail to get data on a query. + EXPECT_FALSE(GetPrintBackend()->GetPrinterBasicInfo(kNullDataPrinterName, + &printer_info)); + + // Verify that (re)adding a printer with null basic info results in a failure + // the next time when trying to get the basic info. + GetPrintBackend()->AddValidPrinter(kAlternatePrinterName, /*caps=*/nullptr, + /*info=*/nullptr); + EXPECT_FALSE(GetPrintBackend()->GetPrinterBasicInfo(kAlternatePrinterName, + &printer_info)); +} + +TEST_F(TestPrintBackendTest, GetPrinterSemanticCapsAndDefaults) { + PrinterSemanticCapsAndDefaults caps; + + // Should fail when there are no printers in the environment. + EXPECT_FALSE(GetPrintBackend()->GetPrinterSemanticCapsAndDefaults( + kDefaultPrinterName, &caps)); + + AddPrinters(); + + EXPECT_TRUE(GetPrintBackend()->GetPrinterSemanticCapsAndDefaults( + kDefaultPrinterName, &caps)); + EXPECT_EQ(caps.copies_max, kDefaultCopiesMax); + + EXPECT_TRUE(GetPrintBackend()->GetPrinterSemanticCapsAndDefaults( + kAlternatePrinterName, &caps)); + EXPECT_EQ(caps.copies_max, kAlternateCopiesMax); + + EXPECT_FALSE(GetPrintBackend()->GetPrinterSemanticCapsAndDefaults( + kInvalidPrinterName, &caps)); + + // Printers added with null capabilities fail to get data on a query. + EXPECT_FALSE(GetPrintBackend()->GetPrinterSemanticCapsAndDefaults( + kNullDataPrinterName, &caps)); + + // Verify that (re)adding a printer with null capabilities results in a + // failure the next time when trying to get capabilities. + GetPrintBackend()->AddValidPrinter(kAlternatePrinterName, /*caps=*/nullptr, + /*info=*/nullptr); + EXPECT_FALSE(GetPrintBackend()->GetPrinterSemanticCapsAndDefaults( + kAlternatePrinterName, &caps)); +} + +TEST_F(TestPrintBackendTest, IsValidPrinter) { + PrinterSemanticCapsAndDefaults caps; + + // Should fail when there are no printers in the environment. + EXPECT_FALSE(GetPrintBackend()->IsValidPrinter(kDefaultPrinterName)); + + AddPrinters(); + + EXPECT_TRUE(GetPrintBackend()->IsValidPrinter(kDefaultPrinterName)); + EXPECT_TRUE(GetPrintBackend()->IsValidPrinter(kAlternatePrinterName)); + EXPECT_FALSE(GetPrintBackend()->IsValidPrinter(kInvalidPrinterName)); + + // Verify that still shows as valid printer even if basic info and + // capabilities were originally null. + EXPECT_TRUE(GetPrintBackend()->IsValidPrinter(kNullDataPrinterName)); + + // Verify that (re)adding a printer with null info and capabilities still + // shows as valid. + GetPrintBackend()->AddValidPrinter(kAlternatePrinterName, /*caps=*/nullptr, + /*info=*/nullptr); + EXPECT_TRUE(GetPrintBackend()->IsValidPrinter(kAlternatePrinterName)); +} + +} // namespace printing diff --git a/chromium/printing/backend/tools/code_generator.py b/chromium/printing/backend/tools/code_generator.py index 872028697c9..3951c6be01d 100755 --- a/chromium/printing/backend/tools/code_generator.py +++ b/chromium/printing/backend/tools/code_generator.py @@ -10,13 +10,14 @@ import argparse import csv import re -# We skip attributes that are already implemented in print preview. +# Skip attributes that are already implemented in print preview plus job-priority (b/172208667). NOOP_ATTRS = [ 'copies', 'job-hold-until', 'job-copies', 'job-password', 'job-password-encryption', + 'job-priority', 'media', 'media-col', 'multiple-document-handling', @@ -58,7 +59,7 @@ HANDLER_FOOTER = """ return result; L10N_HEADER = """// DO NOT MODIFY // Generated by printing/backend/tools/code_generator.py -#include "components/printing/browser/ipp_l10n.h" +#include "chrome/common/printing/ipp_l10n.h" #include "base/no_destructor.h" #include "components/strings/grit/components_strings.h" diff --git a/chromium/printing/backend/win_helper.cc b/chromium/printing/backend/win_helper.cc index df45f28b2ea..e9d57725f10 100644 --- a/chromium/printing/backend/win_helper.cc +++ b/chromium/printing/backend/win_helper.cc @@ -211,7 +211,7 @@ bool XPSModule::InitImpl() { return true; } -HRESULT XPSModule::OpenProvider(const base::string16& printer_name, +HRESULT XPSModule::OpenProvider(const std::wstring& printer_name, DWORD version, HPTPROVIDER* provider) { base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, @@ -409,9 +409,9 @@ std::string GetDriverInfo(HANDLE printer) { FileVersionInfo::CreateFileVersionInfo( base::FilePath(info_6.get()->pDriverPath))); if (version_info.get()) { - info[1] = base::WideToUTF8(version_info->file_version()); - info[2] = base::WideToUTF8(version_info->product_name()); - info[3] = base::WideToUTF8(version_info->product_version()); + info[1] = base::UTF16ToUTF8(version_info->file_version()); + info[2] = base::UTF16ToUTF8(version_info->product_name()); + info[3] = base::UTF16ToUTF8(version_info->product_version()); } } @@ -425,7 +425,7 @@ std::string GetDriverInfo(HANDLE printer) { } std::unique_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode( - const base::string16& printer_name, + const std::wstring& printer_name, const std::string& print_ticket) { std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode; ScopedXPSInitializer xps_initializer; @@ -469,7 +469,7 @@ bool IsDevModeWithColor(const DEVMODE* devmode) { std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor( HANDLE printer, - const base::string16& printer_name, + const std::wstring& printer_name, bool color) { std::unique_ptr<DEVMODE, base::FreeDeleter> default_ticket = CreateDevMode(printer, nullptr); @@ -569,7 +569,7 @@ std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, std::unique_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( HANDLE printer, - const base::string16& printer_name, + const std::wstring& printer_name, DEVMODE* in, HWND window, bool* canceled) { diff --git a/chromium/printing/backend/win_helper.h b/chromium/printing/backend/win_helper.h index 13ab1412cf9..b2bd3328d54 100644 --- a/chromium/printing/backend/win_helper.h +++ b/chromium/printing/backend/win_helper.h @@ -20,7 +20,6 @@ #include <string> #include "base/memory/free_deleter.h" -#include "base/strings/string16.h" #include "base/win/scoped_handle.h" #include "printing/printing_export.h" @@ -81,7 +80,7 @@ class PRINTING_EXPORT XPSModule { // All the other methods can ONLY be called after a successful call to Init. // Init can be called many times and by multiple threads. static bool Init(); - static HRESULT OpenProvider(const base::string16& printer_name, + static HRESULT OpenProvider(const std::wstring& printer_name, DWORD version, HPTPROVIDER* provider); static HRESULT GetPrintCapabilities(HPTPROVIDER provider, @@ -163,7 +162,7 @@ PRINTING_EXPORT bool InitBasicPrinterInfo(HANDLE printer, PRINTING_EXPORT std::string GetDriverInfo(HANDLE printer); PRINTING_EXPORT std::unique_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode( - const base::string16& printer_name, + const std::wstring& printer_name, const std::string& print_ticket); PRINTING_EXPORT bool IsDevModeWithColor(const DEVMODE* devmode); @@ -172,7 +171,7 @@ PRINTING_EXPORT bool IsDevModeWithColor(const DEVMODE* devmode); // workaround for color. PRINTING_EXPORT std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor(HANDLE printer, - const base::string16& printer_name, + const std::wstring& printer_name, bool color); // Creates new DEVMODE. If |in| is not NULL copy settings from there. @@ -183,7 +182,7 @@ PRINTING_EXPORT std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode( // Prompts for new DEVMODE. If |in| is not NULL copy settings from there. PRINTING_EXPORT std::unique_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( HANDLE printer, - const base::string16& printer_name, + const std::wstring& printer_name, DEVMODE* in, HWND window, bool* canceled); diff --git a/chromium/printing/buildflags/buildflags.gni b/chromium/printing/buildflags/buildflags.gni index 86febe492a5..058e7f77747 100644 --- a/chromium/printing/buildflags/buildflags.gni +++ b/chromium/printing/buildflags/buildflags.gni @@ -4,6 +4,7 @@ import("//build/config/chromecast_build.gni") import("//build/config/chromeos/args.gni") +import("//build/config/chromeos/ui_mode.gni") import("//build/config/features.gni") import("//build/config/sanitizers/sanitizers.gni") @@ -24,7 +25,7 @@ declare_args() { # For fuzzing, just restrict to chromeos and linux. use_cups = true } else { - use_cups = (is_chromeos_device || is_linux || is_mac) && !is_chromecast && - !is_fuchsia + use_cups = (is_chromeos_device || (is_linux || is_chromeos_lacros) || + is_mac) && !is_chromecast && !is_fuchsia } } diff --git a/chromium/printing/emf_win_unittest.cc b/chromium/printing/emf_win_unittest.cc index a8ff6741740..a8bc3a4909d 100644 --- a/chromium/printing/emf_win_unittest.cc +++ b/chromium/printing/emf_win_unittest.cc @@ -87,7 +87,7 @@ TEST_F(EmfPrintingTest, Enumerate) { auto settings = std::make_unique<PrintSettings>(); // My test case is a HP Color LaserJet 4550 PCL. - settings->set_device_name(L"UnitTest Printer"); + settings->set_device_name(STRING16_LITERAL("UnitTest Printer")); // Initialize it. PrintingContextWin context(this); @@ -114,7 +114,7 @@ TEST_F(EmfPrintingTest, Enumerate) { // unit_test, PrintingContext automatically dumps its files to the // current directory. // TODO(maruel): Clean the .PRN file generated in current directory. - context.NewDocument(L"EmfTest.Enumerate"); + context.NewDocument(STRING16_LITERAL("EmfTest.Enumerate")); context.NewPage(); // Process one at a time. RECT page_bounds = emf.GetPageBounds(1).ToRECT(); diff --git a/chromium/printing/metafile_skia.cc b/chromium/printing/metafile_skia.cc index dddfcbae4f5..9aff20384cd 100644 --- a/chromium/printing/metafile_skia.cc +++ b/chromium/printing/metafile_skia.cc @@ -11,9 +11,9 @@ #include "base/bind.h" #include "base/callback_helpers.h" +#include "base/containers/contains.h" #include "base/files/file.h" #include "base/numerics/safe_conversions.h" -#include "base/stl_util.h" #include "base/time/time.h" #include "base/unguessable_token.h" #include "cc/paint/paint_record.h" diff --git a/chromium/printing/print_settings.cc b/chromium/printing/print_settings.cc index 7c43ddeafad..c22c0502d79 100644 --- a/chromium/printing/print_settings.cc +++ b/chromium/printing/print_settings.cc @@ -10,7 +10,7 @@ #include "build/chromeos_buildflags.h" #include "printing/units.h" -#if defined(USE_CUPS) && (defined(OS_MAC) || BUILDFLAG(IS_ASH)) +#if defined(USE_CUPS) && (defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)) #include <cups/cups.h> #endif @@ -183,7 +183,7 @@ void GetColorModelForModel(mojom::ColorModel color_model, // all ColorModel values are determinantly handled. } -#if defined(OS_MAC) || BUILDFLAG(IS_ASH) +#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) std::string GetIppColorModelForModel(mojom::ColorModel color_model) { // Accept |kUnknownColorModel| for consistency with GetColorModelForModel(). if (color_model == mojom::ColorModel::kUnknownColorModel) @@ -198,7 +198,7 @@ std::string GetIppColorModelForModel(mojom::ColorModel color_model) { return is_color.value() ? CUPS_PRINT_COLOR_MODE_COLOR : CUPS_PRINT_COLOR_MODE_MONOCHROME; } -#endif // defined(OS_MAC) || BUILDFLAG(IS_ASH) +#endif // defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) #endif // defined(USE_CUPS) base::Optional<bool> IsColorModelSelected(mojom::ColorModel color_model) { @@ -281,11 +281,11 @@ void PrintSettings::Clear() { #if defined(OS_LINUX) || defined(OS_CHROMEOS) advanced_settings_.clear(); #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) send_user_info_ = false; username_.clear(); pin_value_.clear(); -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } void PrintSettings::SetPrinterPrintableArea( diff --git a/chromium/printing/print_settings.h b/chromium/printing/print_settings.h index f15f1f84fc7..c3277c631ce 100644 --- a/chromium/printing/print_settings.h +++ b/chromium/printing/print_settings.h @@ -44,7 +44,7 @@ PRINTING_EXPORT void GetColorModelForModel(mojom::ColorModel color_model, std::string* color_setting_name, std::string* color_value); -#if defined(OS_MAC) || BUILDFLAG(IS_ASH) +#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) // Convert from |color_model| to a print-color-mode value from PWG 5100.13. PRINTING_EXPORT std::string GetIppColorModelForModel( mojom::ColorModel color_model); @@ -229,7 +229,7 @@ class PRINTING_EXPORT PrintSettings { } #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) void set_send_user_info(bool send_user_info) { send_user_info_ = send_user_info; } @@ -240,7 +240,7 @@ class PRINTING_EXPORT PrintSettings { void set_pin_value(const std::string& pin_value) { pin_value_ = pin_value; } const std::string& pin_value() const { return pin_value_; } -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) // Cookie generator. It is used to initialize PrintedDocument with its // associated PrintSettings, to be sure that each generated PrintedPage is @@ -326,7 +326,7 @@ class PRINTING_EXPORT PrintSettings { AdvancedSettings advanced_settings_; #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) // Whether to send user info. bool send_user_info_; diff --git a/chromium/printing/print_settings_conversion.cc b/chromium/printing/print_settings_conversion.cc index 686a2fa1ab4..15e52e7b153 100644 --- a/chromium/printing/print_settings_conversion.cc +++ b/chromium/printing/print_settings_conversion.cc @@ -211,16 +211,21 @@ std::unique_ptr<PrintSettings> PrintSettingsFromJobSettings( #endif } -#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(USE_CUPS)) +// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is +// complete. +#if defined(OS_CHROMEOS) || \ + ((defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \ + defined(USE_CUPS)) const base::Value* advanced_settings = job_settings.FindDictKey(kSettingAdvancedSettings); if (advanced_settings) { for (const auto& item : advanced_settings->DictItems()) settings->advanced_settings().emplace(item.first, item.second.Clone()); } -#endif // defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(USE_CUPS)) +#endif // defined(OS_CHROMEOS) || ((defined(OS_LINUX) || + // BUILDFLAG(IS_CHROMEOS_LACROS)) && defined(USE_CUPS)) -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) bool send_user_info = job_settings.FindBoolKey(kSettingSendUserInfo).value_or(false); settings->set_send_user_info(send_user_info); @@ -233,7 +238,7 @@ std::unique_ptr<PrintSettings> PrintSettingsFromJobSettings( const std::string* pin_value = job_settings.FindStringKey(kSettingPinValue); if (pin_value) settings->set_pin_value(*pin_value); -#endif // BUILDFLAG(IS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) return settings; } diff --git a/chromium/printing/print_settings_conversion_unittest.cc b/chromium/printing/print_settings_conversion_unittest.cc index 2f410d2d462..75a0b79453f 100644 --- a/chromium/printing/print_settings_conversion_unittest.cc +++ b/chromium/printing/print_settings_conversion_unittest.cc @@ -61,7 +61,7 @@ TEST(PrintSettingsConversionTest, ConversionTest) { std::unique_ptr<PrintSettings> settings = PrintSettingsFromJobSettings(value.value()); ASSERT_TRUE(settings); -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) EXPECT_TRUE(settings->send_user_info()); EXPECT_EQ("username@domain.net", settings->username()); EXPECT_EQ("0000", settings->pin_value()); @@ -78,7 +78,7 @@ TEST(PrintSettingsConversionTest, ConversionTest) { EXPECT_FALSE(settings); } -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) TEST(PrintSettingsConversionTest, ConversionTest_DontSendUsername) { base::Optional<base::Value> value = base::JSONReader::Read(kPrinterSettings); ASSERT_TRUE(value.has_value()); diff --git a/chromium/printing/print_settings_unittest.cc b/chromium/printing/print_settings_unittest.cc index c66d82ea8f7..56c0c430a13 100644 --- a/chromium/printing/print_settings_unittest.cc +++ b/chromium/printing/print_settings_unittest.cc @@ -56,7 +56,7 @@ TEST(PrintSettingsTest, GetColorModelForModel) { } } -#if defined(OS_MAC) || BUILDFLAG(IS_ASH) +#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) TEST(PrintSettingsTest, GetIppColorModelForModel) { for (int model = static_cast<int>(mojom::ColorModel::kUnknownColorModel); model <= static_cast<int>(mojom::ColorModel::kColorModelLast); ++model) { @@ -64,7 +64,7 @@ TEST(PrintSettingsTest, GetIppColorModelForModel) { .empty()); } } -#endif // defined(OS_MAC) || BUILDFLAG(IS_ASH) +#endif // defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) #endif // defined(USE_CUPS) } // namespace printing diff --git a/chromium/printing/printed_document.cc b/chromium/printing/printed_document.cc index 5ed3e08c152..4ee13d029e6 100644 --- a/chromium/printing/printed_document.cc +++ b/chromium/printing/printed_document.cc @@ -258,7 +258,7 @@ base::FilePath PrintedDocument::CreateDebugDumpPath( filename += document_name; base::FilePath::StringType system_filename; #if defined(OS_WIN) - system_filename = filename; + system_filename = base::UTF16ToWide(filename); #else // OS_WIN system_filename = base::UTF16ToUTF8(filename); #endif // OS_WIN diff --git a/chromium/printing/printed_document_linux.cc b/chromium/printing/printed_document_linux.cc index e3ef9ae649a..c2e2a5d59e1 100644 --- a/chromium/printing/printed_document_linux.cc +++ b/chromium/printing/printed_document_linux.cc @@ -8,7 +8,7 @@ #include "build/chromeos_buildflags.h" #include "printing/printing_context_linux.h" -#if defined(OS_ANDROID) || BUILDFLAG(IS_ASH) +#if defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) #error "This file is not used on Android / ChromeOS ash-chrome" #endif diff --git a/chromium/printing/printed_document_win.cc b/chromium/printing/printed_document_win.cc index 5025b8f031c..8806e53754e 100644 --- a/chromium/printing/printed_document_win.cc +++ b/chromium/printing/printed_document_win.cc @@ -5,6 +5,7 @@ #include "printing/printed_document.h" #include "base/check_op.h" +#include "base/strings/utf_string_conversions.h" #include "printing/metafile_skia.h" #include "printing/page_number.h" #include "printing/printed_page_win.h" @@ -83,7 +84,8 @@ bool PrintedDocument::RenderPrintedDocument(PrintingContext* context) { if (context->NewPage() != PrintingContext::OK) return false; - base::string16 device_name = immutable_.settings_->device_name(); + std::wstring device_name = + base::UTF16ToWide(immutable_.settings_->device_name()); { base::AutoLock lock(lock_); const MetafilePlayer* metafile = GetMetafile(); diff --git a/chromium/printing/printing_context.cc b/chromium/printing/printing_context.cc index 49e0e83868d..92561ff7c6b 100644 --- a/chromium/printing/printing_context.cc +++ b/chromium/printing/printing_context.cc @@ -146,7 +146,7 @@ PrintingContext::Result PrintingContext::UpdatePrintSettings( job_settings.FindIntKey(kSettingPreviewPageCount).value_or(0)); } -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) PrintingContext::Result PrintingContext::UpdatePrintSettingsFromPOD( std::unique_ptr<PrintSettings> job_settings) { ResetSettings(); diff --git a/chromium/printing/printing_context.h b/chromium/printing/printing_context.h index 896d1b26f49..268e03d2b8d 100644 --- a/chromium/printing/printing_context.h +++ b/chromium/printing/printing_context.h @@ -87,7 +87,7 @@ class PRINTING_EXPORT PrintingContext { // settings information. Result UpdatePrintSettings(base::Value job_settings); -#if BUILDFLAG(IS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) // Updates Print Settings. Result UpdatePrintSettingsFromPOD( std::unique_ptr<PrintSettings> job_settings); diff --git a/chromium/printing/printing_context_chromeos.cc b/chromium/printing/printing_context_chromeos.cc index 29be6f8b7c8..7d8a1de0f2d 100644 --- a/chromium/printing/printing_context_chromeos.cc +++ b/chromium/printing/printing_context_chromeos.cc @@ -30,12 +30,24 @@ #include "printing/print_job_constants.h" #include "printing/print_settings.h" #include "printing/printing_features.h" +#include "printing/printing_utils.h" #include "printing/units.h" namespace printing { namespace { +// We only support sending username for secure printers. +const char kUsernamePlaceholder[] = "chronos"; + +// We only support sending document name for secure printers. +const char kDocumentNamePlaceholder[] = "-"; + +bool IsUriInsecure(const base::StringPiece uri) { + return !base::StartsWith(uri, "ipps:") && !base::StartsWith(uri, "https:") && + !base::StartsWith(uri, "usb:") && !base::StartsWith(uri, "ippusb:"); +} + // Returns a new char buffer which is a null-terminated copy of |value|. The // caller owns the returned string. char* DuplicateString(const base::StringPiece value) { @@ -178,7 +190,7 @@ std::vector<ScopedCupsOption> SettingsToCupsOptions( options.push_back( ConstructOption(kIppColor, GetIppColorModelForModel(settings.color()))); // color - options.push_back(ConstructOption(kIppDuplex, sides)); // duplexing + options.push_back(ConstructOption(kIppDuplex, sides)); // duplexing options.push_back( ConstructOption(kIppMedia, settings.requested_media().vendor_id)); // paper size @@ -200,37 +212,35 @@ std::vector<ScopedCupsOption> SettingsToCupsOptions( options.push_back(ConstructOption(kIppResolution, dpi + "dpi")); } - if (base::FeatureList::IsEnabled( - printing::features::kAdvancedPpdAttributes)) { - size_t regular_attr_count = options.size(); - std::map<std::string, std::vector<std::string>> multival; - for (const auto& setting : settings.advanced_settings()) { - const std::string& key = setting.first; - const std::string& value = setting.second.GetString(); - if (value.empty()) - continue; - - // Check for multivalue enum ("attribute/value"). - size_t pos = key.find('/'); - if (pos == std::string::npos) { - // Regular value. - ReportEnumUsage(key); - options.push_back(ConstructOption(key, value)); - continue; - } - // Store selected enum values. - if (value == kOptionTrue) - multival[key.substr(0, pos)].push_back(key.substr(pos + 1)); + size_t regular_attr_count = options.size(); + std::map<std::string, std::vector<std::string>> multival; + for (const auto& setting : settings.advanced_settings()) { + const std::string& key = setting.first; + const std::string& value = setting.second.GetString(); + if (value.empty()) + continue; + + // Check for multivalue enum ("attribute/value"). + size_t pos = key.find('/'); + if (pos == std::string::npos) { + // Regular value. + ReportEnumUsage(key); + options.push_back(ConstructOption(key, value)); + continue; } - // Pass multivalue enums as comma-separated lists. - for (const auto& it : multival) { - ReportEnumUsage(it.first); - options.push_back( - ConstructOption(it.first, base::JoinString(it.second, ","))); - } - base::UmaHistogramCounts1000("Printing.CUPS.IppAttributesUsed", - options.size() - regular_attr_count); + // Store selected enum values. + if (value == kOptionTrue) + multival[key.substr(0, pos)].push_back(key.substr(pos + 1)); + } + + // Pass multivalue enums as comma-separated lists. + for (const auto& it : multival) { + ReportEnumUsage(it.first); + options.push_back( + ConstructOption(it.first, base::JoinString(it.second, ","))); } + base::UmaHistogramCounts1000("Printing.CUPS.IppAttributesUsed", + options.size() - regular_attr_count); return options; } @@ -242,7 +252,14 @@ std::unique_ptr<PrintingContext> PrintingContext::Create(Delegate* delegate) { PrintingContextChromeos::PrintingContextChromeos(Delegate* delegate) : PrintingContext(delegate), - connection_(GURL(), HTTP_ENCRYPT_NEVER, true), + connection_(CupsConnection::Create(GURL(), HTTP_ENCRYPT_NEVER, true)), + send_user_info_(false) {} + +PrintingContextChromeos::PrintingContextChromeos( + Delegate* delegate, + std::unique_ptr<CupsConnection> connection) + : PrintingContext(delegate), + connection_(std::move(connection)), send_user_info_(false) {} PrintingContextChromeos::~PrintingContextChromeos() { @@ -357,14 +374,12 @@ PrintingContext::Result PrintingContextChromeos::UpdatePrinterSettings( send_user_info_ = settings_->send_user_info(); if (send_user_info_) { DCHECK(printer_); - std::string uri_string = printer_->GetUri(); - const base::StringPiece uri(uri_string); - if (!base::StartsWith(uri, "ipps:") && !base::StartsWith(uri, "https:") && - !base::StartsWith(uri, "usb:") && !base::StartsWith(uri, "ippusb:")) { - return OnError(); + if (IsUriInsecure(printer_->GetUri())) { + username_ = kUsernamePlaceholder; + } else { + username_ = settings_->username(); } } - username_ = send_user_info_ ? settings_->username() : std::string(); return OK; } @@ -373,7 +388,7 @@ PrintingContext::Result PrintingContextChromeos::InitializeDevice( const std::string& device) { DCHECK(!in_print_job_); - std::unique_ptr<CupsPrinter> printer = connection_.GetPrinter(device); + std::unique_ptr<CupsPrinter> printer = connection_->GetPrinter(device); if (!printer) { LOG(WARNING) << "Could not initialize device"; return OnError(); @@ -390,8 +405,14 @@ PrintingContext::Result PrintingContextChromeos::NewDocument( in_print_job_ = true; std::string converted_name; - if (send_user_info_) - converted_name = base::UTF16ToUTF8(document_name); + if (send_user_info_) { + DCHECK(printer_); + if (IsUriInsecure(printer_->GetUri())) { + converted_name = kDocumentNamePlaceholder; + } else { + converted_name = base::UTF16ToUTF8(document_name); + } + } std::vector<cups_option_t> options; for (const ScopedCupsOption& option : cups_options_) { diff --git a/chromium/printing/printing_context_chromeos.h b/chromium/printing/printing_context_chromeos.h index c379796fd40..91498980135 100644 --- a/chromium/printing/printing_context_chromeos.h +++ b/chromium/printing/printing_context_chromeos.h @@ -20,6 +20,9 @@ namespace printing { class PRINTING_EXPORT PrintingContextChromeos : public PrintingContext { public: explicit PrintingContextChromeos(Delegate* delegate); + // For testing + PrintingContextChromeos(Delegate* delegate, + std::unique_ptr<CupsConnection> connection); PrintingContextChromeos(const PrintingContextChromeos&) = delete; PrintingContextChromeos& operator=(const PrintingContextChromeos&) = delete; ~PrintingContextChromeos() override; @@ -48,7 +51,7 @@ class PRINTING_EXPORT PrintingContextChromeos : public PrintingContext { // Lazily initializes |printer_|. Result InitializeDevice(const std::string& device); - CupsConnection connection_; + std::unique_ptr<CupsConnection> connection_; std::unique_ptr<CupsPrinter> printer_; std::vector<ScopedCupsOption> cups_options_; bool send_user_info_; diff --git a/chromium/printing/printing_context_chromeos_unittest.cc b/chromium/printing/printing_context_chromeos_unittest.cc index 90086b817e6..b417972dd4e 100644 --- a/chromium/printing/printing_context_chromeos_unittest.cc +++ b/chromium/printing/printing_context_chromeos_unittest.cc @@ -6,13 +6,27 @@ #include <string.h> +#include "base/strings/utf_string_conversions.h" #include "printing/backend/cups_ipp_constants.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace printing { namespace { +using ::testing::_; +using ::testing::ByMove; +using ::testing::DoAll; +using ::testing::Return; +using ::testing::SaveArg; + +constexpr char kPrinterName[] = "printer"; + +constexpr char kUsername[] = "test user"; + +constexpr char kDocumentName[] = "document name"; + const char* GetOptionValue(const std::vector<ScopedCupsOption>& options, const char* option_name) { DCHECK(option_name); @@ -29,17 +43,97 @@ const char* GetOptionValue(const std::vector<ScopedCupsOption>& options, return ret; } +class MockCupsPrinter : public CupsPrinter { + public: + MOCK_CONST_METHOD0(is_default, bool()); + MOCK_CONST_METHOD0(GetName, std::string()); + MOCK_CONST_METHOD0(GetMakeAndModel, std::string()); + MOCK_CONST_METHOD0(GetInfo, std::string()); + MOCK_CONST_METHOD0(GetUri, std::string()); + MOCK_CONST_METHOD0(EnsureDestInfo, bool()); + MOCK_CONST_METHOD1(ToPrinterInfo, bool(PrinterBasicInfo* basic_info)); + MOCK_METHOD4(CreateJob, + ipp_status_t(int* job_id, + const std::string& title, + const std::string& username, + const std::vector<cups_option_t>& options)); + MOCK_METHOD5(StartDocument, + bool(int job_id, + const std::string& docname, + bool last_doc, + const std::string& username, + const std::vector<cups_option_t>& options)); + MOCK_METHOD1(StreamData, bool(const std::vector<char>& buffer)); + MOCK_METHOD0(FinishDocument, bool()); + MOCK_METHOD2(CloseJob, ipp_status_t(int job_id, const std::string& username)); + MOCK_METHOD1(CancelJob, bool(int job_id)); + MOCK_METHOD1(GetMediaMarginsByName, + CupsMediaMargins(const std::string& media_id)); + + MOCK_CONST_METHOD1(GetSupportedOptionValues, + ipp_attribute_t*(const char* option_name)); + MOCK_CONST_METHOD1(GetSupportedOptionValueStrings, + std::vector<base::StringPiece>(const char* option_name)); + MOCK_CONST_METHOD1(GetDefaultOptionValue, + ipp_attribute_t*(const char* option_name)); + MOCK_CONST_METHOD2(CheckOptionSupported, + bool(const char* name, const char* value)); +}; + +class MockCupsConnection : public CupsConnection { + public: + MOCK_METHOD0(GetDests, std::vector<std::unique_ptr<CupsPrinter>>()); + MOCK_METHOD2(GetJobs, + bool(const std::vector<std::string>& printer_ids, + std::vector<QueueStatus>* jobs)); + MOCK_METHOD2(GetPrinterStatus, + bool(const std::string& printer_id, + PrinterStatus* printer_status)); + MOCK_CONST_METHOD0(server_name, std::string()); + MOCK_CONST_METHOD0(last_error, int()); + + MOCK_METHOD1(GetPrinter, + std::unique_ptr<CupsPrinter>(const std::string& printer_name)); +}; + class TestPrintSettings : public PrintSettings { public: TestPrintSettings() { set_duplex_mode(mojom::DuplexMode::kSimplex); } }; -class PrintingContextTest : public testing::Test { +class PrintingContextTest : public testing::Test, + public PrintingContext::Delegate { public: + void SetDefaultSettings(bool send_user_info, const std::string& uri) { + auto unique_connection = std::make_unique<MockCupsConnection>(); + auto* connection = unique_connection.get(); + auto unique_printer = std::make_unique<MockCupsPrinter>(); + printer_ = unique_printer.get(); + EXPECT_CALL(*printer_, GetUri()).WillRepeatedly(Return(uri)); + EXPECT_CALL(*connection, GetPrinter(kPrinterName)) + .WillOnce(Return(ByMove(std::move(unique_printer)))); + printing_context_ = std::make_unique<PrintingContextChromeos>( + this, std::move(unique_connection)); + auto settings = std::make_unique<PrintSettings>(); + settings->set_device_name(base::ASCIIToUTF16(kPrinterName)); + settings->set_send_user_info(send_user_info); + settings->set_duplex_mode(mojom::DuplexMode::kLongEdge); + settings->set_username(kUsername); + printing_context_->UpdatePrintSettingsFromPOD(std::move(settings)); + } + const char* Get(const char* name) const { return GetOptionValue(SettingsToCupsOptions(settings_), name); } + TestPrintSettings settings_; + + // PrintingContext::Delegate methods. + gfx::NativeView GetParentView() override { return nullptr; } + std::string GetAppLocale() override { return std::string(); } + + std::unique_ptr<PrintingContextChromeos> printing_context_; + MockCupsPrinter* printer_; }; TEST_F(PrintingContextTest, SettingsToCupsOptions_Color) { @@ -94,6 +188,81 @@ TEST_F(PrintingContextTest, SettingsToCupsOptions_Resolution) { EXPECT_STREQ("600x1200dpi", Get(kIppResolution)); } +TEST_F(PrintingContextTest, SettingsToCupsOptions_SendUserInfo_Secure) { + std::string uri = "ipps://test-uri"; + ipp_status_t status = ipp_status_t::IPP_STATUS_OK; + base::string16 document_name = base::ASCIIToUTF16(kDocumentName); + SetDefaultSettings(true, uri); + std::string create_job_document_name; + std::string create_job_username; + std::string start_document_document_name; + std::string start_document_username; + EXPECT_CALL(*printer_, CreateJob) + .WillOnce(DoAll(SaveArg<1>(&create_job_document_name), + SaveArg<2>(&create_job_username), Return(status))); + EXPECT_CALL(*printer_, StartDocument) + .WillOnce(DoAll(SaveArg<1>(&start_document_document_name), + SaveArg<3>(&start_document_username), Return(true))); + + printing_context_->NewDocument(document_name); + + EXPECT_EQ(create_job_document_name, kDocumentName); + EXPECT_EQ(start_document_document_name, kDocumentName); + EXPECT_EQ(create_job_username, kUsername); + EXPECT_EQ(start_document_username, kUsername); +} + +TEST_F(PrintingContextTest, SettingsToCupsOptions_SendUserInfo_Insecure) { + std::string uri = "ipp://test-uri"; + ipp_status_t status = ipp_status_t::IPP_STATUS_OK; + base::string16 document_name = base::ASCIIToUTF16(kDocumentName); + std::string default_username = "chronos"; + std::string default_document_name = "-"; + SetDefaultSettings(true, uri); + std::string create_job_document_name; + std::string create_job_username; + std::string start_document_document_name; + std::string start_document_username; + EXPECT_CALL(*printer_, CreateJob) + .WillOnce(DoAll(SaveArg<1>(&create_job_document_name), + SaveArg<2>(&create_job_username), Return(status))); + EXPECT_CALL(*printer_, StartDocument) + .WillOnce(DoAll(SaveArg<1>(&start_document_document_name), + SaveArg<3>(&start_document_username), Return(true))); + + printing_context_->NewDocument(document_name); + + EXPECT_EQ(create_job_document_name, default_document_name); + EXPECT_EQ(start_document_document_name, default_document_name); + EXPECT_EQ(create_job_username, default_username); + EXPECT_EQ(start_document_username, default_username); +} + +TEST_F(PrintingContextTest, SettingsToCupsOptions_DoNotSendUserInfo) { + std::string uri = "ipps://test-uri"; + ipp_status_t status = ipp_status_t::IPP_STATUS_OK; + base::string16 document_name = base::ASCIIToUTF16(kDocumentName); + std::string blank; + SetDefaultSettings(false, uri); + std::string create_job_document_name; + std::string create_job_username; + std::string start_document_document_name; + std::string start_document_username; + EXPECT_CALL(*printer_, CreateJob) + .WillOnce(DoAll(SaveArg<1>(&create_job_document_name), + SaveArg<2>(&create_job_username), Return(status))); + EXPECT_CALL(*printer_, StartDocument) + .WillOnce(DoAll(SaveArg<1>(&start_document_document_name), + SaveArg<3>(&start_document_username), Return(true))); + + printing_context_->NewDocument(document_name); + + EXPECT_EQ(create_job_document_name, blank); + EXPECT_EQ(start_document_document_name, blank); + EXPECT_EQ(create_job_username, blank); + EXPECT_EQ(start_document_username, blank); +} + } // namespace } // namespace printing diff --git a/chromium/printing/printing_context_system_dialog_win.cc b/chromium/printing/printing_context_system_dialog_win.cc index d3c8677f30d..fe7fc797504 100644 --- a/chromium/printing/printing_context_system_dialog_win.cc +++ b/chromium/printing/printing_context_system_dialog_win.cc @@ -8,6 +8,7 @@ #include "base/auto_reset.h" #include "base/stl_util.h" +#include "base/strings/utf_string_conversions.h" #include "base/task/current_thread.h" #include "printing/backend/win_helper.h" #include "printing/print_settings_initializer_win.h" @@ -133,7 +134,7 @@ bool PrintingContextSystemDialogWin::InitializeSettingsWithRanges( } settings_->set_ranges(ranges_vector); - settings_->set_device_name(new_device_name); + settings_->set_device_name(base::WideToUTF16(new_device_name)); settings_->set_selection_only(selection_only); PrintSettingsInitializerWin::InitPrintSettings(context(), dev_mode, settings_.get()); diff --git a/chromium/printing/printing_context_win.cc b/chromium/printing/printing_context_win.cc index 1489ac00f59..8ed97f412a4 100644 --- a/chromium/printing/printing_context_win.cc +++ b/chromium/printing/printing_context_win.cc @@ -60,7 +60,7 @@ PrintingContextWin::~PrintingContextWin() { ReleaseContext(); } -void PrintingContextWin::PrintDocument(const base::string16& device_name, +void PrintingContextWin::PrintDocument(const std::wstring& device_name, const MetafileSkia& metafile) { // TODO(crbug.com/1008222) NOTIMPLEMENTED(); @@ -78,7 +78,7 @@ PrintingContext::Result PrintingContextWin::UseDefaultSettings() { scoped_refptr<PrintBackend> backend = PrintBackend::CreateInstance(delegate_->GetAppLocale()); - base::string16 default_printer = + std::wstring default_printer = base::UTF8ToWide(backend->GetDefaultPrinterName()); if (!default_printer.empty()) { ScopedPrinterHandle printer; @@ -162,13 +162,14 @@ PrintingContext::Result PrintingContextWin::UpdatePrinterSettings( DCHECK(!external_preview) << "Not implemented"; ScopedPrinterHandle printer; - if (!printer.OpenPrinterWithName(settings_->device_name().c_str())) + if (!printer.OpenPrinterWithName(base::as_wcstr(settings_->device_name()))) return OnError(); // Make printer changes local to Chrome. // See MSDN documentation regarding DocumentProperties. std::unique_ptr<DEVMODE, base::FreeDeleter> scoped_dev_mode = - CreateDevModeWithColor(printer.Get(), settings_->device_name(), + CreateDevModeWithColor(printer.Get(), + base::UTF16ToWide(settings_->device_name()), settings_->color() != mojom::ColorModel::kGray); if (!scoped_dev_mode) return OnError(); @@ -247,7 +248,8 @@ PrintingContext::Result PrintingContextWin::UpdatePrinterSettings( ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; - return InitializeSettings(settings_->device_name(), scoped_dev_mode.get()); + return InitializeSettings(base::UTF16ToWide(settings_->device_name()), + scoped_dev_mode.get()); } PrintingContext::Result PrintingContextWin::InitWithSettingsForTest( @@ -258,13 +260,14 @@ PrintingContext::Result PrintingContextWin::InitWithSettingsForTest( // TODO(maruel): settings_.ToDEVMODE() ScopedPrinterHandle printer; - if (!printer.OpenPrinterWithName(settings_->device_name().c_str())) + if (!printer.OpenPrinterWithName(base::as_wcstr(settings_->device_name()))) return FAILED; std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode = CreateDevMode(printer.Get(), nullptr); - return InitializeSettings(settings_->device_name(), dev_mode.get()); + return InitializeSettings(base::UTF16ToWide(settings_->device_name()), + dev_mode.get()); } PrintingContext::Result PrintingContextWin::NewDocument( @@ -289,7 +292,7 @@ PrintingContext::Result PrintingContextWin::NewDocument( DCHECK(SimplifyDocumentTitle(document_name) == document_name); DOCINFO di = {sizeof(DOCINFO)}; - di.lpszDocName = document_name.c_str(); + di.lpszDocName = base::as_wcstr(document_name); // Is there a debug dump directory specified? If so, force to print to a file. if (PrintedDocument::HasDebugDumpPath()) { @@ -391,7 +394,7 @@ PrintingContext::Result PrintingContextWin::InitializeSettings( skia::InitializeDC(context_); DCHECK(!in_print_job_); - settings_->set_device_name(device_name); + settings_->set_device_name(base::WideToUTF16(device_name)); PrintSettingsInitializerWin::InitPrintSettings(context_, *dev_mode, settings_.get()); diff --git a/chromium/printing/printing_context_win.h b/chromium/printing/printing_context_win.h index ef051ce6f8e..245b0320880 100644 --- a/chromium/printing/printing_context_win.h +++ b/chromium/printing/printing_context_win.h @@ -24,7 +24,7 @@ class PRINTING_EXPORT PrintingContextWin : public PrintingContext { ~PrintingContextWin() override; // Prints the document contained in |metafile|. - void PrintDocument(const base::string16& device_name, + void PrintDocument(const std::wstring& device_name, const MetafileSkia& metafile); // Initializes with predefined settings. @@ -53,7 +53,7 @@ class PRINTING_EXPORT PrintingContextWin : public PrintingContext { // Reads the settings from the selected device context. Updates settings_ and // its margins. - virtual Result InitializeSettings(const base::string16& device_name, + virtual Result InitializeSettings(const std::wstring& device_name, DEVMODE* dev_mode); void set_context(HDC context) { context_ = context; } diff --git a/chromium/printing/printing_context_win_unittest.cc b/chromium/printing/printing_context_win_unittest.cc index 88ca0fcb8a1..36f06b5db94 100644 --- a/chromium/printing/printing_context_win_unittest.cc +++ b/chromium/printing/printing_context_win_unittest.cc @@ -10,6 +10,7 @@ #include <utility> #include "base/bind.h" +#include "base/strings/utf_string_conversions.h" #include "base/test/task_environment.h" #include "base/win/scoped_handle.h" #include "base/win/scoped_hdc.h" @@ -76,7 +77,7 @@ class MockPrintingContextWin : public PrintingContextSystemDialogWin { lppd->lpPageRanges[0].nFromPage = 1; lppd->lpPageRanges[0].nToPage = 5; - base::string16 printer_name = PrintingContextTest::GetDefaultPrinter(); + std::wstring printer_name = PrintingContextTest::GetDefaultPrinter(); ScopedPrinterHandle printer; if (!printer.OpenPrinterWithName(printer_name.c_str())) return E_FAIL; @@ -179,7 +180,7 @@ TEST_F(PrintingContextTest, Base) { return; auto settings = std::make_unique<PrintSettings>(); - settings->set_device_name(GetDefaultPrinter()); + settings->set_device_name(base::WideToUTF16(GetDefaultPrinter())); // Initialize it. PrintingContextWin context(this); EXPECT_EQ(PrintingContext::OK, diff --git a/chromium/printing/printing_features.cc b/chromium/printing/printing_features.cc index 7feeeba13f0..237a9d9f7fc 100644 --- a/chromium/printing/printing_features.cc +++ b/chromium/printing/printing_features.cc @@ -9,12 +9,6 @@ namespace printing { namespace features { -#if BUILDFLAG(IS_ASH) -// Enables Advanced PPD Attributes. -const base::Feature kAdvancedPpdAttributes{"AdvancedPpdAttributes", - base::FEATURE_ENABLED_BY_DEFAULT}; -#endif // BUILDFLAG(IS_ASH) - #if defined(OS_MAC) // Use the CUPS IPP printing backend instead of the original CUPS backend that // calls the deprecated PPD API. diff --git a/chromium/printing/printing_features.h b/chromium/printing/printing_features.h index 7dda9ddd52c..72b155a3e76 100644 --- a/chromium/printing/printing_features.h +++ b/chromium/printing/printing_features.h @@ -16,10 +16,6 @@ namespace features { // The following features are declared alphabetically. The features should be // documented with descriptions of their behaviors in the .cc file. -#if BUILDFLAG(IS_ASH) -PRINTING_EXPORT extern const base::Feature kAdvancedPpdAttributes; -#endif // BUILDFLAG(IS_ASH) - #if defined(OS_MAC) PRINTING_EXPORT extern const base::Feature kCupsIppPrintingBackend; #endif // defined(OS_MAC) |