blob: 282291dfa3cc1ce01bbe2d5ba4a99e3152f32f45 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OOP_H_
#define CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OOP_H_
#include <string>
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "chrome/browser/printing/print_job_worker.h"
#include "chrome/services/printing/public/mojom/print_backend_service.mojom.h"
#include "printing/buildflags/buildflags.h"
#include "printing/mojom/print.mojom.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#if !BUILDFLAG(ENABLE_OOP_PRINTING)
#error "OOP printing must be enabled"
#endif
namespace printing {
class PrintedDocument;
// Worker thread code. It manages the PrintingContext and offloads all system
// driver interactions to the Print Backend service. This is the object that
// generates most NOTIFY_PRINT_JOB_EVENT notifications, but they are generated
// through a NotificationTask task to be executed from the right thread, the UI
// thread. PrintJob always outlives its worker instance.
class PrintJobWorkerOop : public PrintJobWorker {
public:
PrintJobWorkerOop(
std::unique_ptr<PrintingContext::Delegate> printing_context_delegate,
std::unique_ptr<PrintingContext> printing_context,
PrintJob* print_job,
mojom::PrintTargetType print_target_type);
PrintJobWorkerOop(const PrintJobWorkerOop&) = delete;
PrintJobWorkerOop& operator=(const PrintJobWorkerOop&) = delete;
~PrintJobWorkerOop() override;
// `PrintJobWorker` overrides.
void StartPrinting(PrintedDocument* new_document) override;
protected:
// For testing.
PrintJobWorkerOop(
std::unique_ptr<PrintingContext::Delegate> printing_context_delegate,
std::unique_ptr<PrintingContext> printing_context,
PrintJob* print_job,
bool simulate_spooling_memory_errors);
virtual void OnDidStartPrinting(mojom::ResultCode result);
#if BUILDFLAG(IS_WIN)
virtual void OnDidRenderPrintedPage(uint32_t page_index,
mojom::ResultCode result);
#endif
virtual void OnDidRenderPrintedDocument(mojom::ResultCode result);
virtual void OnDidDocumentDone(int job_id, mojom::ResultCode result);
virtual void OnDidCancel(scoped_refptr<PrintJob> job);
// `PrintJobWorker` overrides.
#if BUILDFLAG(IS_WIN)
bool SpoolPage(PrintedPage* page) override;
#endif
bool SpoolDocument() override;
void OnDocumentDone() override;
void OnFailure() override;
private:
// Support to unregister this worker as a printing client. Applicable any
// time a print job finishes, is canceled, or needs to be restarted.
void UnregisterServiceManagerClient();
// Helper function for restarting a print job after error.
bool TryRestartPrinting();
// Initiate failure handling, including notification to the user.
void NotifyFailure(mojom::ResultCode result);
void SendStartPrinting(const std::string& device_name,
const std::u16string& document_name);
#if BUILDFLAG(IS_WIN)
void SendRenderPrintedPage(
const PrintedPage* page,
mojom::MetafileDataType page_data_type,
base::ReadOnlySharedMemoryRegion serialized_page_data);
#endif // BUILDFLAG(IS_WIN)
void SendRenderPrintedDocument(
mojom::MetafileDataType data_type,
base::ReadOnlySharedMemoryRegion serialized_data);
void SendDocumentDone();
void SendCancel(scoped_refptr<PrintJob> job);
// Used to test spooling memory error handling.
bool simulate_spooling_memory_errors_ = false;
// Client ID with the print backend service manager for this print job.
// Used only from UI thread.
absl::optional<uint32_t> service_manager_client_id_;
// The device name used when printing via a service. Used only from the UI
// thread.
std::string device_name_;
// The processed name of the document being printed. Used only from the UI
// thread.
std::u16string document_name_;
// The printed document. Only has read-only access. This reference separate
// from the one already in the base class provides a guarantee that the
// `PrintedDocument` will persist until OOP processing completes, even if
// the `PrintJob` should drop its reference as part of failure/cancel
// processing. Named differently than base (even though both are private)
// to avoid any potential confusion between them.
scoped_refptr<PrintedDocument> document_oop_;
// The type of target to print to. Used only from the UI thread.
mojom::PrintTargetType print_target_type_ =
mojom::PrintTargetType::kDirectToDevice;
#if BUILDFLAG(IS_WIN)
// Number of pages that have completed printing.
uint32_t pages_printed_count_ = 0;
#endif
// Tracks if a restart for printing has already been attempted.
bool print_retried_ = false;
// Tracks if the service has already been requested to cancel printing the
// document
bool print_cancel_requested_ = false;
// Weak pointers have flags that get bound to the thread where they are
// checked, so it is necessary to use different factories when getting a
// weak pointer to send to the worker task runner vs. to the UI thread.
base::WeakPtrFactory<PrintJobWorkerOop> worker_weak_factory_{this};
base::WeakPtrFactory<PrintJobWorkerOop> ui_weak_factory_{this};
};
} // namespace printing
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OOP_H_