File: print_job_worker_oop.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (177 lines) | stat: -rw-r--r-- 7,271 bytes parent folder | download | duplicates (4)
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
// 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 <memory>
#include <optional>
#include <string>

#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "chrome/browser/printing/print_backend_service_manager.h"
#include "chrome/browser/printing/print_job_worker.h"
#include "chrome/services/printing/public/mojom/print_backend_service.mojom.h"
#include "components/enterprise/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "printing/mojom/print.mojom.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:
  // The `client_id` specifies the print document client registered with
  // `PrintBackendServiceManager`.  `PrintJobWorkerOop` takes responsibility
  // for unregistering the client ID with `PrintBackendServiceManager` once
  // printing is completed.
  // The `client_id` can be empty.  This can occur for placeholder print jobs
  // that don't actually initiate printing such as during content analysis.
  PrintJobWorkerOop(
      std::unique_ptr<PrintingContext::Delegate> printing_context_delegate,
      std::unique_ptr<PrintingContext> printing_context,
      std::optional<PrintBackendServiceManager::ClientId> client_id,
      std::optional<PrintBackendServiceManager::ContextId> context_id,
      PrintJob* print_job,
      bool print_from_system_dialog);
  PrintJobWorkerOop(const PrintJobWorkerOop&) = delete;
  PrintJobWorkerOop& operator=(const PrintJobWorkerOop&) = delete;
  ~PrintJobWorkerOop() override;

  // `PrintJobWorker` overrides.
  void StartPrinting(PrintedDocument* new_document) override;
  void Cancel() override;
#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
  void CleanupAfterContentAnalysisDenial() override;
#endif

 protected:
  // For testing.
  PrintJobWorkerOop(
      std::unique_ptr<PrintingContext::Delegate> printing_context_delegate,
      std::unique_ptr<PrintingContext> printing_context,
      std::optional<PrintBackendServiceManager::ClientId> client_id,
      std::optional<PrintBackendServiceManager::ContextId> context_id,
      PrintJob* print_job,
      bool print_from_system_dialog,
      bool simulate_spooling_memory_errors);

  // Local callback wrappers for Print Backend Service mojom call.  Virtual to
  // support testing.
  virtual void OnDidStartPrinting(mojom::ResultCode result, int job_id);
#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,
                           mojom::ResultCode cancel_reason);

  // `PrintJobWorker` overrides.
#if BUILDFLAG(IS_WIN)
  bool SpoolPage(PrintedPage* page) override;
#endif
  bool SpoolDocument() override;
  void OnDocumentDone() override;
  void FinishDocumentDone(int job_id) override;
  void OnCancel() 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);

  // Mojo support to send messages from UI thread.
  void SendEstablishPrintingContext();
  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(base::OnceClosure on_did_cancel_callback);

  // Used to test spooling memory error handling.
  const bool simulate_spooling_memory_errors_;

  // Client ID with the print backend service manager for this print job.
  // Used only from UI thread.
  std::optional<PrintBackendServiceManager::ClientId>
      service_manager_client_id_;

  // The printing context identifier related to this print job.
  // Used only from UI thread.
  std::optional<PrintBackendServiceManager::ContextId> printing_context_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.
  // Once set at the start of printing on the worker thread, it is only
  // referenced thereafter from the UI thread.  UI thread accesses only occur
  // once the interactions with the Print Backend service occur as a result of
  // starting to print the job.  Any document access from worker thread happens
  // by methods in base class, which use the base `document_` field.
  scoped_refptr<PrintedDocument> document_oop_;

  // Indicates if the print job was initiated from the print system dialog.
  const bool print_from_system_dialog_;

#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_