blob: 9e67479c44a71bf8fd34313610089871d1c85c5e [file] [log] [blame]
// Copyright 2020 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 "chrome/services/printing/print_backend_service_impl.h"
#include <memory>
#include <string>
#include <utility>
#include "base/logging.h"
#include "base/notreached.h"
#include "build/build_config.h"
#include "chrome/services/printing/public/mojom/print_backend_service.mojom.h"
#include "components/crash/core/common/crash_keys.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "printing/backend/print_backend.h"
#include "printing/mojom/print.mojom.h"
#if defined(OS_MAC)
#include "base/threading/thread_restrictions.h"
#include "chrome/common/printing/printer_capabilities_mac.h"
#endif
namespace printing {
PrintBackendServiceImpl::PrintBackendServiceImpl(
mojo::PendingReceiver<mojom::PrintBackendService> receiver)
: receiver_(this, std::move(receiver)) {}
PrintBackendServiceImpl::~PrintBackendServiceImpl() = default;
void PrintBackendServiceImpl::Init(const std::string& locale) {
print_backend_ = PrintBackend::CreateInstance(locale);
}
// TODO(crbug.com/1225111) Do nothing, this is just to assist an idle timeout
// change by providing a low-cost call to ensure it is applied.
void PrintBackendServiceImpl::Poke() {}
void PrintBackendServiceImpl::EnumeratePrinters(
mojom::PrintBackendService::EnumeratePrintersCallback callback) {
if (!print_backend_) {
DLOG(ERROR)
<< "Print backend instance has not been initialized for locale.";
std::move(callback).Run(
mojom::PrinterListResult::NewResultCode(mojom::ResultCode::kFailed));
return;
}
PrinterList printer_list;
mojom::ResultCode result = print_backend_->EnumeratePrinters(&printer_list);
if (result != mojom::ResultCode::kSuccess) {
std::move(callback).Run(mojom::PrinterListResult::NewResultCode(result));
return;
}
std::move(callback).Run(
mojom::PrinterListResult::NewPrinterList(std::move(printer_list)));
}
void PrintBackendServiceImpl::GetDefaultPrinterName(
mojom::PrintBackendService::GetDefaultPrinterNameCallback callback) {
if (!print_backend_) {
DLOG(ERROR)
<< "Print backend instance has not been initialized for locale.";
std::move(callback).Run(mojom::DefaultPrinterNameResult::NewResultCode(
mojom::ResultCode::kFailed));
return;
}
std::string default_printer;
mojom::ResultCode result =
print_backend_->GetDefaultPrinterName(default_printer);
if (result != mojom::ResultCode::kSuccess) {
std::move(callback).Run(
mojom::DefaultPrinterNameResult::NewResultCode(result));
return;
}
std::move(callback).Run(
mojom::DefaultPrinterNameResult::NewDefaultPrinterName(default_printer));
}
void PrintBackendServiceImpl::GetPrinterSemanticCapsAndDefaults(
const std::string& printer_name,
mojom::PrintBackendService::GetPrinterSemanticCapsAndDefaultsCallback
callback) {
if (!print_backend_) {
DLOG(ERROR)
<< "Print backend instance has not been initialized for locale.";
std::move(callback).Run(
mojom::PrinterSemanticCapsAndDefaultsResult::NewResultCode(
mojom::ResultCode::kFailed));
return;
}
crash_keys_ = std::make_unique<crash_keys::ScopedPrinterInfo>(
print_backend_->GetPrinterDriverInfo(printer_name));
PrinterSemanticCapsAndDefaults printer_caps;
const mojom::ResultCode result =
print_backend_->GetPrinterSemanticCapsAndDefaults(printer_name,
&printer_caps);
if (result != mojom::ResultCode::kSuccess) {
std::move(callback).Run(
mojom::PrinterSemanticCapsAndDefaultsResult::NewResultCode(result));
return;
}
std::move(callback).Run(
mojom::PrinterSemanticCapsAndDefaultsResult::NewPrinterCaps(
std::move(printer_caps)));
}
void PrintBackendServiceImpl::FetchCapabilities(
const std::string& printer_name,
mojom::PrintBackendService::FetchCapabilitiesCallback callback) {
if (!print_backend_) {
DLOG(ERROR)
<< "Print backend instance has not been initialized for locale.";
std::move(callback).Run(mojom::PrinterCapsAndInfoResult::NewResultCode(
mojom::ResultCode::kFailed));
return;
}
crash_keys_ = std::make_unique<crash_keys::ScopedPrinterInfo>(
print_backend_->GetPrinterDriverInfo(printer_name));
PrinterSemanticCapsAndDefaults::Papers user_defined_papers;
#if defined(OS_MAC)
{
// Blocking is needed here for when macOS reads paper sizes from file.
//
// Fetching capabilities in the browser process happens from the thread
// pool with the MayBlock() trait for macOS. However this call can also
// run from a utility process's main thread where blocking is not
// implicitly allowed. In order to preserve ordering, the utility process
// must process this synchronously by blocking.
//
// TODO(crbug.com/1163635): Investigate whether utility process main
// thread should be allowed to block like in-process workers are.
base::ScopedAllowBlocking allow_blocking;
user_defined_papers = GetMacCustomPaperSizes();
}
#endif
PrinterBasicInfo printer_info;
mojom::ResultCode result =
print_backend_->GetPrinterBasicInfo(printer_name, &printer_info);
if (result != mojom::ResultCode::kSuccess) {
std::move(callback).Run(
mojom::PrinterCapsAndInfoResult::NewResultCode(result));
return;
}
PrinterSemanticCapsAndDefaults caps;
result =
print_backend_->GetPrinterSemanticCapsAndDefaults(printer_name, &caps);
if (result != mojom::ResultCode::kSuccess) {
std::move(callback).Run(
mojom::PrinterCapsAndInfoResult::NewResultCode(result));
return;
}
mojom::PrinterCapsAndInfoPtr caps_and_info = mojom::PrinterCapsAndInfo::New(
std::move(printer_info), std::move(user_defined_papers), std::move(caps));
std::move(callback).Run(
mojom::PrinterCapsAndInfoResult::NewPrinterCapsAndInfo(
std::move(caps_and_info)));
}
} // namespace printing