diff options
Diffstat (limited to 'chromium/printing/backend')
-rw-r--r-- | chromium/printing/backend/cups_helper.cc | 95 | ||||
-rw-r--r-- | chromium/printing/backend/cups_helper.h | 2 | ||||
-rw-r--r-- | chromium/printing/backend/cups_helper_unittest.cc | 106 | ||||
-rw-r--r-- | chromium/printing/backend/print_backend_cups.cc | 3 |
4 files changed, 101 insertions, 105 deletions
diff --git a/chromium/printing/backend/cups_helper.cc b/chromium/printing/backend/cups_helper.cc index b4cc35afe73..251455e0cbb 100644 --- a/chromium/printing/backend/cups_helper.cc +++ b/chromium/printing/backend/cups_helper.cc @@ -4,21 +4,17 @@ #include "printing/backend/cups_helper.h" -#include <cups/ppd.h> #include <stddef.h> -#include <string> #include <vector> -#include "base/base_paths.h" #include "base/files/file_util.h" #include "base/logging.h" -#include "base/path_service.h" #include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/time/time.h" #include "base/values.h" +#include "build/build_config.h" #include "printing/backend/print_backend.h" #include "printing/backend/print_backend_consts.h" #include "printing/mojom/print.mojom.h" @@ -52,7 +48,10 @@ constexpr char kCupsMaxCopies[] = "cupsMaxCopies"; constexpr char kColorDevice[] = "ColorDevice"; constexpr char kColorModel[] = "ColorModel"; constexpr char kColorMode[] = "ColorMode"; +// TODO(crbug.com/1081705): Epson "Ink" attribute bloats prints on Linux. +#if !defined(OS_LINUX) constexpr char kInk[] = "Ink"; +#endif constexpr char kProcessColorModel[] = "ProcessColorModel"; constexpr char kPrintoutMode[] = "PrintoutMode"; constexpr char kDraftGray[] = "Draft.Gray"; @@ -88,81 +87,6 @@ constexpr char kXeroxXRXColor[] = "XRXColor"; constexpr char kXeroxAutomatic[] = "Automatic"; constexpr char kXeroxBW[] = "BW"; -void ParseLpOptions(const base::FilePath& filepath, - base::StringPiece printer_name, - int* num_options, - cups_option_t** options) { - std::string content; - if (!base::ReadFileToString(filepath, &content)) - return; - - const char kDest[] = "dest"; - const char kDefault[] = "default"; - const size_t kDestLen = sizeof(kDest) - 1; - const size_t kDefaultLen = sizeof(kDefault) - 1; - - for (base::StringPiece line : base::SplitStringPiece( - content, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { - if (base::StartsWith(line, base::StringPiece(kDefault, kDefaultLen), - base::CompareCase::INSENSITIVE_ASCII) && - isspace(line[kDefaultLen])) { - line = line.substr(kDefaultLen); - } else if (base::StartsWith(line, base::StringPiece(kDest, kDestLen), - base::CompareCase::INSENSITIVE_ASCII) && - isspace(line[kDestLen])) { - line = line.substr(kDestLen); - } else { - continue; - } - - line = base::TrimWhitespaceASCII(line, base::TRIM_ALL); - if (line.empty()) - continue; - - size_t space_found = line.find(' '); - if (space_found == base::StringPiece::npos) - continue; - - base::StringPiece name = line.substr(0, space_found); - if (name.empty()) - continue; - - if (!EqualsCaseInsensitiveASCII(printer_name, name)) - continue; // This is not the required printer. - - line = line.substr(space_found + 1); - // Remove extra spaces. - line = base::TrimWhitespaceASCII(line, base::TRIM_ALL); - if (line.empty()) - continue; - - // Parse the selected printer custom options. Need to pass a - // null-terminated string. - *num_options = cupsParseOptions(line.as_string().c_str(), 0, options); - } -} - -void MarkLpOptions(base::StringPiece printer_name, ppd_file_t* ppd) { - static constexpr char kSystemLpOptionPath[] = "/etc/cups/lpoptions"; - static constexpr char kUserLpOptionPath[] = ".cups/lpoptions"; - - std::vector<base::FilePath> file_locations; - file_locations.push_back(base::FilePath(kSystemLpOptionPath)); - base::FilePath homedir; - base::PathService::Get(base::DIR_HOME, &homedir); - file_locations.push_back(base::FilePath(homedir.Append(kUserLpOptionPath))); - - for (const base::FilePath& location : file_locations) { - int num_options = 0; - cups_option_t* options = nullptr; - ParseLpOptions(location, printer_name, &num_options, &options); - if (num_options > 0 && options) { - cupsMarkOptions(ppd, num_options, options); - cupsFreeOptions(num_options, options); - } - } -} - int32_t GetCopiesMax(ppd_file_t* ppd) { ppd_attr_t* attr = ppdFindAttr(ppd, kCupsMaxCopies, nullptr); if (!attr || !attr->value) { @@ -409,6 +333,8 @@ bool GetHPColorModeSettings(ppd_file_t* ppd, return true; } +// TODO(crbug.com/1081705): Epson "Ink" attribute bloats prints on Linux. +#if !defined(OS_LINUX) bool GetEpsonInkSettings(ppd_file_t* ppd, ColorModel* color_model_for_black, ColorModel* color_model_for_color, @@ -434,6 +360,7 @@ bool GetEpsonInkSettings(ppd_file_t* ppd, } return true; } +#endif // !defined(OS_LINUX) bool GetSharpARCModeSettings(ppd_file_t* ppd, ColorModel* color_model_for_black, @@ -538,7 +465,10 @@ bool GetColorModelSettings(ppd_file_t* ppd, GetHPColorSettings(ppd, cm_black, cm_color, is_color) || GetHPColorModeSettings(ppd, cm_black, cm_color, is_color) || GetBrotherColorSettings(ppd, cm_black, cm_color, is_color) || +// TODO(crbug.com/1081705): Epson "Ink" attribute bloats prints on Linux. +#if !defined(OS_LINUX) GetEpsonInkSettings(ppd, cm_black, cm_color, is_color) || +#endif GetSharpARCModeSettings(ppd, cm_black, cm_color, is_color) || GetXeroxColorSettings(ppd, cm_black, cm_color, is_color) || GetProcessColorModelSettings(ppd, cm_black, cm_color, is_color); @@ -594,7 +524,7 @@ http_t* HttpConnectionCUPS::http() { return http_; } -bool ParsePpdCapabilities(base::StringPiece printer_name, +bool ParsePpdCapabilities(cups_dest_t* dest, base::StringPiece locale, base::StringPiece printer_capabilities, PrinterSemanticCapsAndDefaults* printer_info) { @@ -616,7 +546,8 @@ bool ParsePpdCapabilities(base::StringPiece printer_name, return false; } ppdMarkDefaults(ppd); - MarkLpOptions(printer_name, ppd); + if (dest) + cupsMarkOptions(ppd, dest->num_options, dest->options); PrinterSemanticCapsAndDefaults caps; caps.collate_capable = true; diff --git a/chromium/printing/backend/cups_helper.h b/chromium/printing/backend/cups_helper.h index 4a261e26439..8d90531e5b5 100644 --- a/chromium/printing/backend/cups_helper.h +++ b/chromium/printing/backend/cups_helper.h @@ -36,7 +36,7 @@ class PRINTING_EXPORT HttpConnectionCUPS { // Helper function to parse and convert PPD capabilitites to // semantic options. PRINTING_EXPORT bool ParsePpdCapabilities( - base::StringPiece printer_name, + cups_dest_t* dest, base::StringPiece locale, base::StringPiece printer_capabilities, PrinterSemanticCapsAndDefaults* printer_info); diff --git a/chromium/printing/backend/cups_helper_unittest.cc b/chromium/printing/backend/cups_helper_unittest.cc index 53dc4602e99..990bad663b1 100644 --- a/chromium/printing/backend/cups_helper_unittest.cc +++ b/chromium/printing/backend/cups_helper_unittest.cc @@ -4,6 +4,7 @@ #include "printing/backend/cups_helper.h" +#include "build/build_config.h" #include "printing/backend/print_backend.h" #include "printing/mojom/print.mojom.h" #include "printing/print_settings.h" @@ -56,7 +57,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingNoColorDuplexShortEdge) { *CloseGroup: General)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.collate_capable); EXPECT_TRUE(caps.collate_default); EXPECT_EQ(caps.copies_max, 9999); @@ -86,7 +88,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingNoColorDuplexSimples) { *CloseGroup: General)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.collate_capable); EXPECT_TRUE(caps.collate_default); EXPECT_EQ(caps.copies_max, 9999); @@ -113,7 +116,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingNoColorNoDuplex) { *CloseGroup: General)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.collate_capable); EXPECT_TRUE(caps.collate_default); EXPECT_EQ(caps.copies_max, 9999); @@ -146,7 +150,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingColorTrueDuplexShortEdge) { *CloseGroup: General)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.collate_capable); EXPECT_TRUE(caps.collate_default); EXPECT_EQ(caps.copies_max, 9999); @@ -188,7 +193,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingColorFalseDuplexLongEdge) { *CloseGroup: General)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.collate_capable); EXPECT_TRUE(caps.collate_default); EXPECT_EQ(caps.copies_max, 9999); @@ -220,7 +226,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingPageSize) { *CloseUI: *PageSize)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); ASSERT_EQ(2UL, caps.papers.size()); EXPECT_EQ("Letter", caps.papers[0].vendor_id); EXPECT_EQ("US Letter", caps.papers[0].display_name); @@ -261,7 +268,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingPageSizeNoDefaultSpecified) { { PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "en-US", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"en-US", + kTestPpdData, &caps)); ASSERT_EQ(4UL, caps.papers.size()); EXPECT_EQ("Letter", caps.papers[3].vendor_id); EXPECT_EQ("US Letter", caps.papers[3].display_name); @@ -271,7 +279,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingPageSizeNoDefaultSpecified) { } { PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "en-UK", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"en-UK", + kTestPpdData, &caps)); ASSERT_EQ(4UL, caps.papers.size()); EXPECT_EQ("A4", caps.papers[1].vendor_id); EXPECT_EQ("ISO A4", caps.papers[1].display_name); @@ -294,7 +303,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingBrotherPrinters) { *CloseUI: *BRPrintQuality)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.color_changeable); EXPECT_TRUE(caps.color_default); EXPECT_EQ(BROTHER_BRSCRIPT3_COLOR, caps.color_model); @@ -313,7 +323,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingBrotherPrinters) { *CloseUI: *BRMonoColor)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.color_changeable); EXPECT_TRUE(caps.color_default); EXPECT_EQ(BROTHER_CUPS_COLOR, caps.color_model); @@ -332,7 +343,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingBrotherPrinters) { *CloseUI: *BRDuplex)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_THAT(caps.duplex_modes, testing::UnorderedElementsAre(mojom::DuplexMode::kSimplex, mojom::DuplexMode::kLongEdge, @@ -354,7 +366,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingHpPrinters) { *CloseUI: *HPColorMode)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.color_changeable); EXPECT_TRUE(caps.color_default); EXPECT_EQ(HP_COLOR_COLOR, caps.color_model); @@ -362,7 +375,13 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingHpPrinters) { VerifyCapabilityColorModels(caps); } -TEST(PrintBackendCupsHelperTest, TestPpdParsingEpsonPrinters) { +// TODO(crbug.com/1081705): Epson "Ink" attribute bloats prints on Linux. +#if defined(OS_LINUX) +#define MAYBE_TestPpdParsingEpsonPrinters DISABLED_TestPpdParsingEpsonPrinters +#else +#define MAYBE_TestPpdParsingEpsonPrinters TestPpdParsingEpsonPrinters +#endif +TEST(PrintBackendCupsHelperTest, MAYBE_TestPpdParsingEpsonPrinters) { constexpr char kTestPpdData[] = R"(*PPD-Adobe: "4.3" *ColorDevice: True @@ -377,7 +396,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingEpsonPrinters) { *CloseUI: *Ink)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.color_changeable); EXPECT_TRUE(caps.color_default); EXPECT_EQ(EPSON_INK_COLOR, caps.color_model); @@ -396,7 +416,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingSamsungPrinters) { *CloseUI: *ColorMode)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.color_changeable); EXPECT_TRUE(caps.color_default); EXPECT_EQ(COLORMODE_COLOR, caps.color_model); @@ -420,7 +441,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingSharpPrinters) { *CloseUI: *ARCMode)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.color_changeable); EXPECT_TRUE(caps.color_default); EXPECT_EQ(SHARP_ARCMODE_CMCOLOR, caps.color_model); @@ -442,7 +464,8 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingXeroxPrinters) { *CloseUI: *XRXColor)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); EXPECT_TRUE(caps.color_changeable); EXPECT_TRUE(caps.color_default); EXPECT_EQ(XEROX_XRXCOLOR_AUTOMATIC, caps.color_model); @@ -460,8 +483,9 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingCupsMaxCopies) { *CloseUI: *ColorMode)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); - EXPECT_EQ(caps.copies_max, 99); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); + EXPECT_EQ(99, caps.copies_max); } { @@ -473,9 +497,49 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingCupsMaxCopies) { *CloseUI: *ColorMode)"; PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities("test", "", kTestPpdData, &caps)); - EXPECT_EQ(caps.copies_max, 9999); + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); + EXPECT_EQ(9999, caps.copies_max); } } +TEST(PrintBackendCupsHelperTest, TestPpdSetsDestOptions) { + constexpr char kTestPpdData[] = + R"(*PPD-Adobe: "4.3" +*OpenUI *Duplex/2-Sided Printing: PickOne +*DefaultDuplex: DuplexTumble +*Duplex None/Off: " + <</Duplex false>>setpagedevice" +*Duplex DuplexNoTumble/LongEdge: " + </Duplex true/Tumble false>>setpagedevice" +*Duplex DuplexTumble/ShortEdge: " + <</Duplex true/Tumble true>>setpagedevice" +*CloseUI: *Duplex)"; + + cups_dest_t* dest; + int num_dests = 0; + num_dests = + cupsAddDest(/*name=*/"test_dest", /*instance=*/nullptr, num_dests, &dest); + ASSERT_EQ(1, num_dests); + + // Set long edge duplex mode in the destination options even though the PPD + // sets short edge duplex mode as the default. + cups_option_t* options = nullptr; + int num_options = 0; + num_options = + cupsAddOption("Duplex", "DuplexNoTumble", num_options, &options); + dest->num_options = num_options; + dest->options = options; + + PrinterSemanticCapsAndDefaults caps; + EXPECT_TRUE(ParsePpdCapabilities(dest, /*locale=*/"", kTestPpdData, &caps)); + EXPECT_THAT(caps.duplex_modes, + testing::UnorderedElementsAre(mojom::DuplexMode::kSimplex, + mojom::DuplexMode::kLongEdge, + mojom::DuplexMode::kShortEdge)); + EXPECT_EQ(mojom::DuplexMode::kLongEdge, caps.duplex_default); + + cupsFreeDests(num_dests, dest); +} + } // namespace printing diff --git a/chromium/printing/backend/print_backend_cups.cc b/chromium/printing/backend/print_backend_cups.cc index db324056841..0f033a350c0 100644 --- a/chromium/printing/backend/print_backend_cups.cc +++ b/chromium/printing/backend/print_backend_cups.cc @@ -164,7 +164,8 @@ bool PrintBackendCUPS::GetPrinterSemanticCapsAndDefaults( if (!GetPrinterCapsAndDefaults(printer_name, &info)) return false; - return ParsePpdCapabilities(printer_name, locale(), info.printer_capabilities, + ScopedDestination dest = GetNamedDest(printer_name); + return ParsePpdCapabilities(dest.get(), locale(), info.printer_capabilities, printer_info); } |