blob: 93db1a80a360702a36f2d3113c9a83105bf7fffe [file] [log] [blame]
// Copyright (c) 2011 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/printing_context.h"
#include <utility>
#include "base/check.h"
#include "base/notreached.h"
#include "build/build_config.h"
#include "printing/buildflags/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"
#include "printing/printing_context_factory_for_test.h"
#include "printing/units.h"
#if BUILDFLAG(ENABLE_OOP_PRINTING)
#include "printing/printing_features.h"
#endif
namespace printing {
namespace {
PrintingContextFactoryForTest* g_printing_context_factory_for_test = nullptr;
} // namespace
PrintingContext::PrintingContext(Delegate* delegate)
: settings_(std::make_unique<PrintSettings>()),
delegate_(delegate),
in_print_job_(false),
abort_printing_(false) {
DCHECK(delegate_);
}
PrintingContext::~PrintingContext() = default;
// static
std::unique_ptr<PrintingContext> PrintingContext::Create(
Delegate* delegate,
bool skip_system_calls) {
return g_printing_context_factory_for_test
? g_printing_context_factory_for_test->CreatePrintingContext(
delegate, skip_system_calls)
: PrintingContext::CreateImpl(delegate, skip_system_calls);
}
// static
void PrintingContext::SetPrintingContextFactoryForTest(
PrintingContextFactoryForTest* factory) {
g_printing_context_factory_for_test = factory;
}
void PrintingContext::set_margin_type(mojom::MarginType type) {
DCHECK(type != mojom::MarginType::kCustomMargins);
settings_->set_margin_type(type);
}
void PrintingContext::set_is_modifiable(bool is_modifiable) {
settings_->set_is_modifiable(is_modifiable);
}
const PrintSettings& PrintingContext::settings() const {
DCHECK(!in_print_job_);
return *settings_;
}
void PrintingContext::ResetSettings() {
ReleaseContext();
settings_->Clear();
in_print_job_ = false;
abort_printing_ = false;
}
std::unique_ptr<PrintSettings> PrintingContext::TakeAndResetSettings() {
std::unique_ptr<PrintSettings> result = std::move(settings_);
settings_ = std::make_unique<PrintSettings>();
return result;
}
mojom::ResultCode PrintingContext::OnError() {
mojom::ResultCode result = abort_printing_ ? mojom::ResultCode::kCanceled
: mojom::ResultCode::kFailed;
ResetSettings();
return result;
}
void PrintingContext::UsePdfSettings() {
base::Value::Dict pdf_settings;
pdf_settings.Set(kSettingHeaderFooterEnabled, false);
pdf_settings.Set(kSettingShouldPrintBackgrounds, false);
pdf_settings.Set(kSettingShouldPrintSelectionOnly, false);
pdf_settings.Set(kSettingMarginsType,
static_cast<int>(mojom::MarginType::kNoMargins));
pdf_settings.Set(kSettingCollate, true);
pdf_settings.Set(kSettingCopies, 1);
pdf_settings.Set(kSettingColor, static_cast<int>(mojom::ColorModel::kColor));
// DPI value should match GetPdfCapabilities().
pdf_settings.Set(kSettingDpiHorizontal, kDefaultPdfDpi);
pdf_settings.Set(kSettingDpiVertical, kDefaultPdfDpi);
pdf_settings.Set(kSettingDuplexMode,
static_cast<int>(printing::mojom::DuplexMode::kSimplex));
pdf_settings.Set(kSettingLandscape, false);
pdf_settings.Set(kSettingDeviceName, "");
pdf_settings.Set(kSettingPrinterType,
static_cast<int>(mojom::PrinterType::kPdf));
pdf_settings.Set(kSettingScaleFactor, 100);
pdf_settings.Set(kSettingRasterizePdf, false);
pdf_settings.Set(kSettingPagesPerSheet, 1);
mojom::ResultCode result = UpdatePrintSettings(std::move(pdf_settings));
// TODO(thestig): Downgrade these to DCHECKs after shipping these CHECKs to
// production without any failures.
CHECK_EQ(result, mojom::ResultCode::kSuccess);
// UsePdfSettings() should never fail and the returned DPI should always be a
// well-known value that is safe to use as a divisor.
#if BUILDFLAG(IS_MAC)
CHECK_EQ(settings_->device_units_per_inch(), kPointsPerInch);
#else
CHECK_EQ(settings_->device_units_per_inch(), kDefaultPdfDpi);
#endif
}
mojom::ResultCode PrintingContext::UpdatePrintSettings(
base::Value::Dict job_settings) {
ResetSettings();
{
std::unique_ptr<PrintSettings> settings =
PrintSettingsFromJobSettings(job_settings);
if (!settings) {
NOTREACHED();
return OnError();
}
settings_ = std::move(settings);
}
mojom::PrinterType printer_type = static_cast<mojom::PrinterType>(
job_settings.FindInt(kSettingPrinterType).value());
if (printer_type == mojom::PrinterType::kPrivetDeprecated ||
printer_type == mojom::PrinterType::kCloudDeprecated) {
NOTREACHED();
return OnError();
}
bool open_in_external_preview =
job_settings.contains(kSettingOpenPDFInPreview);
if (!open_in_external_preview &&
(printer_type == mojom::PrinterType::kPdf ||
printer_type == mojom::PrinterType::kExtension)) {
if (printer_type == mojom::PrinterType::kExtension)
settings_->set_dpi(kDefaultPdfDpi);
gfx::Size paper_size(GetPdfPaperSizeDeviceUnits());
if (!settings_->requested_media().size_microns.IsEmpty()) {
float device_microns_per_device_unit =
static_cast<float>(kMicronsPerInch) /
settings_->device_units_per_inch();
paper_size =
gfx::Size(settings_->requested_media().size_microns.width() /
device_microns_per_device_unit,
settings_->requested_media().size_microns.height() /
device_microns_per_device_unit);
}
gfx::Rect paper_rect(0, 0, paper_size.width(), paper_size.height());
settings_->SetPrinterPrintableArea(paper_size, paper_rect, true);
return mojom::ResultCode::kSuccess;
}
PrinterSettings printer_settings {
#if BUILDFLAG(IS_MAC)
.external_preview = open_in_external_preview,
#endif
.show_system_dialog =
job_settings.FindBool(kSettingShowSystemDialog).value_or(false),
#if BUILDFLAG(IS_WIN)
.page_count = job_settings.FindInt(kSettingPreviewPageCount).value_or(0)
#endif
};
return UpdatePrinterSettings(printer_settings);
}
#if BUILDFLAG(IS_CHROMEOS)
mojom::ResultCode PrintingContext::UpdatePrintSettingsFromPOD(
std::unique_ptr<PrintSettings> job_settings) {
ResetSettings();
settings_ = std::move(job_settings);
return UpdatePrinterSettings({.show_system_dialog = false});
}
#endif
void PrintingContext::ApplyPrintSettings(const PrintSettings& settings) {
*settings_ = settings;
}
} // namespace printing