summaryrefslogtreecommitdiff
path: root/chromium/printing/backend
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/printing/backend')
-rw-r--r--chromium/printing/backend/cups_helper.cc95
-rw-r--r--chromium/printing/backend/cups_helper.h2
-rw-r--r--chromium/printing/backend/cups_helper_unittest.cc106
-rw-r--r--chromium/printing/backend/print_backend_cups.cc3
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);
}