File: print_composite_client.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (212 lines) | stat: -rw-r--r-- 9,173 bytes parent folder | download | duplicates (9)
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
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_PRINTING_BROWSER_PRINT_COMPOSITE_CLIENT_H_
#define COMPONENTS_PRINTING_BROWSER_PRINT_COMPOSITE_CLIENT_H_

#include <map>
#include <memory>

#include "base/containers/flat_set.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "components/printing/common/print.mojom.h"
#include "components/services/print_compositor/public/mojom/print_compositor.mojom.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "printing/buildflags/buildflags.h"
#include "printing/mojom/print.mojom.h"
#include "ui/accessibility/ax_tree_update_forward.h"

namespace printing {

// Class to manage print requests and their communication with print compositor
// service. Each composite request have a separate interface pointer to connect
// with remote service. The request and its subframe printing results are
// tracked by its document cookie and print page number.
class PrintCompositeClient
    : public content::WebContentsUserData<PrintCompositeClient>,
      public content::WebContentsObserver {
 public:
  explicit PrintCompositeClient(content::WebContents* web_contents);
  PrintCompositeClient(const PrintCompositeClient&) = delete;
  PrintCompositeClient& operator=(const PrintCompositeClient&) = delete;
  ~PrintCompositeClient() override;

  // content::WebContentsObserver
  void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;

  void SetAccessibilityTree(int document_cookie,
                            const ui::AXTreeUpdate& accessibility_tree);

  // Instructs the specified subframe to print.
  void PrintCrossProcessSubframe(const gfx::Rect& rect,
                                 int document_cookie,
                                 content::RenderFrameHost* subframe_host);

  // Printing single pages is only used by print preview for early return of
  // rendered results. In this case, the pages share the content with printed
  // document. The document can be collected from the individual pages,
  // avoiding the need to also send the entire document again as a large blob.
  // This is for compositing such a single preview page.
  void CompositePage(int cookie,
                     content::RenderFrameHost* render_frame_host,
                     const mojom::DidPrintContentParams& content,
                     mojom::PrintCompositor::CompositePageCallback callback);

  // Notifies compositor to collect individual pages into a document
  // when processing the individual pages for preview.  The `document_type`
  // specified determines the format of the document passed back in the
  // `callback` from `FinishDocumentComposition()`.
  void PrepareToCompositeDocument(
      int document_cookie,
      content::RenderFrameHost* render_frame_host,
      mojom::PrintCompositor::DocumentType document_type,
      mojom::PrintCompositor::PrepareToCompositeDocumentCallback callback);

  // Notifies compositor of the total number of pages being concurrently
  // collected into the document, allowing for completion of the composition
  // when all pages have been received.  The format of the provided document
  // is of the `document_type` specified in `PrepareToCompositeDocument()`.
  void FinishDocumentComposition(
      int document_cookie,
      uint32_t pages_count,
      mojom::PrintCompositor::FinishDocumentCompositionCallback callback);

  // Used for compositing the entire document for print preview or actual
  // printing.
  void CompositeDocument(
      int cookie,
      content::RenderFrameHost* render_frame_host,
      const mojom::DidPrintContentParams& content,
      const ui::AXTreeUpdate& accessibility_tree,
      mojom::GenerateDocumentOutline generate_document_outline,
      mojom::PrintCompositor::DocumentType document_type,
      mojom::PrintCompositor::CompositeDocumentCallback callback);

  // Get the concurrent composition status for a document.  Identifies if the
  // full document will be compiled from the individual pages; if not then a
  // separate document object will need to be provided.
  bool GetIsDocumentConcurrentlyComposited(int cookie) const;

  void SetUserAgent(const std::string& user_agent) { user_agent_ = user_agent; }

 private:
  friend class content::WebContentsUserData<PrintCompositeClient>;
  FRIEND_TEST_ALL_PREFIXES(PrintBrowserTest,
                           PrintSubframeContentBeforeCompositeClientCreation);

  // Callback functions for getting the replies.
  static void OnDidCompositePage(
      mojom::PrintCompositor::CompositePageCallback callback,
      mojom::PrintCompositor::Status status,
      base::ReadOnlySharedMemoryRegion region);

  void OnDidCompositeDocument(
      int document_cookie,
      mojom::PrintCompositor::CompositeDocumentCallback callback,
      mojom::PrintCompositor::Status status,
      base::ReadOnlySharedMemoryRegion region);

  static void OnDidPrepareToCompositeDocument(
      mojom::PrintCompositor::PrepareToCompositeDocumentCallback callback,
      mojom::PrintCompositor::Status status);

  void OnDidFinishDocumentComposition(
      int document_cookie,
      mojom::PrintCompositor::FinishDocumentCompositionCallback callback,
      mojom::PrintCompositor::Status status,
      base::ReadOnlySharedMemoryRegion region);

  void OnDidPrintFrameContent(content::GlobalRenderFrameHostId rfh_id,
                              int document_cookie,
                              mojom::DidPrintContentParamsPtr params);

  // Creates a new composite request for a given document |cookie|. Since
  // printed pages always share content with its document, they share the same
  // composite request. Launches the compositor in a separate process.
  // If a composite request already exists, it is removed.
  // Returns the created composite request.
  mojom::PrintCompositor* CreateCompositeRequest(
      int cookie,
      content::RenderFrameHost* initiator_frame,
      mojom::PrintCompositor::DocumentType document_type);

  // Remove the existing composite request.
  void RemoveCompositeRequest(int cookie);

  // Checks if the |document_cookie| is not 0 and matches |document_cookie_|.
  bool IsDocumentCookieValid(int document_cookie) const;

  // Get the composite request of a document. |cookie| must be valid and equal
  // to |document_cookie_|.
  mojom::PrintCompositor* GetCompositeRequest(int cookie) const;

  // Helper method to fetch the PrintRenderFrame remote interface pointer
  // associated with a given subframe.
  const mojo::AssociatedRemote<mojom::PrintRenderFrame>& GetPrintRenderFrame(
      content::RenderFrameHost* rfh);

  // Stores the message pipe endpoint for making remote calls to the compositor.
  mojo::Remote<mojom::PrintCompositor> compositor_;

  // Stores the unique sequential cookie of the document being composited.
  // Holds 0 if no document is being composited.
  int document_cookie_ = 0;

  // Stores whether the document is concurrently compositing using individual
  // pages, so that no separate composite request with full-document blob is
  // required.
  bool is_doc_concurrently_composited_ = false;

  // Stores the the frame that initiated the composite request;
  // Holds nullptr if no document is being composited.
  raw_ptr<content::RenderFrameHost> initiator_frame_ = nullptr;

  // Stores the pending subframes for the composited document.
  base::flat_set<raw_ptr<content::RenderFrameHost, CtnExperimental>>
      pending_subframes_;

  // Stores the printed subframes for the composited document.
  base::flat_set<raw_ptr<content::RenderFrameHost, CtnExperimental>>
      printed_subframes_;

  struct RequestedSubFrame {
    RequestedSubFrame(content::GlobalRenderFrameHostId rfh_id,
                      int document_cookie,
                      mojom::DidPrintContentParamsPtr params,
                      bool is_live);
    ~RequestedSubFrame();
    RequestedSubFrame(const RequestedSubFrame&) = delete;
    RequestedSubFrame& operator=(const RequestedSubFrame&) = delete;

    content::GlobalRenderFrameHostId rfh_id_;
    int document_cookie_;
    mojom::DidPrintContentParamsPtr params_;
    bool is_live_;
  };
  base::flat_set<std::unique_ptr<RequestedSubFrame>> requested_subframes_;

  std::string user_agent_;

  // Stores a PrintRenderFrame associated remote with the RenderFrameHost used
  // to bind it. The PrintRenderFrame is used to transmit mojo interface method
  // calls to the associated receiver.
  std::map<content::RenderFrameHost*,
           mojo::AssociatedRemote<mojom::PrintRenderFrame>>
      print_render_frames_;

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

  WEB_CONTENTS_USER_DATA_KEY_DECL();
};

}  // namespace printing

#endif  // COMPONENTS_PRINTING_BROWSER_PRINT_COMPOSITE_CLIENT_H_