File: print_preview_ui.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; 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 (333 lines) | stat: -rw-r--r-- 12,863 bytes parent folder | download | duplicates (5)
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
// Copyright 2012 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_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_
#define CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_

#include <stdint.h>

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "base/containers/span.h"
#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
#include "chrome/services/printing/public/mojom/pdf_nup_converter.mojom.h"
#include "components/printing/common/print.mojom.h"
#include "components/services/print_compositor/public/mojom/print_compositor.mojom.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/browser/webui_config.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "printing/buildflags/buildflags.h"
#include "printing/mojom/print.mojom-forward.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"

#if BUILDFLAG(ENABLE_OOP_PRINTING)
#include "chrome/browser/printing/print_backend_service_manager.h"
#endif

class GURL;

namespace base {
class FilePath;
class RefCountedMemory;
}  // namespace base

namespace content {
class BrowserContext;
}  // namespace content

namespace printing {

class PrintPreviewHandler;
class PrintPreviewUI;

class PrintPreviewUIConfig
    : public content::DefaultWebUIConfig<PrintPreviewUI> {
 public:
  PrintPreviewUIConfig();
  ~PrintPreviewUIConfig() override;

  // content::DefaultWebUIConfig:
  bool IsWebUIEnabled(content::BrowserContext* browser_context) override;
  bool ShouldHandleURL(const GURL& url) override;
};

// PrintPreviewUI lives on the UI thread.
class PrintPreviewUI : public ConstrainedWebDialogUI,
                       public mojom::PrintPreviewUI {
 public:
  explicit PrintPreviewUI(content::WebUI* web_ui);

  PrintPreviewUI(const PrintPreviewUI&) = delete;
  PrintPreviewUI& operator=(const PrintPreviewUI&) = delete;

  ~PrintPreviewUI() override;

  mojo::PendingAssociatedRemote<mojom::PrintPreviewUI> BindPrintPreviewUI();

  // Gets the print preview |data|. |index| is zero-based, and can be
  // |COMPLETE_PREVIEW_DOCUMENT_INDEX| to get the entire preview document.
  virtual void GetPrintPreviewDataForIndex(
      int index,
      scoped_refptr<base::RefCountedMemory>* data) const;

  // printing::mojo::PrintPreviewUI:
  void SetOptionsFromDocument(const mojom::OptionsFromDocumentParamsPtr params,
                              int32_t request_id) override;
  void DidPrepareDocumentForPreview(int32_t document_cookie,
                                    int32_t request_id) override;
  void DidPreviewPage(mojom::DidPreviewPageParamsPtr params,
                      int32_t request_id) override;
  void MetafileReadyForPrinting(mojom::DidPreviewDocumentParamsPtr params,
                                int32_t request_id) override;
  void PrintPreviewFailed(int32_t document_cookie, int32_t request_id) override;
  void PrintPreviewCancelled(int32_t document_cookie,
                             int32_t request_id) override;
  void PrinterSettingsInvalid(int32_t document_cookie,
                              int32_t request_id) override;
  void DidGetDefaultPageLayout(mojom::PageSizeMarginsPtr page_layout_in_points,
                               const gfx::RectF& printable_area_in_points,
                               bool all_pages_have_custom_size,
                               bool all_pages_have_custom_orientation,
                               int32_t request_id) override;
  void DidStartPreview(mojom::DidStartPreviewParamsPtr params,
                       int32_t request_id) override;

  bool IsBound() const;

  // Setters
  void SetInitiatorTitle(const std::u16string& initiator_title);

  const std::u16string& initiator_title() const { return initiator_title_; }

  int pages_per_sheet() const { return pages_per_sheet_; }

  const gfx::Rect& printable_area() const { return printable_area_; }

  const gfx::Size& page_size() const { return page_size_; }

  PrintPreviewHandler* handler() const { return handler_; }

  // Returns true if `page_index` is the last page in `pages_to_render_`.
  // `page_index` is a 0-based.
  bool LastPageComposited(uint32_t page_index) const;

  // Get the 0-based index of the `page_index` in `pages_to_render_`.
  // `page_index` is a 0-based.
  uint32_t GetPageToNupConvertIndex(uint32_t page_index) const;

  std::vector<base::ReadOnlySharedMemoryRegion> TakePagesForNupConvert();

  // Save pdf pages temporarily before ready to do N-up conversion.
  void AddPdfPageForNupConversion(base::ReadOnlySharedMemoryRegion pdf_page);

  // Determines whether to cancel a print preview request based on the request
  // id.
  static bool ShouldCancelRequest(const std::optional<int32_t>& preview_ui_id,
                                  int request_id);

  // Returns an id to uniquely identify this PrintPreviewUI.
  std::optional<int32_t> GetIDForPrintPreviewUI() const;

  // Notifies the Web UI of a print preview request with |request_id|.
  virtual void OnPrintPreviewRequest(int request_id);

  // Notifies the Web UI that the 0-based page `page_index` rendering is being
  // processed and an OnPendingPreviewPage() call is imminent. Returns whether
  // `page_index` is the expected page.
  bool OnPendingPreviewPage(uint32_t page_index);

  // Notifies the Web UI that the print preview failed to render for the request
  // with id = |request_id|.
  void OnPrintPreviewFailed(int request_id);

  // Notified the Web UI that this print preview dialog's RenderProcess has been
  // closed, which may occur for several reasons, e.g. tab closure or crash.
  void OnPrintPreviewDialogClosed();

  // Notifies the Web UI that initiator is closed, so we can disable all the
  // controls that need the initiator for generating the preview data.
  void OnInitiatorClosed();

  // Notifies the Web UI to cancel the pending preview request.
  virtual void OnCancelPendingPreviewRequest();

  // Hides the print preview dialog.
  virtual void OnHidePreviewDialog();

  // Closes the print preview dialog.
  virtual void OnClosePrintPreviewDialog();

  // Allows tests to wait until the print preview dialog is loaded.
  class TestDelegate {
   public:
    // Provides the total number of pages requested for the preview.
    virtual void DidGetPreviewPageCount(uint32_t page_count) {}

    // Notifies that a page was rendered for the preview.  This occurs after
    // any possible N-up processing, so each rendered page could represent
    // multiple pages that were counted in `DidGetPreviewPageCount()`.
    virtual void DidRenderPreviewPage(content::WebContents* preview_dialog) {}

    // Notifies that the document to print from preview is ready.  This occurs
    // after any possible N-up processing.
    virtual void PreviewDocumentReady(content::WebContents* preview_dialog,
                                      base::span<const uint8_t> data) {}

   protected:
    virtual ~TestDelegate() = default;
  };

  static void SetDelegateForTesting(TestDelegate* delegate);

  // Allows for tests to set a file path to print a PDF to. This also initiates
  // the printing without having to click a button on the print preview dialog.
  void SetSelectedFileForTesting(const base::FilePath& path);

  // Passes |closure| to PrintPreviewHandler::SetPdfSavedClosureForTesting().
  void SetPdfSavedClosureForTesting(base::OnceClosure closure);

  // See SetPrintPreviewDataForIndex().
  void SetPrintPreviewDataForIndexForTest(
      int index,
      scoped_refptr<base::RefCountedMemory> data);

  // See ClearAllPreviewData().
  void ClearAllPreviewDataForTest();

  // Sets a new valid Print Preview UI ID for this instance. Called by
  // PrintPreviewHandler in OnJavascriptAllowed().
  void SetPreviewUIId();

  // Clears the UI ID. Called by PrintPreviewHandler in
  // OnJavascriptDisallowed().
  void ClearPreviewUIId();

 protected:
  // Alternate constructor for tests
  PrintPreviewUI(content::WebUI* web_ui,
                 std::unique_ptr<PrintPreviewHandler> handler);

 private:
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewDialogControllerUnitTest,
                           TitleAfterReload);
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewUIUnitTest,
                           PrintPreviewFailureCancelsPendingActions);

  // Sets the print preview |data|. |index| is zero-based, and can be
  // |COMPLETE_PREVIEW_DOCUMENT_INDEX| to set the entire preview document.
  void SetPrintPreviewDataForIndex(int index,
                                   scoped_refptr<base::RefCountedMemory> data);

  // Clear the existing print preview data.
  void ClearAllPreviewData();

  // Notifies the Web UI that the 0-based page `page_index` has been rendered.
  // `request_id` indicates which request resulted in this response.
  void NotifyUIPreviewPageReady(
      uint32_t page_index,
      int request_id,
      scoped_refptr<base::RefCountedMemory> data_bytes);

  // Notifies the Web UI renderer that preview data is available. |request_id|
  // indicates which request resulted in this response.
  void NotifyUIPreviewDocumentReady(
      int request_id,
      scoped_refptr<base::RefCountedMemory> data_bytes);

  bool ShouldUseCompositor() const;

  // Callbacks for print compositor client.
  void OnPrepareForDocumentToPdfDone(int32_t request_id,
                                     mojom::PrintCompositor::Status status);
  void OnCompositePdfPageDone(uint32_t page_index,
                              int32_t document_cookie,
                              int32_t request_id,
                              mojom::PrintCompositor::Status status,
                              base::ReadOnlySharedMemoryRegion region);
  void OnNupPdfConvertDone(uint32_t page_index,
                           int32_t request_id,
                           mojom::PdfNupConverter::Status status,
                           base::ReadOnlySharedMemoryRegion region);
  void OnNupPdfDocumentConvertDone(int32_t request_id,
                                   mojom::PdfNupConverter::Status status,
                                   base::ReadOnlySharedMemoryRegion region);
  void OnCompositeToPdfDone(int document_cookie,
                            int32_t request_id,
                            mojom::PrintCompositor::Status status,
                            base::ReadOnlySharedMemoryRegion region);

#if BUILDFLAG(ENABLE_OOP_PRINTING)
  // Registers this PrintPreviewUI with the PrintBackendServiceManager. It is
  // beneficial to have the Print Backend service be present and ready for at
  // least as long as this UI is around.
  void RegisterPrintBackendServiceManagerClient();

  void UnregisterPrintBackendServiceManagerClient();
#endif  // BUILDFLAG(ENABLE_OOP_PRINTING)

  WEB_UI_CONTROLLER_TYPE_DECL();

  base::TimeTicks initial_preview_start_time_;

  // Tracks if this is the first instance created since the browser started.
  const bool first_print_usage_since_startup_;

  // The unique ID for this class instance. Stored here to avoid calling
  // GetIDForPrintPreviewUI() everywhere.
  std::optional<int32_t> id_;

#if BUILDFLAG(ENABLE_OOP_PRINTING)
  // This UI's client ID with the print backend service manager.
  PrintBackendServiceManager::ClientId service_manager_client_id_;
#endif

  // Weak pointer to the WebUI handler.
  const raw_ptr<PrintPreviewHandler> handler_;

  // Keeps track of whether OnClosePrintPreviewDialog() has been called or not.
  bool dialog_closed_ = false;

  // Store the initiator title, used for populating the print preview dialog
  // title.
  std::u16string initiator_title_;

  // The list of 0-based page indices that will be rendered.
  std::vector<uint32_t> pages_to_render_;

  // The list of pages to be converted.
  std::vector<base::ReadOnlySharedMemoryRegion> pages_for_nup_convert_;

  // Index into `pages_to_render_`. The expected page index is the value at
  // `pages_to_render_[pages_to_render_index_]`
  size_t pages_to_render_index_ = 0;

  // number of pages per sheet and should be greater or equal to 1.
  int pages_per_sheet_ = 1;

  // Physical size of the page, including non-printable margins.
  gfx::Size page_size_;

  // The printable area of the printed document pages.
  gfx::Rect printable_area_;

  mojo::AssociatedReceiver<mojom::PrintPreviewUI> receiver_{this};

  base::WeakPtrFactory<PrintPreviewUI> weak_ptr_factory_{this};
};

}  // namespace printing

#endif  // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_