diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-10-26 13:57:00 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-11-02 11:31:01 +0000 |
commit | 1943b3c2a1dcee36c233724fc4ee7613d71b9cf6 (patch) | |
tree | 8c1b5f12357025c197da5427ae02cfdc2f3570d6 /chromium/printing | |
parent | 21ba0c5d4bf8fba15dddd97cd693bad2358b77fd (diff) | |
download | qtwebengine-chromium-1943b3c2a1dcee36c233724fc4ee7613d71b9cf6.tar.gz |
BASELINE: Update Chromium to 94.0.4606.111
Change-Id: I924781584def20fc800bedf6ff41fdb96c438193
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/printing')
51 files changed, 1021 insertions, 285 deletions
diff --git a/chromium/printing/BUILD.gn b/chromium/printing/BUILD.gn index dee9ed88876..8149cab8239 100644 --- a/chromium/printing/BUILD.gn +++ b/chromium/printing/BUILD.gn @@ -260,6 +260,7 @@ test("printing_unittests") { "backend/print_backend_utils_unittest.cc", "backend/test_print_backend_unittest.cc", "metafile_skia_unittest.cc", + "mojom/printing_context_mojom_traits_unittest.cc", "nup_parameters_unittest.cc", "page_number_unittest.cc", "page_range_unittest.cc", @@ -284,6 +285,7 @@ test("printing_unittests") { "//printing/backend/mojom", "//printing/common", "//printing/mojom", + "//printing/mojom:printing_context", "//testing/gmock", "//testing/gtest", "//ui/base", diff --git a/chromium/printing/OWNERS b/chromium/printing/OWNERS index 6d26dfe6200..84eaf29afcb 100644 --- a/chromium/printing/OWNERS +++ b/chromium/printing/OWNERS @@ -2,5 +2,3 @@ set noparent rbpotter@chromium.org thestig@chromium.org weili@chromium.org - -per-file printing_context_android*=ctzsm@chromium.org diff --git a/chromium/printing/README.md b/chromium/printing/README.md new file mode 100644 index 00000000000..7106887f1b3 --- /dev/null +++ b/chromium/printing/README.md @@ -0,0 +1,4 @@ +`//printing` contains foundational code that is used for printing. It can depend +on other low-level directories like `//cc/paint` and `//ui`, but not higher +level code like `//components` or `//content`. Higher level printing code should +live in `//components/printing` or the embedder. diff --git a/chromium/printing/backend/PRESUBMIT.py b/chromium/printing/backend/PRESUBMIT.py index 303ef5da3db..4ef6bceedf3 100644 --- a/chromium/printing/backend/PRESUBMIT.py +++ b/chromium/printing/backend/PRESUBMIT.py @@ -9,6 +9,8 @@ See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for more details about the presubmit API. """ +USE_PYTHON3 = True + def _CheckForStringViewFromNullableIppApi(input_api, output_api): """ Looks for all affected lines in CL where one constructs either diff --git a/chromium/printing/backend/cups_connection.cc b/chromium/printing/backend/cups_connection.cc index ac31022183e..bd8f0033eb1 100644 --- a/chromium/printing/backend/cups_connection.cc +++ b/chromium/printing/backend/cups_connection.cc @@ -11,14 +11,13 @@ #include <utility> #include "base/logging.h" +#include "printing/backend/cups_helper.h" #include "printing/backend/cups_jobs.h" namespace printing { namespace { -constexpr int kTimeoutMs = 3000; - // The number of jobs we'll retrieve for a queue. We expect a user to queue at // most 10 jobs per printer. If they queue more, they won't receive updates for // the 11th job until one finishes. @@ -80,38 +79,31 @@ class CupsConnectionImpl : public CupsConnection { ~CupsConnectionImpl() override {} - std::vector<std::unique_ptr<CupsPrinter>> GetDests() override { + bool GetDests(std::vector<std::unique_ptr<CupsPrinter>>& printers) override { + printers.clear(); if (!Connect()) { - LOG(WARNING) << "CUPS connection failed"; - return std::vector<std::unique_ptr<CupsPrinter>>(); + LOG(WARNING) << "CUPS connection failed: "; + return false; } - - // 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, + cupsEnumDests(CUPS_DEST_FLAGS_NONE, kCupsTimeoutMs, /*cancel=*/nullptr, - /*type=*/CUPS_PRINTER_LOCAL, kMask, + /*type=*/CUPS_PRINTER_LOCAL, kDestinationsFilterMask, &DestinationEnumerator::cups_callback, &enumerator); if (!success) { LOG(WARNING) << "Enumerating printers failed"; - return std::vector<std::unique_ptr<CupsPrinter>>(); + return false; } 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))); } - return printers; + return true; } std::unique_ptr<CupsPrinter> GetPrinter(const std::string& name) override { @@ -199,7 +191,7 @@ class CupsConnectionImpl : public CupsConnection { cups_http_.reset(httpConnect2(host.c_str(), port, nullptr, AF_UNSPEC, cups_encryption_, blocking_ ? 1 : 0, - kTimeoutMs, nullptr)); + kCupsTimeoutMs, nullptr)); return !!cups_http_; } diff --git a/chromium/printing/backend/cups_connection.h b/chromium/printing/backend/cups_connection.h index eb455234cc3..fc0960a7448 100644 --- a/chromium/printing/backend/cups_connection.h +++ b/chromium/printing/backend/cups_connection.h @@ -40,8 +40,11 @@ class COMPONENT_EXPORT(PRINT_BACKEND) CupsConnection { http_encryption_t encryption, bool blocking); - // Returns a vector of all the printers configure on the CUPS server. - virtual std::vector<std::unique_ptr<CupsPrinter>> GetDests() = 0; + // Obtain a vector of all the printers configure on the CUPS server. Returns + // true if the list of printers was obtained, and false if an error was + // encountered during the query. + virtual bool GetDests( + std::vector<std::unique_ptr<CupsPrinter>>& printers) = 0; // Returns a printer for `printer_name` from the connected server. virtual std::unique_ptr<CupsPrinter> GetPrinter( diff --git a/chromium/printing/backend/cups_helper.h b/chromium/printing/backend/cups_helper.h index 3b6fb684fac..e28b48c6b90 100644 --- a/chromium/printing/backend/cups_helper.h +++ b/chromium/printing/backend/cups_helper.h @@ -17,6 +17,18 @@ namespace printing { struct PrinterSemanticCapsAndDefaults; +// Time willing to wait for individual CUPS calls to complete, such as +// establishing a new connection or enumerating list of printers. +constexpr int kCupsTimeoutMs = 3000; + +// Exclude fax and scanner devices when enumerating printers. +// Also exclude discovered printers that have not been added locally. +// 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) +constexpr cups_ptype_t kDestinationsFilterMask = + CUPS_PRINTER_FAX | CUPS_PRINTER_SCANNER | CUPS_PRINTER_DISCOVERED; + // Helper wrapper around http_t structure, with connection and cleanup // functionality. class COMPONENT_EXPORT(PRINT_BACKEND) HttpConnectionCUPS { diff --git a/chromium/printing/backend/mojom/print_backend.mojom b/chromium/printing/backend/mojom/print_backend.mojom index 508e8778426..670327fb771 100644 --- a/chromium/printing/backend/mojom/print_backend.mojom +++ b/chromium/printing/backend/mojom/print_backend.mojom @@ -8,6 +8,8 @@ import "printing/mojom/print.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; // Basic information for a specific printer. +// Corresponds to `printing::PrinterBasicInfo` in +// printing/backend/print_backend.h. struct PrinterBasicInfo { string printer_name; string display_name; @@ -18,6 +20,8 @@ struct PrinterBasicInfo { }; // Paper used by printer semantic capabilities and defaults. +// Corresponds to `printing::PrinterSemanticCapsAndDefaults::Paper` in +// printing/backend/print_backend.h. [Stable] struct Paper { string display_name; @@ -26,6 +30,9 @@ struct Paper { }; // An advanced capability value for ChromeOS printing. +// Paper used by printer semantic capabilities and defaults. +// Corresponds to `printing::AdvancedCapabilityValue` in +// printing/backend/print_backend.h. [Stable, EnableIf=is_chromeos] struct AdvancedCapabilityValue { string name; @@ -33,6 +40,8 @@ struct AdvancedCapabilityValue { }; // The type of the values for advanced capabilities. +// Corresponds to `printing::AdvancedCapability::Type` in +// printing/backend/print_backend.h. [Stable, Extensible, EnableIf=is_chromeos] enum AdvancedCapabilityType { [Default] kString, @@ -42,6 +51,8 @@ enum AdvancedCapabilityType { }; // An advanced capability for ChromeOS printing. +// Corresponds to `printing::AdvancedCapability` in +// printing/backend/print_backend.h. [Stable, EnableIf=is_chromeos] struct AdvancedCapability { string name; @@ -52,6 +63,8 @@ struct AdvancedCapability { }; // The semantic capabilities and defaults used for a printer. +// Corresponds to `printing::PrinterSemanticCapsAndDefaults` in +// printing/backend/print_backend.h. [Stable] struct PrinterSemanticCapsAndDefaults { bool collate_capable = false; @@ -63,10 +76,10 @@ struct PrinterSemanticCapsAndDefaults { bool color_default = false; ColorModel color_model = kUnknownColorModel; ColorModel bw_model = kUnknownColorModel; - array<Paper> papers; + array<Paper> papers; // Empty and duplicates allowed. array<Paper> user_defined_papers; Paper default_paper; - array<gfx.mojom.Size> dpis; + array<gfx.mojom.Size> dpis; // Duplicates allowed. gfx.mojom.Size default_dpi; [EnableIf=is_chromeos] diff --git a/chromium/printing/backend/mojom/print_backend_mojom_traits.cc b/chromium/printing/backend/mojom/print_backend_mojom_traits.cc index 52ca698ec44..c1d1d31da03 100644 --- a/chromium/printing/backend/mojom/print_backend_mojom_traits.cc +++ b/chromium/printing/backend/mojom/print_backend_mojom_traits.cc @@ -215,13 +215,7 @@ bool StructTraits<printing::mojom::PrinterSemanticCapsAndDefaultsDataView, return false; } - // There should be at least one item in `papers`. - if (out->papers.empty()) { - DLOG(ERROR) << "The available papers must not be empty."; - return false; - } - - // There should not be duplicates in any of the arrays. + // There should not be duplicates in certain arrays. DuplicateChecker<printing::mojom::DuplexMode> duplex_modes_dup_checker; if (duplex_modes_dup_checker.HasDuplicates(out->duplex_modes)) { DLOG(ERROR) << "Duplicate duplex_modes detected."; @@ -229,25 +223,12 @@ bool StructTraits<printing::mojom::PrinterSemanticCapsAndDefaultsDataView, } DuplicateChecker<printing::PrinterSemanticCapsAndDefaults::Paper> - papers_dup_checker; - if (papers_dup_checker.HasDuplicates(out->papers)) { - DLOG(ERROR) << "Duplicate papers detected."; - return false; - } - - DuplicateChecker<printing::PrinterSemanticCapsAndDefaults::Paper> user_defined_papers_dup_checker; if (user_defined_papers_dup_checker.HasDuplicates(out->user_defined_papers)) { DLOG(ERROR) << "Duplicate user_defined_papers detected."; return false; } - DuplicateChecker<gfx::Size> dpis_dup_checker; - if (dpis_dup_checker.HasDuplicates(out->dpis)) { - DLOG(ERROR) << "Duplicate dpis detected."; - return false; - } - #if defined(OS_CHROMEOS) DuplicateChecker<printing::AdvancedCapability> advanced_capabilities_dup_checker; 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 ad487843da8..dd2da6f252a 100644 --- a/chromium/printing/backend/mojom/print_backend_mojom_traits_unittest.cc +++ b/chromium/printing/backend/mojom/print_backend_mojom_traits_unittest.cc @@ -275,11 +275,15 @@ TEST(PrintBackendMojomTraitsTest, GenerateSamplePrinterSemanticCapsAndDefaults(); PrinterSemanticCapsAndDefaults output; - // Override sample with empty `papers`, which is not allowed. + // Override sample with empty `papers`. This is known to be possible, seen + // with Epson PX660 series driver. + const PrinterSemanticCapsAndDefaults::Papers kEmptyPapers; input.papers.clear(); - EXPECT_FALSE(mojo::test::SerializeAndDeserialize< - mojom::PrinterSemanticCapsAndDefaults>(input, output)); + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + mojom::PrinterSemanticCapsAndDefaults>(input, output)); + + EXPECT_EQ(kEmptyPapers, output.papers); } TEST( @@ -297,27 +301,12 @@ TEST( EXPECT_FALSE(mojo::test::SerializeAndDeserialize< mojom::PrinterSemanticCapsAndDefaults>(input, output)); - // Use a paper with same name but different size. - PrinterSemanticCapsAndDefaults::Paper paper_a4_prime = kPaperA4; - paper_a4_prime.size_um = kPaperLetter.size_um; - input = GenerateSamplePrinterSemanticCapsAndDefaults(); - input.papers = {kPaperA4, kPaperLetter, kPaperLedger, paper_a4_prime}; - - EXPECT_FALSE(mojo::test::SerializeAndDeserialize< - mojom::PrinterSemanticCapsAndDefaults>(input, output)); - input = GenerateSamplePrinterSemanticCapsAndDefaults(); input.user_defined_papers = {kPaperLetter, kPaperLetter}; EXPECT_FALSE(mojo::test::SerializeAndDeserialize< mojom::PrinterSemanticCapsAndDefaults>(input, output)); - input = GenerateSamplePrinterSemanticCapsAndDefaults(); - input.dpis = {kDpi600, kDpi600, kDpi1200}; - - EXPECT_FALSE(mojo::test::SerializeAndDeserialize< - mojom::PrinterSemanticCapsAndDefaults>(input, output)); - #if defined(OS_CHROMEOS) // Use an advanced capability with same name but different other fields. AdvancedCapability advanced_capability1_prime = kAdvancedCapability1; @@ -332,4 +321,37 @@ TEST( #endif } +TEST( + PrintBackendMojomTraitsTest, + TestSerializeAndDeserializePrinterSemanticCapsAndDefaultsAllowedDuplicatesInArrays) { + PrinterSemanticCapsAndDefaults input = + GenerateSamplePrinterSemanticCapsAndDefaults(); + PrinterSemanticCapsAndDefaults output; + + // Override sample with arrays containing duplicates where it is allowed. + // Duplicate DPIs are known to be possible, seen with the Kyocera KX driver. + const std::vector<gfx::Size> kDuplicateDpis{kDpi600, kDpi600, kDpi1200}; + input.dpis = kDuplicateDpis; + + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + mojom::PrinterSemanticCapsAndDefaults>(input, output)); + + EXPECT_EQ(kDuplicateDpis, output.dpis); + + // Duplicate papers are known to be possible, seen with the Konica Minolta + // 4750 Series PS driver. + // Use a paper with same name but different size. + PrinterSemanticCapsAndDefaults::Paper paper_a4_prime = kPaperA4; + paper_a4_prime.size_um = kPaperLetter.size_um; + input = GenerateSamplePrinterSemanticCapsAndDefaults(); + const PrinterSemanticCapsAndDefaults::Papers kDuplicatePapers{ + kPaperA4, kPaperLetter, kPaperLedger, paper_a4_prime}; + input.papers = kDuplicatePapers; + + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + mojom::PrinterSemanticCapsAndDefaults>(input, output)); + + EXPECT_EQ(kDuplicatePapers, output.papers); +} + } // namespace printing diff --git a/chromium/printing/backend/print_backend.h b/chromium/printing/backend/print_backend.h index 52662be431c..1565c60b351 100644 --- a/chromium/printing/backend/print_backend.h +++ b/chromium/printing/backend/print_backend.h @@ -181,8 +181,12 @@ class COMPONENT_EXPORT(PRINT_BACKEND) PrintBackend // failure in generating the list. virtual mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) = 0; - // Gets the default printer name. Empty string if no default printer. - virtual std::string GetDefaultPrinterName() = 0; + // Gets the default printer name. If there is no default printer then it + // will still return success and `default_printer` will be empty. The result + // code will return one of the error result codes when there is a failure in + // trying to get the default printer. + virtual mojom::ResultCode GetDefaultPrinterName( + std::string& default_printer) = 0; // Gets the basic printer info for a specific printer. Implementations must // check `printer_name` validity in the same way as IsValidPrinter(). diff --git a/chromium/printing/backend/print_backend_chromeos.cc b/chromium/printing/backend/print_backend_chromeos.cc index e122459bb4c..974fc207f4c 100644 --- a/chromium/printing/backend/print_backend_chromeos.cc +++ b/chromium/printing/backend/print_backend_chromeos.cc @@ -24,7 +24,8 @@ class PrintBackendChromeOS : public PrintBackend { // PrintBackend implementation. mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; - std::string GetDefaultPrinterName() override; + mojom::ResultCode GetDefaultPrinterName( + std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo( const std::string& printer_name, PrinterBasicInfo* printer_info) override; @@ -75,8 +76,10 @@ std::string PrintBackendChromeOS::GetPrinterDriverInfo( return std::string(); } -std::string PrintBackendChromeOS::GetDefaultPrinterName() { - return std::string(); +mojom::ResultCode PrintBackendChromeOS::GetDefaultPrinterName( + std::string& default_printer) { + default_printer = std::string(); + return mojom::ResultCode::kSuccess; } bool PrintBackendChromeOS::IsValidPrinter(const std::string& printer_name) { diff --git a/chromium/printing/backend/print_backend_cups.cc b/chromium/printing/backend/print_backend_cups.cc index dc0baf8951c..4148bd71f45 100644 --- a/chromium/printing/backend/print_backend_cups.cc +++ b/chromium/printing/backend/print_backend_cups.cc @@ -4,6 +4,7 @@ #include "printing/backend/print_backend_cups.h" +#include <cups/cups.h> #include <cups/ppd.h> #include <dlfcn.h> #include <errno.h> @@ -35,6 +36,27 @@ namespace printing { +namespace { + +struct CupsDestsData { + int num_dests; + cups_dest_t* dests; +}; + +int CaptureCupsDestCallback(void* data, unsigned flags, cups_dest_t* dest) { + CupsDestsData* dests_data = reinterpret_cast<CupsDestsData*>(data); + if (flags & CUPS_DEST_FLAGS_REMOVED) { + dests_data->num_dests = cupsRemoveDest( + dest->name, dest->instance, dests_data->num_dests, &dests_data->dests); + } else { + dests_data->num_dests = + cupsCopyDest(dest, dests_data->num_dests, &dests_data->dests); + } + return 1; // Keep going. +} + +} // namespace + PrintBackendCUPS::PrintBackendCUPS(const GURL& print_server_url, http_encryption_t encryption, bool blocking, @@ -55,14 +77,7 @@ mojom::ResultCode PrintBackendCUPS::PrinterBasicInfoFromCUPS( if (type_str) { cups_ptype_t type; if (base::StringToUint(type_str, &type)) { - // Exclude fax and scanner devices. - // Also exclude discovered printers that have not been added locally. - // 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) - constexpr cups_ptype_t kMask = - CUPS_PRINTER_FAX | CUPS_PRINTER_SCANNER | CUPS_PRINTER_DISCOVERED; - if (type & kMask) + if (type & kDestinationsFilterMask) return mojom::ResultCode::kFailed; } } @@ -125,15 +140,39 @@ mojom::ResultCode PrintBackendCUPS::EnumeratePrinters( DCHECK(printer_list); printer_list->clear(); - cups_dest_t* destinations = nullptr; - int num_dests = GetDests(&destinations); - DCHECK_GE(num_dests, 0); - if (!num_dests) { + // If possible prefer to use cupsEnumDests() over GetDests(), because the + // latter has been found to filter out some destination values if a device + // reports multiple times (crbug.com/1209175), which can lead to destinations + // not showing as available. Using cupsEnumDests() allows us to do our own + // filtering should any duplicates occur. + CupsDestsData dests_data = {0, nullptr}; + ipp_status_t last_error = IPP_STATUS_OK; + if (print_server_url_.is_empty()) { + VLOG(1) << "CUPS: using cupsEnumDests to enumerate printers"; + if (!cupsEnumDests(CUPS_DEST_FLAGS_NONE, kCupsTimeoutMs, + /*cancel=*/nullptr, + /*type=*/CUPS_PRINTER_LOCAL, kDestinationsFilterMask, + CaptureCupsDestCallback, &dests_data)) { + // Free any allocations and reset data, and then fall through to common + // error handling below. + last_error = cupsLastError(); + cupsFreeDests(dests_data.num_dests, dests_data.dests); + dests_data.num_dests = 0; + dests_data.dests = nullptr; + } + } else { + VLOG(1) << "CUPS: using cupsGetDests2 to enumerate printers"; + dests_data.num_dests = GetDests(&dests_data.dests); + if (!dests_data.num_dests) + last_error = cupsLastError(); + } + + DCHECK_GE(dests_data.num_dests, 0); + if (!dests_data.num_dests) { // No destinations could mean the operation failed or that there are simply // no printer drivers installed. Rely upon CUPS error code to distinguish // between these. - DCHECK(!destinations); - const ipp_status_t last_error = cupsLastError(); + DCHECK(!dests_data.dests); if (last_error != IPP_STATUS_ERROR_NOT_FOUND) { VLOG(1) << "CUPS: Error getting printers from CUPS server" << ", server: " << print_server_url_ @@ -145,8 +184,9 @@ mojom::ResultCode PrintBackendCUPS::EnumeratePrinters( return mojom::ResultCode::kSuccess; } - for (int printer_index = 0; printer_index < num_dests; ++printer_index) { - const cups_dest_t& printer = destinations[printer_index]; + for (int printer_index = 0; printer_index < dests_data.num_dests; + ++printer_index) { + const cups_dest_t& printer = dests_data.dests[printer_index]; PrinterBasicInfo printer_info; if (PrinterBasicInfoFromCUPS(printer, &printer_info) == @@ -155,21 +195,33 @@ mojom::ResultCode PrintBackendCUPS::EnumeratePrinters( } } - cupsFreeDests(num_dests, destinations); + cupsFreeDests(dests_data.num_dests, dests_data.dests); VLOG(1) << "CUPS: Enumerated printers, server: " << print_server_url_ << ", # of printers: " << printer_list->size(); return mojom::ResultCode::kSuccess; } -std::string PrintBackendCUPS::GetDefaultPrinterName() { +mojom::ResultCode PrintBackendCUPS::GetDefaultPrinterName( + std::string& default_printer) { // Not using cupsGetDefault() because it lies about the default printer. cups_dest_t* dests; int num_dests = GetDests(&dests); cups_dest_t* dest = cupsGetDest(nullptr, nullptr, num_dests, dests); - std::string name = dest ? std::string(dest->name) : std::string(); + mojom::ResultCode result = mojom::ResultCode::kSuccess; + if (dest) { + default_printer = std::string(dest->name); + } else if (cupsLastError() <= IPP_OK_EVENTS_COMPLETE) { + // No default printer found. + default_printer.clear(); + } else { + LOG(ERROR) << "CUPS: Error getting default printer: " + << cupsLastErrorString(); + result = mojom::ResultCode::kFailed; + } + cupsFreeDests(num_dests, dests); - return name; + return result; } mojom::ResultCode PrintBackendCUPS::GetPrinterBasicInfo( diff --git a/chromium/printing/backend/print_backend_cups.h b/chromium/printing/backend/print_backend_cups.h index 3d601702ad2..71395cfa2c7 100644 --- a/chromium/printing/backend/print_backend_cups.h +++ b/chromium/printing/backend/print_backend_cups.h @@ -43,7 +43,8 @@ class PrintBackendCUPS : public PrintBackend { // PrintBackend implementation. mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; - std::string GetDefaultPrinterName() override; + mojom::ResultCode GetDefaultPrinterName( + std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo( const std::string& printer_name, PrinterBasicInfo* printer_info) override; diff --git a/chromium/printing/backend/print_backend_cups_ipp.cc b/chromium/printing/backend/print_backend_cups_ipp.cc index 4f7a219ecb0..10d8ccb77c0 100644 --- a/chromium/printing/backend/print_backend_cups_ipp.cc +++ b/chromium/printing/backend/print_backend_cups_ipp.cc @@ -34,23 +34,13 @@ mojom::ResultCode PrintBackendCupsIpp::EnumeratePrinters( DCHECK(printer_list); printer_list->clear(); - std::vector<std::unique_ptr<CupsPrinter>> printers = - cups_connection_->GetDests(); - if (printers.empty()) { - // No destinations could mean the operation failed or that there are simply - // no printer drivers installed. Rely upon CUPS error code to distinguish - // between these. - const int last_error = cups_connection_->last_error(); - if (last_error != IPP_STATUS_ERROR_NOT_FOUND) { - LOG(WARNING) << "CUPS: Error getting printers from CUPS server" - << ", server: " << cups_connection_->server_name() - << ", error: " << last_error << " - " - << cups_connection_->last_error_message(); - return mojom::ResultCode::kFailed; - } - VLOG(1) << "CUPS: No printers found for CUPS server: " - << cups_connection_->server_name(); - return mojom::ResultCode::kSuccess; + std::vector<std::unique_ptr<CupsPrinter>> printers; + if (!cups_connection_->GetDests(printers)) { + LOG(WARNING) << "CUPS: Error getting printers from CUPS server" + << ", server: " << cups_connection_->server_name() + << ", error: " << cups_connection_->last_error() << " - " + << cups_connection_->last_error_message(); + return mojom::ResultCode::kFailed; } VLOG(1) << "CUPS: found " << printers.size() @@ -65,16 +55,24 @@ mojom::ResultCode PrintBackendCupsIpp::EnumeratePrinters( return mojom::ResultCode::kSuccess; } -std::string PrintBackendCupsIpp::GetDefaultPrinterName() { - std::vector<std::unique_ptr<CupsPrinter>> printers = - cups_connection_->GetDests(); +mojom::ResultCode PrintBackendCupsIpp::GetDefaultPrinterName( + std::string& default_printer) { + std::vector<std::unique_ptr<CupsPrinter>> printers; + if (!cups_connection_->GetDests(printers)) { + LOG(ERROR) << "CUPS: unable to get default printer: " + << cupsLastErrorString(); + return mojom::ResultCode::kFailed; + } + for (const auto& printer : printers) { if (printer->is_default()) { - return printer->GetName(); + default_printer = printer->GetName(); + return mojom::ResultCode::kSuccess; } } - return std::string(); + default_printer = std::string(); + return mojom::ResultCode::kSuccess; } mojom::ResultCode PrintBackendCupsIpp::GetPrinterBasicInfo( diff --git a/chromium/printing/backend/print_backend_cups_ipp.h b/chromium/printing/backend/print_backend_cups_ipp.h index 7da7a886a96..ceb021a8698 100644 --- a/chromium/printing/backend/print_backend_cups_ipp.h +++ b/chromium/printing/backend/print_backend_cups_ipp.h @@ -24,7 +24,8 @@ class PrintBackendCupsIpp : public PrintBackend { // PrintBackend implementation. mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; - std::string GetDefaultPrinterName() override; + mojom::ResultCode GetDefaultPrinterName( + std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo( const std::string& printer_name, PrinterBasicInfo* printer_info) override; diff --git a/chromium/printing/backend/print_backend_dummy.cc b/chromium/printing/backend/print_backend_dummy.cc index fefe3bf72c4..f888d92925f 100644 --- a/chromium/printing/backend/print_backend_dummy.cc +++ b/chromium/printing/backend/print_backend_dummy.cc @@ -24,7 +24,11 @@ class DummyPrintBackend : public PrintBackend { return mojom::ResultCode::kFailed; } - std::string GetDefaultPrinterName() override { return std::string(); } + mojom::ResultCode GetDefaultPrinterName( + std::string& default_printer) override { + default_printer = std::string(); + return mojom::ResultCode::kSuccess; + } mojom::ResultCode GetPrinterBasicInfo( const std::string& printer_name, diff --git a/chromium/printing/backend/print_backend_win.cc b/chromium/printing/backend/print_backend_win.cc index 102769be663..92844c63e72 100644 --- a/chromium/printing/backend/print_backend_win.cc +++ b/chromium/printing/backend/print_backend_win.cc @@ -186,7 +186,8 @@ class PrintBackendWin : public PrintBackend { // PrintBackend implementation. mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; - std::string GetDefaultPrinterName() override; + mojom::ResultCode GetDefaultPrinterName( + std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo( const std::string& printer_name, PrinterBasicInfo* printer_info) override; @@ -215,7 +216,12 @@ mojom::ResultCode PrintBackendWin::EnumeratePrinters( // No bytes needed could mean the operation failed or that there are simply // no printer drivers installed. Rely upon system error code to // distinguish between these. - return GetResultCodeFromSystemErrorCode(logging::GetLastSystemErrorCode()); + logging::SystemErrorCode code = logging::GetLastSystemErrorCode(); + if (code != ERROR_SUCCESS) { + LOG(ERROR) << "Error enumerating printers: " + << logging::SystemErrorCodeToString(code); + } + return GetResultCodeFromSystemErrorCode(code); } auto printer_info_buffer = std::make_unique<BYTE[]>(bytes_needed); @@ -226,7 +232,11 @@ mojom::ResultCode PrintBackendWin::EnumeratePrinters( return GetResultCodeFromSystemErrorCode(logging::GetLastSystemErrorCode()); } - std::string default_printer = GetDefaultPrinterName(); + // No need to worry about a query failure for `GetDefaultPrinterName()` here, + // that would mean we can just treat it as there being no default printer. + std::string default_printer; + GetDefaultPrinterName(default_printer); + PRINTER_INFO_4* printer_info = reinterpret_cast<PRINTER_INFO_4*>(printer_info_buffer.get()); for (DWORD index = 0; index < count_returned; index++) { @@ -241,15 +251,20 @@ mojom::ResultCode PrintBackendWin::EnumeratePrinters( return mojom::ResultCode::kSuccess; } -std::string PrintBackendWin::GetDefaultPrinterName() { +mojom::ResultCode PrintBackendWin::GetDefaultPrinterName( + std::string& default_printer) { DWORD size = MAX_PATH; TCHAR default_printer_name[MAX_PATH]; - std::string ret; base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); - if (::GetDefaultPrinter(default_printer_name, &size)) - ret = base::WideToUTF8(default_printer_name); - return ret; + if (!::GetDefaultPrinter(default_printer_name, &size)) { + LOG(ERROR) << "Error getting default printer: " + << logging::SystemErrorCodeToString( + logging::GetLastSystemErrorCode()); + return mojom::ResultCode::kFailed; + } + default_printer = base::WideToUTF8(default_printer_name); + return mojom::ResultCode::kSuccess; } mojom::ResultCode PrintBackendWin::GetPrinterBasicInfo( @@ -265,8 +280,14 @@ mojom::ResultCode PrintBackendWin::GetPrinterBasicInfo( return mojom::ResultCode::kFailed; } - std::string default_printer = GetDefaultPrinterName(); - printer_info->is_default = (printer_info->printer_name == default_printer); + std::string default_printer; + mojom::ResultCode result = GetDefaultPrinterName(default_printer); + if (result != mojom::ResultCode::kSuccess) { + // Query failure means we can treat this printer as not the default. + printer_info->is_default = false; + } else { + printer_info->is_default = (printer_info->printer_name == default_printer); + } return mojom::ResultCode::kSuccess; } diff --git a/chromium/printing/backend/printing_restrictions.h b/chromium/printing/backend/printing_restrictions.h index 34065748525..8e877bfd7da 100644 --- a/chromium/printing/backend/printing_restrictions.h +++ b/chromium/printing/backend/printing_restrictions.h @@ -16,11 +16,11 @@ namespace printing { #if defined(OS_CHROMEOS) // Allowed printing modes as a bitmask. -// This is used in pref file and should never change. +// This is used in pref file and crosapi. It should never change. using ColorModeRestriction = mojom::ColorModeRestriction; // Allowed duplex modes as a bitmask. -// This is used in pref file and should never change. +// This is used in pref file and crosapi. It should never change. using DuplexModeRestriction = mojom::DuplexModeRestriction; // Allowed PIN printing modes. diff --git a/chromium/printing/backend/test_print_backend.cc b/chromium/printing/backend/test_print_backend.cc index 61c582d5a79..4f0d68053ab 100644 --- a/chromium/printing/backend/test_print_backend.cc +++ b/chromium/printing/backend/test_print_backend.cc @@ -61,8 +61,10 @@ mojom::ResultCode TestPrintBackend::EnumeratePrinters( return mojom::ResultCode::kSuccess; } -std::string TestPrintBackend::GetDefaultPrinterName() { - return default_printer_name_; +mojom::ResultCode TestPrintBackend::GetDefaultPrinterName( + std::string& default_printer) { + default_printer = default_printer_name_; + return mojom::ResultCode::kSuccess; } mojom::ResultCode TestPrintBackend::GetPrinterBasicInfo( @@ -151,6 +153,14 @@ void TestPrintBackend::AddValidPrinter( /*blocked_by_permissions=*/false); } +void TestPrintBackend::AddInvalidDataPrinter(const std::string& printer_name) { + // The blank fields in default `PrinterBasicInfo` cause Mojom data validation + // errors. + AddPrinter(printer_name, std::make_unique<PrinterSemanticCapsAndDefaults>(), + std::make_unique<PrinterBasicInfo>(), + /*blocked_by_permissions=*/false); +} + void TestPrintBackend::AddAccessDeniedPrinter(const std::string& printer_name) { AddPrinter(printer_name, /*caps=*/nullptr, /*info=*/nullptr, /*blocked_by_permissions=*/true); diff --git a/chromium/printing/backend/test_print_backend.h b/chromium/printing/backend/test_print_backend.h index b8b910d3ce4..f9dae874006 100644 --- a/chromium/printing/backend/test_print_backend.h +++ b/chromium/printing/backend/test_print_backend.h @@ -22,7 +22,8 @@ class TestPrintBackend : public PrintBackend { // PrintBackend overrides mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; - std::string GetDefaultPrinterName() override; + mojom::ResultCode GetDefaultPrinterName( + std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo( const std::string& printer_name, PrinterBasicInfo* printer_info) override; @@ -53,6 +54,9 @@ class TestPrintBackend : public PrintBackend { std::unique_ptr<PrinterSemanticCapsAndDefaults> caps, std::unique_ptr<PrinterBasicInfo> info); + // Adds a printer which will cause a Mojom data validation error. + void AddInvalidDataPrinter(const std::string& printer_name); + // Adds a printer which will fail with an access-denied permission error for // calls specific to a particular `printer_name`. void AddAccessDeniedPrinter(const std::string& printer_name); diff --git a/chromium/printing/backend/test_print_backend_unittest.cc b/chromium/printing/backend/test_print_backend_unittest.cc index f9e5ba826a7..df18b8711db 100644 --- a/chromium/printing/backend/test_print_backend_unittest.cc +++ b/chromium/printing/backend/test_print_backend_unittest.cc @@ -11,8 +11,9 @@ #include <vector> #include "base/memory/scoped_refptr.h" -#include "base/stl_util.h" #include "base/test/gtest_util.h" +#include "mojo/public/cpp/test_support/test_utils.h" +#include "printing/backend/mojom/print_backend.mojom.h" #include "printing/backend/print_backend.h" #include "printing/mojom/print.mojom.h" #include "testing/gmock/include/gmock/gmock-matchers.h" @@ -28,6 +29,7 @@ constexpr char kAlternatePrinterName[] = "alternate-test-printer"; constexpr char kNullDataPrinterName[] = "null-data-test-printer"; constexpr char kAccessDeniedPrinterName[] = "access-denied-test-printer"; constexpr char kInvalidPrinterName[] = "invalid-test-printer"; +constexpr char kInvalidDataPrinterName[] = "invalid-data-test-printer"; constexpr int kDefaultPrinterStatus = 0; constexpr int kAlternatePrinterStatus = 1; @@ -78,6 +80,10 @@ class TestPrintBackendTest : public testing::Test { /*info=*/nullptr); } + void AddInvalidDataPrinter() { + test_print_backend_->AddInvalidDataPrinter(kInvalidDataPrinterName); + } + void AddAccessDeniedPrinter() { test_print_backend_->AddAccessDeniedPrinter(kAccessDeniedPrinterName); } @@ -111,16 +117,24 @@ TEST_F(TestPrintBackendTest, EnumeratePrintersNoneFound) { } TEST_F(TestPrintBackendTest, DefaultPrinterName) { + std::string default_printer; + // If no printers added then no default. - EXPECT_TRUE(GetPrintBackend()->GetDefaultPrinterName().empty()); + ASSERT_EQ(GetPrintBackend()->GetDefaultPrinterName(default_printer), + mojom::ResultCode::kSuccess); + EXPECT_TRUE(default_printer.empty()); // Once printers are available, should be a default. AddPrinters(); - EXPECT_EQ(GetPrintBackend()->GetDefaultPrinterName(), kDefaultPrinterName); + ASSERT_EQ(GetPrintBackend()->GetDefaultPrinterName(default_printer), + mojom::ResultCode::kSuccess); + EXPECT_EQ(default_printer, kDefaultPrinterName); // Changing default should be reflected on next query. GetPrintBackend()->SetDefaultPrinterName(kAlternatePrinterName); - EXPECT_EQ(GetPrintBackend()->GetDefaultPrinterName(), kAlternatePrinterName); + ASSERT_EQ(GetPrintBackend()->GetDefaultPrinterName(default_printer), + mojom::ResultCode::kSuccess); + EXPECT_EQ(default_printer, kAlternatePrinterName); // Adding a new printer to environment which is marked as default should // automatically make it the new default. @@ -131,17 +145,23 @@ TEST_F(TestPrintBackendTest, DefaultPrinterName) { printer_info->is_default = true; GetPrintBackend()->AddValidPrinter(kNewDefaultPrinterName, std::move(caps), std::move(printer_info)); - EXPECT_EQ(GetPrintBackend()->GetDefaultPrinterName(), kNewDefaultPrinterName); + ASSERT_EQ(GetPrintBackend()->GetDefaultPrinterName(default_printer), + mojom::ResultCode::kSuccess); + EXPECT_EQ(default_printer, kNewDefaultPrinterName); // Requesting an invalid printer name to be a default should have no effect. GetPrintBackend()->SetDefaultPrinterName(kInvalidPrinterName); - EXPECT_EQ(GetPrintBackend()->GetDefaultPrinterName(), kNewDefaultPrinterName); + ASSERT_EQ(GetPrintBackend()->GetDefaultPrinterName(default_printer), + mojom::ResultCode::kSuccess); + EXPECT_EQ(default_printer, 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()); + ASSERT_EQ(GetPrintBackend()->GetDefaultPrinterName(default_printer), + mojom::ResultCode::kSuccess); + EXPECT_TRUE(default_printer.empty()); } TEST_F(TestPrintBackendTest, PrinterBasicInfo) { @@ -202,6 +222,23 @@ TEST_F(TestPrintBackendTest, PrinterBasicInfoAccessDenied) { mojom::ResultCode::kAccessDenied); } +// Demonstrate that a printer might be able to present data considered to be +// invalid, which becomes detectable when it undergoes Mojom message +// validation. +TEST_F(TestPrintBackendTest, PrinterBasicInfoInvalidData) { + PrinterBasicInfo printer_info; + + AddInvalidDataPrinter(); + + EXPECT_EQ(GetPrintBackend()->GetPrinterBasicInfo(kInvalidDataPrinterName, + &printer_info), + mojom::ResultCode::kSuccess); + + PrinterBasicInfo output; + EXPECT_FALSE(mojo::test::SerializeAndDeserialize<mojom::PrinterBasicInfo>( + printer_info, output)); +} + TEST_F(TestPrintBackendTest, GetPrinterSemanticCapsAndDefaults) { PrinterSemanticCapsAndDefaults caps; diff --git a/chromium/printing/backend/win_helper.cc b/chromium/printing/backend/win_helper.cc index e9d57725f10..067e186c4b8 100644 --- a/chromium/printing/backend/win_helper.cc +++ b/chromium/printing/backend/win_helper.cc @@ -11,13 +11,13 @@ #include <memory> #include "base/check_op.h" +#include "base/cxx17_backports.h" #include "base/debug/alias.h" #include "base/file_version_info.h" #include "base/files/file_path.h" #include "base/memory/free_deleter.h" #include "base/notreached.h" #include "base/numerics/safe_conversions.h" -#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" diff --git a/chromium/printing/metafile_skia_unittest.cc b/chromium/printing/metafile_skia_unittest.cc index 519a8593a3f..9e615561cff 100644 --- a/chromium/printing/metafile_skia_unittest.cc +++ b/chromium/printing/metafile_skia_unittest.cc @@ -12,6 +12,7 @@ #include "printing/mojom/print.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkPictureRecorder.h" +#include "third_party/skia/include/core/SkTextBlob.h" namespace printing { @@ -144,15 +145,18 @@ TEST(MetafileSkiaTest, TestMultiPictureDocumentTypefaces) { // Mark the page with some text using multiple fonts. // Use the first font. sk_sp<SkTextBlob> text_blob1 = SkTextBlob::MakeFromString("foo", font1); - record->push<cc::DrawTextBlobOp>(text_blob1, 0, 0, ++node_id, flags_text); + record->push<cc::DrawTextBlobOp>(text_blob1, 0.0f, 0.0f, ++node_id, + flags_text); // Use the second font. sk_sp<SkTextBlob> text_blob2 = SkTextBlob::MakeFromString("bar", font2); - record->push<cc::DrawTextBlobOp>(text_blob2, 0, 0, ++node_id, flags_text); + record->push<cc::DrawTextBlobOp>(text_blob2, 0.0f, 0.0f, ++node_id, + flags_text); // Reuse the first font again on same page. sk_sp<SkTextBlob> text_blob3 = SkTextBlob::MakeFromString("bar", font2); - record->push<cc::DrawTextBlobOp>(text_blob3, 0, 0, ++node_id, flags_text); + record->push<cc::DrawTextBlobOp>(text_blob3, 0.0f, 0.0f, ++node_id, + flags_text); metafile.AppendPage(page_size, std::move(record)); metafile.AppendSubframeInfo(content_id, base::UnguessableToken::Create(), diff --git a/chromium/printing/mojom/BUILD.gn b/chromium/printing/mojom/BUILD.gn index 09a14ceea26..029a1b8d76b 100644 --- a/chromium/printing/mojom/BUILD.gn +++ b/chromium/printing/mojom/BUILD.gn @@ -3,7 +3,45 @@ # found in the LICENSE file. import("//mojo/public/tools/bindings/mojom.gni") +import("//printing/buildflags/buildflags.gni") mojom("mojom") { sources = [ "print.mojom" ] } + +if (enable_basic_printing) { + mojom("printing_context") { + sources = [ "printing_context.mojom" ] + + public_deps = [ "//ui/gfx/geometry/mojom" ] + + cpp_typemaps = [ + { + types = [ + { + mojom = "printing.mojom.PageMargins" + cpp = "::printing::PageMargins" + }, + { + mojom = "printing.mojom.PageSetup" + cpp = "::printing::PageSetup" + }, + { + mojom = "printing.mojom.PageRange" + cpp = "::printing::PageRange" + }, + { + mojom = "printing.mojom.RequestedMedia" + cpp = "::printing::PrintSettings::RequestedMedia" + }, + ] + traits_sources = [ "printing_context_mojom_traits.cc" ] + traits_headers = [ "printing_context_mojom_traits.h" ] + traits_deps = [ + "//printing", + "//ui/gfx/geometry", + ] + }, + ] + } +} diff --git a/chromium/printing/mojom/OWNERS b/chromium/printing/mojom/OWNERS index 08850f42120..1feb5149750 100644 --- a/chromium/printing/mojom/OWNERS +++ b/chromium/printing/mojom/OWNERS @@ -1,2 +1,4 @@ per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *_mojom_traits*.*=set noparent +per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS diff --git a/chromium/printing/mojom/print.mojom b/chromium/printing/mojom/print.mojom index 2509f8928ad..0e0b8ae8619 100644 --- a/chromium/printing/mojom/print.mojom +++ b/chromium/printing/mojom/print.mojom @@ -135,3 +135,23 @@ enum ResultCode { // Insufficient permissions to perform the operation. kAccessDenied, }; + +// Matches print_preview.PrinterType in +// chrome/browser/resources/print_preview/data/destination_match.js +[Stable, Extensible] +enum PrinterType { + kPrivet, + kExtension, + kPdf, + kLocal, + kCloud +}; + +[EnableIf=is_win] +enum PrinterLanguageType { + kNone = 0, + kTextOnly, + kXps, + kPostscriptLevel2, + kPostscriptLevel3, +}; diff --git a/chromium/printing/mojom/printing_context.mojom b/chromium/printing/mojom/printing_context.mojom new file mode 100644 index 00000000000..5e85173e236 --- /dev/null +++ b/chromium/printing/mojom/printing_context.mojom @@ -0,0 +1,42 @@ +// Copyright 2021 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. + +module printing.mojom; + +import "ui/gfx/geometry/mojom/geometry.mojom"; + +// Corresponds to `printing::PageMargins` in printing/page_setup.h. +struct PageMargins { + int32 header; + int32 footer; + int32 left; + int32 right; + int32 top; + int32 bottom; +}; + +// Corresponds to `printing::PageSetup` in printing/page_setup.h. +struct PageSetup { + gfx.mojom.Size physical_size; + gfx.mojom.Rect printable_area; + gfx.mojom.Rect overlay_area; + gfx.mojom.Rect content_area; + PageMargins effective_margins; + PageMargins requested_margins; + bool forced_margins; + int32 text_height; +}; + +// Corresponds to `printing::PageRange` in printing/page_range.h. +struct PageRange { + uint32 from; + uint32 to; +}; + +// Corresponds to `printing::PrintSettings::RequestedMedia` in +// printing/print_settings.h. +struct RequestedMedia { + gfx.mojom.Size size_microns; + string vendor_id; +}; diff --git a/chromium/printing/mojom/printing_context_mojom_traits.cc b/chromium/printing/mojom/printing_context_mojom_traits.cc new file mode 100644 index 00000000000..e6ba49233ab --- /dev/null +++ b/chromium/printing/mojom/printing_context_mojom_traits.cc @@ -0,0 +1,82 @@ +// Copyright 2021 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/mojom/printing_context_mojom_traits.h" + +#include "ui/gfx/geometry/mojom/geometry.mojom-shared.h" +#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h" + +namespace mojo { + +// static +bool StructTraits<printing::mojom::PageMarginsDataView, printing::PageMargins>:: + Read(printing::mojom::PageMarginsDataView data, + printing::PageMargins* out) { + out->header = data.header(); + out->footer = data.footer(); + out->left = data.left(); + out->right = data.right(); + out->top = data.top(); + out->bottom = data.bottom(); + return true; +} + +// static +bool StructTraits<printing::mojom::PageSetupDataView, printing::PageSetup>:: + Read(printing::mojom::PageSetupDataView data, printing::PageSetup* out) { + gfx::Size physical_size; + gfx::Rect printable_area; + gfx::Rect overlay_area; + gfx::Rect content_area; + printing::PageMargins effective_margins; + printing::PageMargins requested_margins; + + if (!data.ReadPhysicalSize(&physical_size) || + !data.ReadPrintableArea(&printable_area) || + !data.ReadOverlayArea(&overlay_area) || + !data.ReadContentArea(&content_area) || + !data.ReadEffectiveMargins(&effective_margins) || + !data.ReadRequestedMargins(&requested_margins)) { + return false; + } + + printing::PageSetup page_setup(physical_size, printable_area, + requested_margins, data.forced_margins(), + data.text_height()); + + if (page_setup.overlay_area() != overlay_area) + return false; + if (page_setup.content_area() != content_area) + return false; + if (!effective_margins.Equals(page_setup.effective_margins())) + return false; + + *out = page_setup; + return true; +} + +// static +bool StructTraits<printing::mojom::PageRangeDataView, printing::PageRange>:: + Read(printing::mojom::PageRangeDataView data, printing::PageRange* out) { + out->from = data.from(); + out->to = data.to(); + + // A range should represent increasing page numbers, not to be used to + // indicate processing pages backwards. + if (out->from > out->to) + return false; + + return true; +} + +// static +bool StructTraits<printing::mojom::RequestedMediaDataView, + printing::PrintSettings::RequestedMedia>:: + Read(printing::mojom::RequestedMediaDataView data, + printing::PrintSettings::RequestedMedia* out) { + return data.ReadSizeMicrons(&out->size_microns) && + data.ReadVendorId(&out->vendor_id); +} + +} // namespace mojo diff --git a/chromium/printing/mojom/printing_context_mojom_traits.h b/chromium/printing/mojom/printing_context_mojom_traits.h new file mode 100644 index 00000000000..8bcc06f385c --- /dev/null +++ b/chromium/printing/mojom/printing_context_mojom_traits.h @@ -0,0 +1,90 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PRINTING_MOJOM_PRINTING_CONTEXT_MOJOM_TRAITS_H_ +#define PRINTING_MOJOM_PRINTING_CONTEXT_MOJOM_TRAITS_H_ + +#include "printing/mojom/printing_context.mojom-shared.h" +#include "printing/page_range.h" +#include "printing/page_setup.h" +#include "printing/print_settings.h" +#include "ui/gfx/geometry/size.h" + +namespace mojo { + +template <> +struct StructTraits<printing::mojom::PageMarginsDataView, + printing::PageMargins> { + static int32_t header(const printing::PageMargins& m) { return m.header; } + static int32_t footer(const printing::PageMargins& m) { return m.footer; } + static int32_t left(const printing::PageMargins& m) { return m.left; } + static int32_t right(const printing::PageMargins& m) { return m.right; } + static int32_t top(const printing::PageMargins& m) { return m.top; } + static int32_t bottom(const printing::PageMargins& m) { return m.bottom; } + + static bool Read(printing::mojom::PageMarginsDataView data, + printing::PageMargins* out); +}; + +template <> +struct StructTraits<printing::mojom::PageSetupDataView, printing::PageSetup> { + static const gfx::Size& physical_size(const printing::PageSetup& s) { + return s.physical_size(); + } + static const gfx::Rect& printable_area(const printing::PageSetup& s) { + return s.printable_area(); + } + static const gfx::Rect& overlay_area(const printing::PageSetup& s) { + return s.overlay_area(); + } + static const gfx::Rect& content_area(const printing::PageSetup& s) { + return s.content_area(); + } + static const printing::PageMargins& effective_margins( + const printing::PageSetup& s) { + return s.effective_margins(); + } + static const printing::PageMargins& requested_margins( + const printing::PageSetup& s) { + return s.requested_margins(); + } + static bool forced_margins(const printing::PageSetup& s) { + return s.forced_margins(); + } + static int32_t text_height(const printing::PageSetup& s) { + return s.text_height(); + } + + static bool Read(printing::mojom::PageSetupDataView data, + printing::PageSetup* out); +}; + +template <> +struct StructTraits<printing::mojom::PageRangeDataView, printing::PageRange> { + static uint32_t from(const printing::PageRange& r) { return r.from; } + static uint32_t to(const printing::PageRange& r) { return r.to; } + + static bool Read(printing::mojom::PageRangeDataView data, + printing::PageRange* out); +}; + +template <> +struct StructTraits<printing::mojom::RequestedMediaDataView, + printing::PrintSettings::RequestedMedia> { + static const gfx::Size& size_microns( + const printing::PrintSettings::RequestedMedia& r) { + return r.size_microns; + } + static const std::string& vendor_id( + const printing::PrintSettings::RequestedMedia& r) { + return r.vendor_id; + } + + static bool Read(printing::mojom::RequestedMediaDataView data, + printing::PrintSettings::RequestedMedia* out); +}; + +} // namespace mojo + +#endif // PRINTING_MOJOM_PRINTING_CONTEXT_MOJOM_TRAITS_H_ diff --git a/chromium/printing/mojom/printing_context_mojom_traits_unittest.cc b/chromium/printing/mojom/printing_context_mojom_traits_unittest.cc new file mode 100644 index 00000000000..481ca7a6ad1 --- /dev/null +++ b/chromium/printing/mojom/printing_context_mojom_traits_unittest.cc @@ -0,0 +1,249 @@ +// Copyright 2021 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 "mojo/public/cpp/test_support/test_utils.h" +#include "printing/mojom/printing_context.mojom.h" +#include "printing/page_range.h" +#include "printing/page_setup.h" +#include "printing/print_settings.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/size.h" + +namespace printing { + +namespace { + +// Values for PageMargins, just want non-zero and all different. +const PageMargins kPageMarginNonzero(/*header=*/1, + /*footer=*/2, + /*left=*/3, + /*right=*/4, + /*top=*/5, + /*bottom=*/6); + +constexpr int kPageSetupTextHeight = 1; +constexpr gfx::Size kPageSetupPhysicalSize = + gfx::Size(/*width=*/100, /*height=*/200); +constexpr gfx::Rect kPageSetupPrintableArea = + gfx::Rect(/*x=*/5, /*y=*/10, /*width=*/80, /*height=*/170); +const PageMargins kPageSetupRequestedMargins( + /*header=*/10, + /*footer=*/20, + /*left=*/5, + /*right=*/15, + /*top=*/10 + kPageSetupTextHeight, + /*bottom=*/20 + kPageSetupTextHeight); + +const PageSetup kPageSetupAsymmetricalMargins(kPageSetupPhysicalSize, + kPageSetupPrintableArea, + kPageSetupRequestedMargins, + /*forced_margins=*/false, + kPageSetupTextHeight); +const PageSetup kPageSetupForcedMargins(kPageSetupPhysicalSize, + kPageSetupPrintableArea, + kPageSetupRequestedMargins, + /*forced_margins=*/true, + kPageSetupTextHeight); + +constexpr gfx::Size kRequestedMediaSize = + gfx::Size(/*width=*/25, /*height=*/75); +const char kRequestedMediaVendorId[] = "iso-foo"; + +PrintSettings::RequestedMedia GenerateSampleRequestedMedia() { + PrintSettings::RequestedMedia media; + media.size_microns = kRequestedMediaSize; + media.vendor_id = kRequestedMediaVendorId; + return media; +} + +} // namespace + +TEST(PrintingContextMojomTraitsTest, TestSerializeAndDeserializePageMargins) { + PageMargins input = kPageMarginNonzero; + PageMargins output; + + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageMargins>(input, output)); + + EXPECT_EQ(kPageMarginNonzero.header, output.header); + EXPECT_EQ(kPageMarginNonzero.footer, output.footer); + EXPECT_EQ(kPageMarginNonzero.left, output.left); + EXPECT_EQ(kPageMarginNonzero.right, output.right); + EXPECT_EQ(kPageMarginNonzero.top, output.top); + EXPECT_EQ(kPageMarginNonzero.bottom, output.bottom); +} + +// Test that no margins is valid. +TEST(PrintingContextMojomTraitsTest, + TestSerializeAndDeserializePageMarginsNoMargins) { + // Default constructor is all members zero. + PageMargins input; + // Ensure `output` doesn't start out with all zeroes. + PageMargins output = kPageMarginNonzero; + + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageMargins>(input, output)); + + EXPECT_EQ(0, output.header); + EXPECT_EQ(0, output.footer); + EXPECT_EQ(0, output.left); + EXPECT_EQ(0, output.right); + EXPECT_EQ(0, output.top); + EXPECT_EQ(0, output.bottom); +} + +// Test that negative margin values are allowed. +TEST(PrintingContextMojomTraitsTest, + TestSerializeAndDeserializePageMarginsNegativeValues) { + PageMargins input = kPageMarginNonzero; + PageMargins output; + + input.header = -1; + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageMargins>(input, output)); + EXPECT_EQ(-1, output.header); + + input = kPageMarginNonzero; + input.footer = -1; + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageMargins>(input, output)); + EXPECT_EQ(-1, output.footer); + + input = kPageMarginNonzero; + input.left = -1; + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageMargins>(input, output)); + EXPECT_EQ(-1, output.left); + + input = kPageMarginNonzero; + input.right = -1; + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageMargins>(input, output)); + EXPECT_EQ(-1, output.right); + + input = kPageMarginNonzero; + input.top = -1; + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageMargins>(input, output)); + EXPECT_EQ(-1, output.top); + + input = kPageMarginNonzero; + input.bottom = -1; + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageMargins>(input, output)); + EXPECT_EQ(-1, output.bottom); +} + +TEST(PrintingContextMojomTraitsTest, TestSerializeAndDeserializePageSetup) { + PageSetup input = kPageSetupAsymmetricalMargins; + PageSetup output; + + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageSetup>(input, output)); + + EXPECT_EQ(kPageSetupAsymmetricalMargins.physical_size(), + output.physical_size()); + EXPECT_EQ(kPageSetupAsymmetricalMargins.printable_area(), + output.printable_area()); + EXPECT_EQ(kPageSetupAsymmetricalMargins.overlay_area(), + output.overlay_area()); + EXPECT_EQ(kPageSetupAsymmetricalMargins.content_area(), + output.content_area()); + EXPECT_TRUE(kPageSetupAsymmetricalMargins.effective_margins().Equals( + output.effective_margins())); + EXPECT_TRUE(kPageSetupAsymmetricalMargins.requested_margins().Equals( + output.requested_margins())); + EXPECT_EQ(kPageSetupAsymmetricalMargins.forced_margins(), + output.forced_margins()); + EXPECT_EQ(kPageSetupAsymmetricalMargins.text_height(), output.text_height()); +} + +TEST(PrintingContextMojomTraitsTest, + TestSerializeAndDeserializePageSetupForcedMargins) { + PageSetup input = kPageSetupForcedMargins; + PageSetup output; + + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageSetup>(input, output)); + + EXPECT_EQ(kPageSetupForcedMargins.physical_size(), output.physical_size()); + EXPECT_EQ(kPageSetupForcedMargins.printable_area(), output.printable_area()); + EXPECT_EQ(kPageSetupForcedMargins.overlay_area(), output.overlay_area()); + EXPECT_EQ(kPageSetupForcedMargins.content_area(), output.content_area()); + EXPECT_TRUE(kPageSetupForcedMargins.effective_margins().Equals( + output.effective_margins())); + EXPECT_TRUE(kPageSetupForcedMargins.requested_margins().Equals( + output.requested_margins())); + EXPECT_EQ(kPageSetupForcedMargins.forced_margins(), output.forced_margins()); + EXPECT_EQ(kPageSetupForcedMargins.text_height(), output.text_height()); +} + +TEST(PrintingContextMojomTraitsTest, + TestSerializeAndDeserializePageRangeMultiPage) { + PageRange input; + PageRange output; + + input.from = 0u; + input.to = 5u; + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageRange>(input, output)); + + EXPECT_EQ(0u, output.from); + EXPECT_EQ(5u, output.to); +} + +TEST(PrintingContextMojomTraitsTest, + TestSerializeAndDeserializePageRangeSinglePage) { + PageRange input; + PageRange output; + + input.from = 1u; + input.to = 1u; + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::PageRange>(input, output)); + + EXPECT_EQ(1u, output.from); + EXPECT_EQ(1u, output.to); +} + +TEST(PrintingContextMojomTraitsTest, + TestSerializeAndDeserializePageRangeReverseRange) { + PageRange input; + PageRange output; + + // Verify that reverse ranges are not allowed (e.g., not a mechanism to print + // the range backwards). + input.from = 5u; + input.to = 1u; + EXPECT_FALSE( + mojo::test::SerializeAndDeserialize<mojom::PageRange>(input, output)); +} + +TEST(PrintingContextMojomTraitsTest, + TestSerializeAndDeserializeRequestedMedia) { + PrintSettings::RequestedMedia input = GenerateSampleRequestedMedia(); + PrintSettings::RequestedMedia output; + + EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::RequestedMedia>( + input, output)); + + EXPECT_EQ(kRequestedMediaSize, output.size_microns); + EXPECT_EQ(kRequestedMediaVendorId, output.vendor_id); +} + +TEST(PrintingContextMojomTraitsTest, + TestSerializeAndDeserializeRequestedMediaEmpty) { + PrintSettings::RequestedMedia input; + PrintSettings::RequestedMedia output; + + // The default is empty. + EXPECT_TRUE(input.IsDefault()); + + EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::RequestedMedia>( + input, output)); + + EXPECT_TRUE(output.IsDefault()); +} + +} // namespace printing diff --git a/chromium/printing/page_number.cc b/chromium/printing/page_number.cc index ff3f361867c..617e07c3385 100644 --- a/chromium/printing/page_number.cc +++ b/chromium/printing/page_number.cc @@ -24,12 +24,9 @@ PageNumber::PageNumber() page_range_index_(kInvalidPageIndex), document_page_count_(0) {} -void PageNumber::operator=(const PageNumber& other) { - ranges_ = other.ranges_; - page_number_ = other.page_number_; - page_range_index_ = other.page_range_index_; - document_page_count_ = other.document_page_count_; -} +PageNumber::PageNumber(const PageNumber& other) = default; + +PageNumber& PageNumber::operator=(const PageNumber& other) = default; void PageNumber::Init(const PrintSettings& settings, uint32_t document_page_count) { diff --git a/chromium/printing/page_number.h b/chromium/printing/page_number.h index 48372a1d121..55866ce761f 100644 --- a/chromium/printing/page_number.h +++ b/chromium/printing/page_number.h @@ -22,7 +22,8 @@ class COMPONENT_EXPORT(PRINTING) PageNumber { PageNumber(); - void operator=(const PageNumber& other); + PageNumber(const PageNumber& other); + PageNumber& operator=(const PageNumber& other); // Initializes the page to the first page in the setting's range or 0. It // initialize to npos if the range is empty and document_page_count is 0. diff --git a/chromium/printing/page_setup.cc b/chromium/printing/page_setup.cc index c00eb62fb0a..3ed736dc8e2 100644 --- a/chromium/printing/page_setup.cc +++ b/chromium/printing/page_setup.cc @@ -36,6 +36,19 @@ bool IsValidPrintableArea(const gfx::Size& page_size, PageMargins::PageMargins() : header(0), footer(0), left(0), right(0), top(0), bottom(0) {} +PageMargins::PageMargins(int header, + int footer, + int left, + int right, + int top, + int bottom) + : header(header), + footer(footer), + left(left), + right(right), + top(top), + bottom(bottom) {} + void PageMargins::Clear() { header = 0; footer = 0; @@ -54,6 +67,15 @@ PageSetup::PageSetup() { Clear(); } +PageSetup::PageSetup(const gfx::Size& physical_size, + const gfx::Rect& printable_area, + const PageMargins& requested_margins, + bool forced_margins, + int text_height) + : requested_margins_(requested_margins), forced_margins_(forced_margins) { + Init(physical_size, printable_area, text_height); +} + PageSetup::PageSetup(const PageSetup& other) = default; PageSetup::~PageSetup() = default; diff --git a/chromium/printing/page_setup.h b/chromium/printing/page_setup.h index 76bcb4ddc91..c8c189e5167 100644 --- a/chromium/printing/page_setup.h +++ b/chromium/printing/page_setup.h @@ -14,6 +14,7 @@ namespace printing { class COMPONENT_EXPORT(PRINTING) PageMargins { public: PageMargins(); + PageMargins(int header, int footer, int left, int right, int top, int bottom); void Clear(); @@ -36,6 +37,11 @@ class COMPONENT_EXPORT(PRINTING) PageMargins { class COMPONENT_EXPORT(PRINTING) PageSetup { public: PageSetup(); + PageSetup(const gfx::Size& physical_size, + const gfx::Rect& printable_area, + const PageMargins& requested_margins, + bool forced_margins, + int text_height); PageSetup(const PageSetup& other); ~PageSetup(); @@ -66,6 +72,9 @@ class COMPONENT_EXPORT(PRINTING) PageSetup { const gfx::Rect& content_area() const { return content_area_; } const gfx::Rect& printable_area() const { return printable_area_; } const PageMargins& effective_margins() const { return effective_margins_; } + const PageMargins& requested_margins() const { return requested_margins_; } + bool forced_margins() const { return forced_margins_; } + int text_height() const { return text_height_; } private: // Store `requested_margins_` and update page setup values. diff --git a/chromium/printing/print_job_constants.cc b/chromium/printing/print_job_constants.cc index 8a41b269394..fd6436ab16a 100644 --- a/chromium/printing/print_job_constants.cc +++ b/chromium/printing/print_job_constants.cc @@ -143,9 +143,6 @@ const char kSettingPolicies[] = "policies"; // Whether the source page content is from ARC or not. const char kSettingPreviewIsFromArc[] = "previewIsFromArc"; -// Whether the source page content is PDF or not. -const char kSettingPreviewIsPdf[] = "previewIsPdf"; - // Whether the source page content is modifiable. True for web content. // i.e. Anything from Blink. False for everything else. e.g. PDF/Flash. const char kSettingPreviewModifiable[] = "previewModifiable"; @@ -183,6 +180,9 @@ const char kSettingPagesPerSheet[] = "pagesPerSheet"; // Whether to rasterize the PDF for printing. const char kSettingRasterizePdf[] = "rasterizePDF"; +// The DPI override to use when rasterize the PDF for printing. +const char kSettingRasterizePdfDpi[] = "rasterizePdfDpi"; + // Ticket option. Contains the ticket in CJT format. const char kSettingTicket[] = "ticket"; diff --git a/chromium/printing/print_job_constants.h b/chromium/printing/print_job_constants.h index cb3f3e2c998..1df500eed61 100644 --- a/chromium/printing/print_job_constants.h +++ b/chromium/printing/print_job_constants.h @@ -95,8 +95,6 @@ COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingPolicies[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingPreviewIsFromArc[]; COMPONENT_EXPORT(PRINTING_BASE) -extern const char kSettingPreviewIsPdf[]; -COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingPreviewModifiable[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingPrintToGoogleDrive[]; @@ -119,6 +117,8 @@ extern const char kSettingPrinterType[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingRasterizePdf[]; COMPONENT_EXPORT(PRINTING_BASE) +extern const char kSettingRasterizePdfDpi[]; +COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingScaleFactor[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingScalingType[]; @@ -188,10 +188,6 @@ enum ScalingType { SCALING_TYPE_LAST = CUSTOM }; -// Must match print_preview.PrinterType in -// chrome/browser/resources/print_preview/data/destination_match.js -enum class PrinterType { kPrivet, kExtension, kPdf, kLocal, kCloud }; - } // namespace printing #endif // PRINTING_PRINT_JOB_CONSTANTS_H_ diff --git a/chromium/printing/print_settings.cc b/chromium/printing/print_settings.cc index bd3b3d9bd26..0115615dfbc 100644 --- a/chromium/printing/print_settings.cc +++ b/chromium/printing/print_settings.cc @@ -14,6 +14,10 @@ #include <cups/cups.h> #endif +#if defined(OS_WIN) +#include "printing/mojom/print.mojom.h" +#endif + namespace printing { namespace { @@ -270,11 +274,12 @@ void PrintSettings::Clear() { dpi_ = gfx::Size(); scale_factor_ = 1.0f; rasterize_pdf_ = false; + rasterize_pdf_dpi_ = 0; landscape_ = false; supports_alpha_blend_ = true; #if defined(OS_WIN) print_text_with_gdi_ = false; - printer_type_ = PrintSettings::PrinterType::TYPE_NONE; + printer_language_type_ = mojom::PrinterLanguageType::kNone; #endif is_modifiable_ = true; pages_per_sheet_ = 1; diff --git a/chromium/printing/print_settings.h b/chromium/printing/print_settings.h index 451632c559f..efba1ec96f6 100644 --- a/chromium/printing/print_settings.h +++ b/chromium/printing/print_settings.h @@ -59,16 +59,6 @@ COMPONENT_EXPORT(PRINTING) const std::string& GetAgent(); class COMPONENT_EXPORT(PRINTING) PrintSettings { public: -#if defined(OS_WIN) - enum PrinterType { - TYPE_NONE = 0, - TYPE_TEXTONLY, - TYPE_XPS, - TYPE_POSTSCRIPT_LEVEL2, - TYPE_POSTSCRIPT_LEVEL3 - }; -#endif - // Media properties requested by the user. Default instance represents // default media selection. struct RequestedMedia { @@ -147,6 +137,9 @@ class COMPONENT_EXPORT(PRINTING) PrintSettings { void set_rasterize_pdf(bool rasterize_pdf) { rasterize_pdf_ = rasterize_pdf; } bool rasterize_pdf() const { return rasterize_pdf_; } + void set_rasterize_pdf_dpi(int32_t dpi) { rasterize_pdf_dpi_ = dpi; } + int32_t rasterize_pdf_dpi() const { return rasterize_pdf_dpi_; } + void set_supports_alpha_blend(bool supports_alpha_blend) { supports_alpha_blend_ = supports_alpha_blend; } @@ -202,16 +195,22 @@ class COMPONENT_EXPORT(PRINTING) PrintSettings { void set_print_text_with_gdi(bool use_gdi) { print_text_with_gdi_ = use_gdi; } bool print_text_with_gdi() const { return print_text_with_gdi_; } - void set_printer_type(PrinterType type) { printer_type_ = type; } - bool printer_is_textonly() const { - return printer_type_ == PrinterType::TYPE_TEXTONLY; + void set_printer_language_type(mojom::PrinterLanguageType type) { + printer_language_type_ = type; + } + bool printer_language_is_textonly() const { + return printer_language_type_ == mojom::PrinterLanguageType::kTextOnly; } - bool printer_is_xps() const { return printer_type_ == PrinterType::TYPE_XPS; } - bool printer_is_ps2() const { - return printer_type_ == PrinterType::TYPE_POSTSCRIPT_LEVEL2; + bool printer_language_is_xps() const { + return printer_language_type_ == mojom::PrinterLanguageType::kXps; } - bool printer_is_ps3() const { - return printer_type_ == PrinterType::TYPE_POSTSCRIPT_LEVEL3; + bool printer_language_is_ps2() const { + return printer_language_type_ == + mojom::PrinterLanguageType::kPostscriptLevel2; + } + bool printer_language_is_ps3() const { + return printer_language_type_ == + mojom::PrinterLanguageType::kPostscriptLevel3; } #endif @@ -243,13 +242,13 @@ class COMPONENT_EXPORT(PRINTING) PrintSettings { const std::string& pin_value() const { return pin_value_; } #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 - // correctly associated with its corresponding PrintedDocument. + // Cookie generator. It is used to initialize `PrintedDocument` with its + // associated `PrintSettings`, to be sure that each generated `PrintedPage` + // is correctly associated with its corresponding `PrintedDocument`. static int NewCookie(); private: - // Multi-page printing. Each PageRange describes a from-to page combination. + // Multi-page printing. Each `PageRange` describes a from-to page combination. // This permits printing selected pages only. PageRanges ranges_; @@ -301,6 +300,11 @@ class COMPONENT_EXPORT(PRINTING) PrintSettings { // True if PDF should be printed as a raster PDF bool rasterize_pdf_; + // The DPI which overrides the calculated value normally used when + // rasterizing a PDF. A non-positive value would be an invalid choice of a + // DPI and indicates no override. + int32_t rasterize_pdf_dpi_; + // Is the orientation landscape or portrait. bool landscape_; @@ -311,7 +315,7 @@ class COMPONENT_EXPORT(PRINTING) PrintSettings { // True to print text with GDI. bool print_text_with_gdi_; - PrinterType printer_type_; + mojom::PrinterLanguageType printer_language_type_; #endif bool is_modifiable_; diff --git a/chromium/printing/print_settings_conversion.cc b/chromium/printing/print_settings_conversion.cc index 167e114a7b5..ee2aaea1393 100644 --- a/chromium/printing/print_settings_conversion.cc +++ b/chromium/printing/print_settings_conversion.cc @@ -44,33 +44,33 @@ PageMargins GetCustomMarginsFromJobSettings(const base::Value& settings) { void SetMarginsToJobSettings(const std::string& json_path, const PageMargins& margins, - base::DictionaryValue* job_settings) { - auto dict = std::make_unique<base::DictionaryValue>(); - dict->SetInteger(kSettingMarginTop, margins.top); - dict->SetInteger(kSettingMarginBottom, margins.bottom); - dict->SetInteger(kSettingMarginLeft, margins.left); - dict->SetInteger(kSettingMarginRight, margins.right); - job_settings->Set(json_path, std::move(dict)); + base::Value& job_settings) { + base::Value dict(base::Value::Type::DICTIONARY); + dict.SetIntKey(kSettingMarginTop, margins.top); + dict.SetIntKey(kSettingMarginBottom, margins.bottom); + dict.SetIntKey(kSettingMarginLeft, margins.left); + dict.SetIntKey(kSettingMarginRight, margins.right); + job_settings.SetKey(json_path, std::move(dict)); } void SetSizeToJobSettings(const std::string& json_path, const gfx::Size& size, - base::DictionaryValue* job_settings) { - auto dict = std::make_unique<base::DictionaryValue>(); - dict->SetInteger("width", size.width()); - dict->SetInteger("height", size.height()); - job_settings->Set(json_path, std::move(dict)); + base::Value& job_settings) { + base::Value dict(base::Value::Type::DICTIONARY); + dict.SetIntKey("width", size.width()); + dict.SetIntKey("height", size.height()); + job_settings.SetKey(json_path, std::move(dict)); } void SetRectToJobSettings(const std::string& json_path, const gfx::Rect& rect, - base::DictionaryValue* job_settings) { - auto dict = std::make_unique<base::DictionaryValue>(); - dict->SetInteger("x", rect.x()); - dict->SetInteger("y", rect.y()); - dict->SetInteger("width", rect.width()); - dict->SetInteger("height", rect.height()); - job_settings->Set(json_path, std::move(dict)); + base::Value& job_settings) { + base::Value dict(base::Value::Type::DICTIONARY); + dict.SetIntKey("x", rect.x()); + dict.SetIntKey("y", rect.y()); + dict.SetIntKey("width", rect.width()); + dict.SetIntKey("height", rect.height()); + job_settings.SetKey(json_path, std::move(dict)); } } // namespace @@ -91,7 +91,8 @@ PageRanges GetPageRangesFromJobSettings(const base::Value& job_settings) { // Page numbers are 1-based in the dictionary. // Page numbers are 0-based for the printing context. - page_ranges.push_back(PageRange{from.value() - 1, to.value() - 1}); + page_ranges.push_back(PageRange{static_cast<uint32_t>(from.value() - 1), + static_cast<uint32_t>(to.value() - 1)}); } } return page_ranges; @@ -191,6 +192,11 @@ std::unique_ptr<PrintSettings> PrintSettingsFromJobSettings( return nullptr; settings->set_dpi_xy(dpi_horizontal.value(), dpi_vertical.value()); + absl::optional<int> rasterize_pdf_dpi = + job_settings.FindIntKey(kSettingRasterizePdfDpi); + if (rasterize_pdf_dpi.has_value()) + settings->set_rasterize_pdf_dpi(rasterize_pdf_dpi.value()); + settings->set_collate(collate.value()); settings->set_copies(copies.value()); settings->SetOrientation(landscape.value()); @@ -215,7 +221,7 @@ std::unique_ptr<PrintSettings> PrintSettingsFromJobSettings( const base::Value* advanced_settings = job_settings.FindDictKey(kSettingAdvancedSettings); if (advanced_settings) { - for (const auto& item : advanced_settings->DictItems()) + 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)) @@ -238,60 +244,66 @@ std::unique_ptr<PrintSettings> PrintSettingsFromJobSettings( return settings; } -void PrintSettingsToJobSettingsDebug(const PrintSettings& settings, - base::DictionaryValue* job_settings) { - job_settings->SetBoolean(kSettingHeaderFooterEnabled, - settings.display_header_footer()); - job_settings->SetString(kSettingHeaderFooterTitle, settings.title()); - job_settings->SetString(kSettingHeaderFooterURL, settings.url()); - job_settings->SetBoolean(kSettingShouldPrintBackgrounds, - settings.should_print_backgrounds()); - job_settings->SetBoolean(kSettingShouldPrintSelectionOnly, - settings.selection_only()); - job_settings->SetInteger(kSettingMarginsType, - static_cast<int>(settings.margin_type())); +base::Value PrintSettingsToJobSettingsDebug(const PrintSettings& settings) { + base::Value job_settings(base::Value::Type::DICTIONARY); + + job_settings.SetBoolKey(kSettingHeaderFooterEnabled, + settings.display_header_footer()); + job_settings.SetStringKey(kSettingHeaderFooterTitle, settings.title()); + job_settings.SetStringKey(kSettingHeaderFooterURL, settings.url()); + job_settings.SetBoolKey(kSettingShouldPrintBackgrounds, + settings.should_print_backgrounds()); + job_settings.SetBoolKey(kSettingShouldPrintSelectionOnly, + settings.selection_only()); + job_settings.SetIntKey(kSettingMarginsType, + static_cast<int>(settings.margin_type())); if (!settings.ranges().empty()) { - auto page_range_array = std::make_unique<base::ListValue>(); - for (size_t i = 0; i < settings.ranges().size(); ++i) { - auto dict = std::make_unique<base::DictionaryValue>(); - dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1); - dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1); - page_range_array->Append(std::move(dict)); + base::ListValue page_range_array; + for (const auto& range : settings.ranges()) { + auto dict = std::make_unique<base::Value>(base::Value::Type::DICTIONARY); + dict->SetIntKey(kSettingPageRangeFrom, range.from + 1); + dict->SetIntKey(kSettingPageRangeTo, range.to + 1); + page_range_array.Append(std::move(dict)); } - job_settings->Set(kSettingPageRange, std::move(page_range_array)); + job_settings.SetKey(kSettingPageRange, std::move(page_range_array)); } - job_settings->SetBoolean(kSettingCollate, settings.collate()); - job_settings->SetInteger(kSettingCopies, settings.copies()); - job_settings->SetInteger(kSettingColor, static_cast<int>(settings.color())); - job_settings->SetInteger(kSettingDuplexMode, - static_cast<int>(settings.duplex_mode())); - job_settings->SetBoolean(kSettingLandscape, settings.landscape()); - job_settings->SetString(kSettingDeviceName, settings.device_name()); - job_settings->SetInteger(kSettingPagesPerSheet, settings.pages_per_sheet()); + job_settings.SetBoolKey(kSettingCollate, settings.collate()); + job_settings.SetIntKey(kSettingCopies, settings.copies()); + job_settings.SetIntKey(kSettingColor, static_cast<int>(settings.color())); + job_settings.SetIntKey(kSettingDuplexMode, + static_cast<int>(settings.duplex_mode())); + job_settings.SetBoolKey(kSettingLandscape, settings.landscape()); + job_settings.SetStringKey(kSettingDeviceName, settings.device_name()); + job_settings.SetIntKey(kSettingDpiHorizontal, settings.dpi_horizontal()); + job_settings.SetIntKey(kSettingDpiVertical, settings.dpi_vertical()); + job_settings.SetIntKey( + kSettingScaleFactor, + static_cast<int>((settings.scale_factor() * 100.0) + 0.5)); + job_settings.SetBoolKey(kSettingRasterizePdf, settings.rasterize_pdf()); + job_settings.SetIntKey(kSettingPagesPerSheet, settings.pages_per_sheet()); // Following values are not read form JSON by InitSettings, so do not have // common public constants. So just serialize in "debug" section. - auto debug = std::make_unique<base::DictionaryValue>(); - debug->SetInteger("dpi", settings.dpi()); - debug->SetInteger("deviceUnitsPerInch", settings.device_units_per_inch()); - debug->SetBoolean("support_alpha_blend", settings.should_print_backgrounds()); - debug->SetString("media_vendor_id", settings.requested_media().vendor_id); + base::Value debug(base::Value::Type::DICTIONARY); + debug.SetIntKey("dpi", settings.dpi()); + debug.SetIntKey("deviceUnitsPerInch", settings.device_units_per_inch()); + debug.SetBoolKey("support_alpha_blend", settings.should_print_backgrounds()); + debug.SetStringKey("media_vendor_id", settings.requested_media().vendor_id); SetSizeToJobSettings("media_size", settings.requested_media().size_microns, - debug.get()); + debug); SetMarginsToJobSettings("requested_custom_margins_in_points", - settings.requested_custom_margins_in_points(), - debug.get()); + settings.requested_custom_margins_in_points(), debug); const PageSetup& page_setup = settings.page_setup_device_units(); SetMarginsToJobSettings("effective_margins", page_setup.effective_margins(), - debug.get()); - SetSizeToJobSettings("physical_size", page_setup.physical_size(), - debug.get()); - SetRectToJobSettings("overlay_area", page_setup.overlay_area(), debug.get()); - SetRectToJobSettings("content_area", page_setup.content_area(), debug.get()); - SetRectToJobSettings("printable_area", page_setup.printable_area(), - debug.get()); - job_settings->Set("debug", std::move(debug)); + debug); + SetSizeToJobSettings("physical_size", page_setup.physical_size(), debug); + SetRectToJobSettings("overlay_area", page_setup.overlay_area(), debug); + SetRectToJobSettings("content_area", page_setup.content_area(), debug); + SetRectToJobSettings("printable_area", page_setup.printable_area(), debug); + job_settings.SetKey("debug", std::move(debug)); + + return job_settings; } } // namespace printing diff --git a/chromium/printing/print_settings_conversion.h b/chromium/printing/print_settings_conversion.h index 4541f03d3c4..9b99da6050b 100644 --- a/chromium/printing/print_settings_conversion.h +++ b/chromium/printing/print_settings_conversion.h @@ -11,7 +11,6 @@ #include "printing/page_range.h" namespace base { -class DictionaryValue; class Value; } // namespace base @@ -27,10 +26,11 @@ COMPONENT_EXPORT(PRINTING) std::unique_ptr<PrintSettings> PrintSettingsFromJobSettings( const base::Value& job_settings); -// Use for debug only, because output is not completely consistent with format -// of `PrintSettingsFromJobSettings` input. -void PrintSettingsToJobSettingsDebug(const PrintSettings& settings, - base::DictionaryValue* job_settings); +// Use for debug/test only, because output is not completely consistent with +// format of `PrintSettingsFromJobSettings` input. The returned value is a +// dictionary type. +COMPONENT_EXPORT(PRINTING) +base::Value PrintSettingsToJobSettingsDebug(const PrintSettings& settings); } // namespace printing diff --git a/chromium/printing/print_settings_conversion_unittest.cc b/chromium/printing/print_settings_conversion_unittest.cc index c9f21e6e185..06902539a93 100644 --- a/chromium/printing/print_settings_conversion_unittest.cc +++ b/chromium/printing/print_settings_conversion_unittest.cc @@ -38,6 +38,7 @@ const char kPrinterSettings[] = R"({ "deviceName": "printer", "scaleFactor": 100, "rasterizePDF": false, + "rasterizePdfDpi": 150, "pagesPerSheet": 1, "dpiHorizontal": 300, "dpiVertical": 300, @@ -71,6 +72,7 @@ TEST(PrintSettingsConversionTest, ConversionTest) { value->SetIntKey("dpiVertical", 600); settings = PrintSettingsFromJobSettings(value.value()); ASSERT_TRUE(settings); + EXPECT_EQ(settings->rasterize_pdf_dpi(), 150); EXPECT_EQ(settings->dpi_horizontal(), 300); EXPECT_EQ(settings->dpi_vertical(), 600); EXPECT_TRUE(value->RemoveKey("dpiVertical")); diff --git a/chromium/printing/print_settings_initializer_win.cc b/chromium/printing/print_settings_initializer_win.cc index 9c1dc4fc905..84a4a4f17ec 100644 --- a/chromium/printing/print_settings_initializer_win.cc +++ b/chromium/printing/print_settings_initializer_win.cc @@ -7,6 +7,7 @@ #include <windows.h> #include "printing/backend/win_helper.h" +#include "printing/mojom/print.mojom.h" #include "printing/print_settings.h" namespace printing { @@ -151,25 +152,26 @@ void PrintSettingsInitializerWin::InitPrintSettings( int level; if (IsPrinterPostScript(hdc, &level)) { if (level == 2) { - print_settings->set_printer_type( - PrintSettings::PrinterType::TYPE_POSTSCRIPT_LEVEL2); + print_settings->set_printer_language_type( + mojom::PrinterLanguageType::kPostscriptLevel2); return; } DCHECK_EQ(3, level); - print_settings->set_printer_type( - PrintSettings::PrinterType::TYPE_POSTSCRIPT_LEVEL3); + print_settings->set_printer_language_type( + mojom::PrinterLanguageType::kPostscriptLevel3); return; } // Detects the generic / text only driver. if (IsPrinterTextOnly(hdc)) { - print_settings->set_printer_type(PrintSettings::PrinterType::TYPE_TEXTONLY); + print_settings->set_printer_language_type( + mojom::PrinterLanguageType::kTextOnly); return; } if (IsPrinterXPS(hdc)) { - print_settings->set_printer_type(PrintSettings::PrinterType::TYPE_XPS); + print_settings->set_printer_language_type(mojom::PrinterLanguageType::kXps); return; } - print_settings->set_printer_type(PrintSettings::PrinterType::TYPE_NONE); + print_settings->set_printer_language_type(mojom::PrinterLanguageType::kNone); } } // namespace printing diff --git a/chromium/printing/printed_document.cc b/chromium/printing/printed_document.cc index 76c8acd7219..5e49e0ca344 100644 --- a/chromium/printing/printed_document.cc +++ b/chromium/printing/printed_document.cc @@ -91,8 +91,7 @@ void DebugDumpDataTask(const std::u16string& doc_name, void DebugDumpSettings(const std::u16string& doc_name, const PrintSettings& settings) { - base::DictionaryValue job_settings; - PrintSettingsToJobSettingsDebug(settings, &job_settings); + base::Value job_settings = PrintSettingsToJobSettingsDebug(settings); std::string settings_str; base::JSONWriter::WriteWithOptions( job_settings, base::JSONWriter::OPTIONS_PRETTY_PRINT, &settings_str); diff --git a/chromium/printing/printing_context.cc b/chromium/printing/printing_context.cc index 30fa5344771..24cf547a45b 100644 --- a/chromium/printing/printing_context.cc +++ b/chromium/printing/printing_context.cc @@ -9,6 +9,7 @@ #include "base/check.h" #include "base/notreached.h" #include "build/chromeos_buildflags.h" +#include "printing/mojom/print.mojom.h" #include "printing/page_setup.h" #include "printing/print_job_constants.h" #include "printing/print_settings_conversion.h" @@ -87,7 +88,7 @@ PrintingContext::Result PrintingContext::UsePdfSettings() { pdf_settings.SetBoolKey(kSettingLandscape, false); pdf_settings.SetStringKey(kSettingDeviceName, ""); pdf_settings.SetIntKey(kSettingPrinterType, - static_cast<int>(PrinterType::kPdf)); + static_cast<int>(mojom::PrinterType::kPdf)); pdf_settings.SetIntKey(kSettingScaleFactor, 100); pdf_settings.SetBoolKey(kSettingRasterizePdf, false); pdf_settings.SetIntKey(kSettingPagesPerSheet, 1); @@ -107,17 +108,18 @@ PrintingContext::Result PrintingContext::UpdatePrintSettings( settings_ = std::move(settings); } - PrinterType printer_type = static_cast<PrinterType>( + mojom::PrinterType printer_type = static_cast<mojom::PrinterType>( job_settings.FindIntKey(kSettingPrinterType).value()); - bool print_with_privet = printer_type == PrinterType::kPrivet; + bool print_with_privet = printer_type == mojom::PrinterType::kPrivet; bool print_to_cloud = !!job_settings.FindKey(kSettingCloudPrintId); bool open_in_external_preview = !!job_settings.FindKey(kSettingOpenPDFInPreview); - if (!open_in_external_preview && (print_to_cloud || print_with_privet || - printer_type == PrinterType::kPdf || - printer_type == PrinterType::kCloud || - printer_type == PrinterType::kExtension)) { + if (!open_in_external_preview && + (print_to_cloud || print_with_privet || + printer_type == mojom::PrinterType::kPdf || + printer_type == mojom::PrinterType::kCloud || + printer_type == mojom::PrinterType::kExtension)) { settings_->set_dpi(kDefaultPdfDpi); gfx::Size paper_size(GetPdfPaperSizeDeviceUnits()); if (!settings_->requested_media().size_microns.IsEmpty()) { diff --git a/chromium/printing/printing_context_chromeos.h b/chromium/printing/printing_context_chromeos.h index 767757f8627..61b256c34fd 100644 --- a/chromium/printing/printing_context_chromeos.h +++ b/chromium/printing/printing_context_chromeos.h @@ -13,7 +13,6 @@ #include "printing/backend/cups_deleters.h" #include "printing/backend/cups_printer.h" #include "printing/printing_context.h" -#include "third_party/abseil-cpp/absl/types/optional.h" namespace printing { diff --git a/chromium/printing/printing_context_chromeos_unittest.cc b/chromium/printing/printing_context_chromeos_unittest.cc index fed56d39686..88cc280ffa7 100644 --- a/chromium/printing/printing_context_chromeos_unittest.cc +++ b/chromium/printing/printing_context_chromeos_unittest.cc @@ -84,7 +84,7 @@ class MockCupsPrinter : public CupsPrinter { class MockCupsConnection : public CupsConnection { public: - MOCK_METHOD0(GetDests, std::vector<std::unique_ptr<CupsPrinter>>()); + MOCK_METHOD1(GetDests, bool(std::vector<std::unique_ptr<CupsPrinter>>&)); MOCK_METHOD2(GetJobs, bool(const std::vector<std::string>& printer_ids, std::vector<QueueStatus>* jobs)); diff --git a/chromium/printing/printing_context_system_dialog_win.cc b/chromium/printing/printing_context_system_dialog_win.cc index fe7fc797504..891e9574625 100644 --- a/chromium/printing/printing_context_system_dialog_win.cc +++ b/chromium/printing/printing_context_system_dialog_win.cc @@ -7,7 +7,7 @@ #include <utility> #include "base/auto_reset.h" -#include "base/stl_util.h" +#include "base/cxx17_backports.h" #include "base/strings/utf_string_conversions.h" #include "base/task/current_thread.h" #include "printing/backend/win_helper.h" diff --git a/chromium/printing/printing_context_win.cc b/chromium/printing/printing_context_win.cc index 45191038fcb..5be3a8f563c 100644 --- a/chromium/printing/printing_context_win.cc +++ b/chromium/printing/printing_context_win.cc @@ -78,8 +78,13 @@ PrintingContext::Result PrintingContextWin::UseDefaultSettings() { scoped_refptr<PrintBackend> backend = PrintBackend::CreateInstance(delegate_->GetAppLocale()); - std::wstring default_printer = - base::UTF8ToWide(backend->GetDefaultPrinterName()); + std::string default_printer_name; + mojom::ResultCode result = + backend->GetDefaultPrinterName(default_printer_name); + if (result != mojom::ResultCode::kSuccess) + return FAILED; + + std::wstring default_printer = base::UTF8ToWide(default_printer_name); if (!default_printer.empty()) { ScopedPrinterHandle printer; if (printer.OpenPrinterWithName(default_printer.c_str())) { diff --git a/chromium/printing/printing_context_win_unittest.cc b/chromium/printing/printing_context_win_unittest.cc index 59058cfdc51..62ada59445e 100644 --- a/chromium/printing/printing_context_win_unittest.cc +++ b/chromium/printing/printing_context_win_unittest.cc @@ -14,7 +14,6 @@ #include "base/test/task_environment.h" #include "base/win/scoped_handle.h" #include "base/win/scoped_hdc.h" -#include "base/win/windows_version.h" #include "printing/backend/printing_info_win.h" #include "printing/backend/win_helper.h" #include "printing/mojom/print.mojom.h" @@ -146,11 +145,8 @@ class MockPrintingContextWin : public PrintingContextSystemDialogWin { } }; -TEST_F(PrintingContextTest, PrintAll) { - // TODO(crbug.com/1231528): Investigate why this test fails on Win 7 bots. - if (base::win::GetVersion() <= base::win::Version::WIN7) - return; - +// Disabled - see crbug.com/1231528 for context. +TEST_F(PrintingContextTest, DISABLED_PrintAll) { if (IsTestCaseDisabled()) return; @@ -165,11 +161,8 @@ TEST_F(PrintingContextTest, PrintAll) { EXPECT_EQ(0u, settings.ranges().size()); } -TEST_F(PrintingContextTest, Color) { - // TODO(crbug.com/1231528): Investigate why this test fails on Win 7 bots. - if (base::win::GetVersion() <= base::win::Version::WIN7) - return; - +// Disabled - see crbug.com/1231528 for context. +TEST_F(PrintingContextTest, DISABLED_Color) { if (IsTestCaseDisabled()) return; @@ -184,11 +177,8 @@ TEST_F(PrintingContextTest, Color) { EXPECT_NE(settings.color(), mojom::ColorModel::kUnknownColorModel); } -TEST_F(PrintingContextTest, Base) { - // TODO(crbug.com/1231528): Investigate why this test fails on Win 7 bots. - if (base::win::GetVersion() <= base::win::Version::WIN7) - return; - +// Disabled - see crbug.com/1231528 for context. +TEST_F(PrintingContextTest, DISABLED_Base) { if (IsTestCaseDisabled()) return; diff --git a/chromium/printing/printing_test.h b/chromium/printing/printing_test.h index 0839204488d..d9b08815e56 100644 --- a/chromium/printing/printing_test.h +++ b/chromium/printing/printing_test.h @@ -10,7 +10,7 @@ #include <string> -#include "base/stl_util.h" +#include "base/cxx17_backports.h" // Disable the whole test case when executing on a computer that has no printer // installed. |