#ifndef CHROME_SERVICES_PRINTING_PRINT_BACKEND_SERVICE_IMPL_H_
#define CHROME_SERVICES_PRINTING_PRINT_BACKEND_SERVICE_IMPL_H_
#include <memory>
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/services/printing/public/mojom/print_backend_service.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "printing/backend/print_backend.h"
#include "printing/buildflags/buildflags.h"
#include "printing/mojom/print.mojom.h"
#include "printing/print_settings.h"
#include "printing/printed_document.h"
#include "printing/printing_context.h"
#include "ui/gfx/native_ui_types.h"
#if BUILDFLAG(IS_WIN)
#include "base/types/expected.h"
#include "chrome/services/printing/public/mojom/printer_xml_parser.mojom.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#endif
#if !BUILDFLAG(ENABLE_OOP_PRINTING)
#error "Out-of-process printing must be enabled."
#endif
namespace crash_keys {
class ScopedPrinterInfo;
}
namespace gfx {
class Rect;
class Size;
}
namespace printing {
class SandboxedPrintBackendHostImpl : public mojom::SandboxedPrintBackendHost {
public:
explicit SandboxedPrintBackendHostImpl(
mojo::PendingReceiver<mojom::SandboxedPrintBackendHost> receiver);
SandboxedPrintBackendHostImpl(const SandboxedPrintBackendHostImpl&) = delete;
SandboxedPrintBackendHostImpl& operator=(
const SandboxedPrintBackendHostImpl&) = delete;
~SandboxedPrintBackendHostImpl() override;
private:
void BindBackend(
mojo::PendingReceiver<mojom::PrintBackendService> receiver) override;
mojo::Receiver<mojom::SandboxedPrintBackendHost> receiver_;
std::unique_ptr<mojom::PrintBackendService> print_backend_service_;
};
class UnsandboxedPrintBackendHostImpl
: public mojom::UnsandboxedPrintBackendHost {
public:
explicit UnsandboxedPrintBackendHostImpl(
mojo::PendingReceiver<mojom::UnsandboxedPrintBackendHost> receiver);
UnsandboxedPrintBackendHostImpl(const UnsandboxedPrintBackendHostImpl&) =
delete;
UnsandboxedPrintBackendHostImpl& operator=(
const UnsandboxedPrintBackendHostImpl&) = delete;
~UnsandboxedPrintBackendHostImpl() override;
private:
void BindBackend(
mojo::PendingReceiver<mojom::PrintBackendService> receiver) override;
mojo::Receiver<mojom::UnsandboxedPrintBackendHost> receiver_;
std::unique_ptr<mojom::PrintBackendService> print_backend_service_;
};
class PrintBackendServiceImpl : public mojom::PrintBackendService {
public:
struct StartPrintingResult {
mojom::ResultCode result;
int job_id;
};
explicit PrintBackendServiceImpl(
mojo::PendingReceiver<mojom::PrintBackendService> receiver);
PrintBackendServiceImpl(const PrintBackendServiceImpl&) = delete;
PrintBackendServiceImpl& operator=(const PrintBackendServiceImpl&) = delete;
~PrintBackendServiceImpl() override;
protected:
void InitCommon(
#if BUILDFLAG(IS_WIN)
const std::string& locale,
mojo::PendingRemote<mojom::PrinterXmlParser> remote
#else
const std::string& locale
#endif
);
private:
friend class PrintBackendServiceTestImpl;
class DocumentHelper;
struct ContextContainer;
class PrintingContextDelegate : public PrintingContext::Delegate {
public:
PrintingContextDelegate();
PrintingContextDelegate(const PrintingContextDelegate&) = delete;
PrintingContextDelegate& operator=(const PrintingContextDelegate&) = delete;
~PrintingContextDelegate() override;
gfx::NativeView GetParentView() override;
std::string GetAppLocale() override;
#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG)
void SetParentWindow(uint32_t parent_window_id);
#endif
void SetAppLocale(const std::string& locale);
private:
#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG)
gfx::NativeView parent_native_view_ = gfx::NativeView();
#endif
std::string locale_;
};
void Init(
#if BUILDFLAG(IS_WIN)
const std::string& locale,
mojo::PendingRemote<mojom::PrinterXmlParser> remote
#else
const std::string& locale
#endif
) override;
void Poke() override;
void EnumeratePrinters(
mojom::PrintBackendService::EnumeratePrintersCallback callback) override;
void GetDefaultPrinterName(
mojom::PrintBackendService::GetDefaultPrinterNameCallback callback)
override;
#if BUILDFLAG(IS_CHROMEOS)
void GetPrinterSemanticCapsAndDefaults(
const std::string& printer_name,
mojom::PrintBackendService::GetPrinterSemanticCapsAndDefaultsCallback
callback) override;
#endif
void FetchCapabilities(
const std::string& printer_name,
mojom::PrintBackendService::FetchCapabilitiesCallback callback) override;
#if BUILDFLAG(IS_WIN)
void GetPaperPrintableArea(
const std::string& printer_name,
const PrintSettings::RequestedMedia& media,
mojom::PrintBackendService::GetPaperPrintableAreaCallback callback)
override;
#endif
void EstablishPrintingContext(uint32_t context_id
#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG)
,
uint32_t parent_window_id
#endif
) override;
void UseDefaultSettings(
uint32_t context_id,
mojom::PrintBackendService::UseDefaultSettingsCallback callback) override;
#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG)
void AskUserForSettings(
uint32_t context_id,
int max_pages,
bool has_selection,
bool is_scripted,
mojom::PrintBackendService::AskUserForSettingsCallback callback) override;
#endif
void UpdatePrintSettings(
uint32_t context_id,
base::Value::Dict job_settings,
mojom::PrintBackendService::UpdatePrintSettingsCallback callback)
override;
void StartPrinting(
uint32_t context_id,
int document_cookie,
const std::u16string& document_name,
#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG)
const std::optional<PrintSettings>& settings,
#endif
mojom::PrintBackendService::StartPrintingCallback callback) override;
#if BUILDFLAG(IS_WIN)
void RenderPrintedPage(
int32_t document_cookie,
uint32_t page_index,
mojom::MetafileDataType page_data_type,
base::ReadOnlySharedMemoryRegion serialized_page,
const gfx::Size& page_size,
const gfx::Rect& page_content_rect,
float shrink_factor,
mojom::PrintBackendService::RenderPrintedPageCallback callback) override;
#endif
void RenderPrintedDocument(
int32_t document_cookie,
uint32_t page_count,
mojom::MetafileDataType data_type,
base::ReadOnlySharedMemoryRegion serialized_doc,
mojom::PrintBackendService::RenderPrintedDocumentCallback callback)
override;
void DocumentDone(
int32_t document_cookie,
mojom::PrintBackendService::DocumentDoneCallback callback) override;
void Cancel(int32_t document_cookie,
mojom::PrintBackendService::CancelCallback callback) override;
#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG)
void OnDidAskUserForSettings(
uint32_t context_id,
mojom::PrintBackendService::AskUserForSettingsCallback callback,
mojom::ResultCode result);
#endif
void OnDidStartPrintingReadyDocument(DocumentHelper& document_helper,
StartPrintingResult printing_result);
void OnDidDocumentDone(
DocumentHelper& document_helper,
mojom::PrintBackendService::DocumentDoneCallback callback,
mojom::ResultCode result);
void OnDidCancel(DocumentHelper& document_helper,
mojom::PrintBackendService::CancelCallback callback);
std::unique_ptr<PrintingContextDelegate> CreatePrintingContextDelegate();
PrintingContext* GetPrintingContext(uint32_t context_id);
DocumentHelper* GetDocumentHelper(int document_cookie);
void RemoveDocumentHelper(DocumentHelper& document_helper);
#if BUILDFLAG(IS_WIN)
base::expected<XpsCapabilities, mojom::ResultCode> GetXpsCapabilities(
const std::string& printer_name);
#endif
std::string locale_;
std::unique_ptr<crash_keys::ScopedPrinterInfo> crash_keys_;
scoped_refptr<PrintBackend> print_backend_;
base::flat_map<uint32_t, std::unique_ptr<ContextContainer>>
persistent_printing_contexts_;
SEQUENCE_CHECKER(main_sequence_checker_);
std::vector<std::unique_ptr<DocumentHelper>> documents_;
mojo::Receiver<mojom::PrintBackendService> receiver_;
#if BUILDFLAG(IS_WIN)
mojo::Remote<mojom::PrinterXmlParser> xml_parser_remote_;
#endif
};
}
#endif