1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PRINTING_BACKEND_PRINT_BACKEND_H_
#define PRINTING_BACKEND_PRINT_BACKEND_H_
#include <stdint.h>
#include <map>
#include <optional>
#include <string>
#include <vector>
#include "base/component_export.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
#include "printing/mojom/print.mojom.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#if BUILDFLAG(IS_WIN)
#include "base/types/expected.h"
#endif // BUILDFLAG(IS_WIN)
// This is the interface for platform-specific code for a print backend
namespace printing {
using PrinterBasicInfoOptions = std::map<std::string, std::string>;
struct COMPONENT_EXPORT(PRINT_BACKEND) PrinterBasicInfo {
PrinterBasicInfo();
PrinterBasicInfo(const std::string& printer_name,
const std::string& display_name,
const std::string& printer_description,
const PrinterBasicInfoOptions& options);
PrinterBasicInfo(const PrinterBasicInfo& other);
~PrinterBasicInfo();
bool operator==(const PrinterBasicInfo& other) const;
// The name of the printer as understood by OS.
std::string printer_name;
// The name of the printer as shown in Print Preview.
// For Windows SetGetDisplayNameFunction() can be used to set the setter of
// this field.
std::string display_name;
std::string printer_description;
PrinterBasicInfoOptions options;
};
using PrinterList = std::vector<PrinterBasicInfo>;
#if BUILDFLAG(IS_CHROMEOS)
struct COMPONENT_EXPORT(PRINT_BACKEND) AdvancedCapabilityValue {
AdvancedCapabilityValue();
AdvancedCapabilityValue(const std::string& name,
const std::string& display_name);
AdvancedCapabilityValue(const AdvancedCapabilityValue& other);
~AdvancedCapabilityValue();
bool operator==(const AdvancedCapabilityValue& other) const;
// IPP identifier of the value.
std::string name;
// Localized name for the value.
std::string display_name;
};
struct COMPONENT_EXPORT(PRINT_BACKEND) AdvancedCapability {
enum class Type : uint8_t { kBoolean, kFloat, kInteger, kString };
AdvancedCapability();
AdvancedCapability(const std::string& name, AdvancedCapability::Type type);
AdvancedCapability(const std::string& name,
const std::string& display_name,
AdvancedCapability::Type type,
const std::string& default_value,
const std::vector<AdvancedCapabilityValue>& values);
AdvancedCapability(const AdvancedCapability& other);
~AdvancedCapability();
bool operator==(const AdvancedCapability& other) const;
// IPP identifier of the attribute.
std::string name;
// Localized name for the attribute.
std::string display_name;
// Attribute type.
AdvancedCapability::Type type;
// Default value.
std::string default_value;
// Values for enumerated attributes.
std::vector<AdvancedCapabilityValue> values;
};
using AdvancedCapabilities = std::vector<AdvancedCapability>;
// Describes the margins for a paper size.
struct COMPONENT_EXPORT(PRINT_BACKEND) PaperMargins {
PaperMargins();
PaperMargins(int32_t top_margin_um,
int32_t right_margin_um,
int32_t bottom_margin_um,
int32_t left_margin_um);
PaperMargins(const PaperMargins& other);
PaperMargins& operator=(const PaperMargins& other);
~PaperMargins();
bool operator==(const PaperMargins& other) const;
// Defines margins from their edges.
int32_t top_margin_um;
int32_t right_margin_um;
int32_t bottom_margin_um;
int32_t left_margin_um;
};
#endif // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_WIN)
struct COMPONENT_EXPORT(PRINT_BACKEND) PageOutputQualityAttribute {
PageOutputQualityAttribute();
PageOutputQualityAttribute(const std::string& display_name,
const std::string& name);
~PageOutputQualityAttribute();
bool operator==(const PageOutputQualityAttribute& other) const;
bool operator<(const PageOutputQualityAttribute& other) const;
// Localized name of the page output quality attribute.
std::string display_name;
// Internal ID of the page output quality attribute.
std::string name;
};
using PageOutputQualityAttributes = std::vector<PageOutputQualityAttribute>;
struct COMPONENT_EXPORT(PRINT_BACKEND) PageOutputQuality {
PageOutputQuality();
PageOutputQuality(PageOutputQualityAttributes qualities,
std::optional<std::string> default_quality);
PageOutputQuality(const PageOutputQuality& other);
~PageOutputQuality();
// All options of page output quality.
PageOutputQualityAttributes qualities;
// Default option of page output quality.
// TODO(crbug.com/40212677): Need populate this option in the next CLs.
std::optional<std::string> default_quality;
};
#if defined(UNIT_TEST)
COMPONENT_EXPORT(PRINT_BACKEND)
bool operator==(const PageOutputQuality& quality1,
const PageOutputQuality& quality2);
#endif // defined(UNIT_TEST)
struct COMPONENT_EXPORT(PRINT_BACKEND) XpsCapabilities {
XpsCapabilities();
XpsCapabilities(const XpsCapabilities&) = delete;
XpsCapabilities& operator=(const XpsCapabilities&) = delete;
XpsCapabilities(XpsCapabilities&& other) noexcept;
XpsCapabilities& operator=(XpsCapabilities&& other) noexcept;
~XpsCapabilities();
std::optional<PageOutputQuality> page_output_quality;
};
#endif // BUILDFLAG(IS_WIN)
struct COMPONENT_EXPORT(PRINT_BACKEND) PrinterSemanticCapsAndDefaults {
PrinterSemanticCapsAndDefaults();
PrinterSemanticCapsAndDefaults(const PrinterSemanticCapsAndDefaults& other);
~PrinterSemanticCapsAndDefaults();
bool collate_capable = false;
bool collate_default = false;
// If `copies_max` > 1, copies are supported.
// If `copies_max` = 1, copies are not supported.
// `copies_max` should never be < 1.
int32_t copies_max = 1;
std::vector<mojom::DuplexMode> duplex_modes;
mojom::DuplexMode duplex_default = mojom::DuplexMode::kUnknownDuplexMode;
bool color_changeable = false;
bool color_default = false;
mojom::ColorModel color_model = mojom::ColorModel::kUnknownColorModel;
mojom::ColorModel bw_model = mojom::ColorModel::kUnknownColorModel;
class COMPONENT_EXPORT(PRINT_BACKEND) Paper {
public:
Paper();
Paper(const std::string& display_name,
const std::string& vendor_id,
const gfx::Size& size_um);
Paper(const std::string& display_name,
const std::string& vendor_id,
const gfx::Size& size_um,
const gfx::Rect& printable_area_um);
Paper(const std::string& display_name,
const std::string& vendor_id,
const gfx::Size& size_um,
const gfx::Rect& printable_area_um,
int max_height_um);
Paper(const std::string& display_name,
const std::string& vendor_id,
const gfx::Size& size_um,
const gfx::Rect& printable_area_um,
int max_height_um,
bool has_borderless_variant
#if BUILDFLAG(IS_CHROMEOS)
,
std::optional<PaperMargins> supported_margins_um = std::nullopt
#endif // BUILDFLAG(IS_CHROMEOS)
);
~Paper();
// The compiler has decided that this class is now "complex" and thus
// requires an explicit, out-of-line copy constructor.
Paper(const Paper& other);
Paper& operator=(const Paper& other);
bool operator==(const Paper& other) const;
const std::string& display_name() const { return display_name_; }
const std::string& vendor_id() const { return vendor_id_; }
const gfx::Size& size_um() const { return size_um_; }
const gfx::Rect& printable_area_um() const { return printable_area_um_; }
int max_height_um() const { return max_height_um_; }
bool has_borderless_variant() const { return has_borderless_variant_; }
void set_display_name(const std::string& display_name) {
display_name_ = display_name;
}
void set_vendor_id(const std::string& vendor_id) { vendor_id_ = vendor_id; }
void set_has_borderless_variant(bool has_borderless_variant) {
has_borderless_variant_ = has_borderless_variant;
}
void set_printable_area_to_paper_size() {
printable_area_um_ = gfx::Rect(size_um_);
}
bool SupportsCustomSize() const;
// Return true if `other_um` is the same size as this object or if this
// object supports a custom size and `other_um` falls within the custom size
// of this object. Else, return false.
bool IsSizeWithinBounds(const gfx::Size& other_um) const;
#if BUILDFLAG(IS_CHROMEOS)
const std::optional<PaperMargins>& supported_margins_um() const {
return supported_margins_um_;
}
#endif // BUILDFLAG(IS_CHROMEOS)
private:
std::string display_name_;
std::string vendor_id_;
gfx::Size size_um_;
// Origin (x,y) is at the bottom-left.
gfx::Rect printable_area_um_;
// This is used to represent a printer that supports a variable height.
// This will either be equal to 0 (which indicates the height is not
// variable) or this will be larger than the height in `size_um` (which
// indicates the height can be anywhere in that range). Note that
// `printable_area_um` is always based on `size_um`.
int max_height_um_ = 0;
// True if this paper size can be used borderless (with the printable area
// covering the entire page) in addition to bordered. If a paper size
// *only* supports borderless and has no variant with margins, this field
// will be false and `printable_area_um` will cover the entire page.
bool has_borderless_variant_ = false;
#if BUILDFLAG(IS_CHROMEOS)
// This field represents supported margins by the printer for this paper.
// If this field is nullopt, it means that it was not possible to determine
// the margins.
std::optional<PaperMargins> supported_margins_um_;
#endif // BUILDFLAG(IS_CHROMEOS)
};
using Papers = std::vector<Paper>;
Papers papers;
Papers user_defined_papers;
Paper default_paper;
// Describes a media type (plain paper, photo paper, etc.)
// TODO(crbug.com/40274266): Support media types on platforms other than
// ChromeOS
struct COMPONENT_EXPORT(PRINT_BACKEND) MediaType {
std::string display_name;
std::string vendor_id;
bool operator==(const MediaType& other) const;
};
using MediaTypes = std::vector<MediaType>;
MediaTypes media_types;
MediaType default_media_type;
std::vector<gfx::Size> dpis;
gfx::Size default_dpi;
#if BUILDFLAG(IS_CHROMEOS)
bool pin_supported = false;
AdvancedCapabilities advanced_capabilities;
// Print scaling capability
std::vector<mojom::PrintScalingType> print_scaling_types;
mojom::PrintScalingType print_scaling_type_default =
mojom::PrintScalingType::kUnknownPrintScalingType;
#endif // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_WIN)
std::optional<PageOutputQuality> page_output_quality;
#endif // BUILDFLAG(IS_WIN)
};
#if defined(UNIT_TEST)
COMPONENT_EXPORT(PRINT_BACKEND)
bool operator==(const PrinterSemanticCapsAndDefaults& caps1,
const PrinterSemanticCapsAndDefaults& caps2);
#endif // defined(UNIT_TEST)
struct COMPONENT_EXPORT(PRINT_BACKEND) PrinterCapsAndDefaults {
PrinterCapsAndDefaults();
PrinterCapsAndDefaults(const PrinterCapsAndDefaults& other);
~PrinterCapsAndDefaults();
std::string printer_capabilities;
std::string caps_mime_type;
std::string printer_defaults;
std::string defaults_mime_type;
};
// PrintBackend class will provide interface for different print backends
// (Windows, CUPS) to implement. User will call CreateInstance() to
// obtain available print backend.
// Please note, that PrintBackend is not platform specific, but rather
// print system specific. For example, CUPS is available on both Linux and Mac,
// but not available on ChromeOS, etc. This design allows us to add more
// functionality on some platforms, while reusing core (CUPS) functions.
class COMPONENT_EXPORT(PRINT_BACKEND) PrintBackend
: public base::RefCountedThreadSafe<PrintBackend> {
public:
// Enumerates the list of installed local and network printers. It will
// return success when the available installed printers have been enumerated
// into `printer_list`. Note that `printer_list` should be empty prior to
// this call. If there are no printers installed then it will still return
// success, and `printer_list` remains empty. The result code will return
// one of the error result codes when there is a failure in generating the
// list.
virtual mojom::ResultCode EnumeratePrinters(PrinterList& printer_list) = 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().
virtual mojom::ResultCode GetPrinterBasicInfo(
const std::string& printer_name,
PrinterBasicInfo* printer_info) = 0;
// Gets the semantic capabilities and defaults for a specific printer.
// This is usually a lighter implementation than GetPrinterCapsAndDefaults().
// Implementations must check `printer_name` validity in the same way as
// IsValidPrinter().
// NOTE: on some old platforms (WinXP without XPS pack)
// GetPrinterCapsAndDefaults() will fail, while this function will succeed.
virtual mojom::ResultCode GetPrinterSemanticCapsAndDefaults(
const std::string& printer_name,
PrinterSemanticCapsAndDefaults* printer_info) = 0;
#if BUILDFLAG(IS_WIN)
// Gets the capabilities and defaults for a specific printer.
// TODO(crbug.com/40100562): Evaluate if this code is useful and delete if
// not.
virtual mojom::ResultCode GetPrinterCapsAndDefaults(
const std::string& printer_name,
PrinterCapsAndDefaults* printer_info) = 0;
// Gets the printable area for just a single paper size. Returns nullopt if
// there is any error in retrieving this data.
// TODO(crbug.com/40260379): Remove this if the printable areas can be made
// fully available from `GetPrinterSemanticCapsAndDefaults()`.
virtual std::optional<gfx::Rect> GetPaperPrintableArea(
const std::string& printer_name,
const std::string& paper_vendor_id,
const gfx::Size& paper_size_um) = 0;
#endif
// Gets the information about driver for a specific printer. A maximum of
// 4 elements can be in the returned result, due to limitations on how this
// is intended to be used for crash keys by `ScopedPrinterInfo`.
virtual std::vector<std::string> GetPrinterDriverInfo(
const std::string& printer_name) = 0;
// Returns true if printer_name points to a valid printer.
virtual bool IsValidPrinter(const std::string& printer_name) = 0;
#if BUILDFLAG(IS_WIN)
// This method uses the XPS API to get the printer capabilities.
// Returns raw XML string on success, or mojom::ResultCode on failure.
// This method is virtual to support testing.
virtual base::expected<std::string, mojom::ResultCode>
GetXmlPrinterCapabilitiesForXpsDriver(const std::string& printer_name);
#endif // BUILDFLAG(IS_WIN)
// Allocates a print backend.
static scoped_refptr<PrintBackend> CreateInstance(const std::string& locale);
// Test method to override the print backend for testing. Caller should
// retain ownership.
static void SetPrintBackendForTesting(PrintBackend* print_backend);
protected:
friend class base::RefCountedThreadSafe<PrintBackend>;
PrintBackend();
virtual ~PrintBackend();
// Provide the actual backend for CreateInstance().
static scoped_refptr<PrintBackend> CreateInstanceImpl(
const std::string& locale);
};
} // namespace printing
#endif // PRINTING_BACKEND_PRINT_BACKEND_H_
|