summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.h
blob: bdccac1a8a46e1de0e8543adcbef37c6996f20f6 (plain)
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
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_HANDLER_H_

#include <map>
#include <memory>
#include <set>
#include <string>

#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "chrome/common/buildflags.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "printing/backend/print_backend.h"
#include "printing/buildflags/buildflags.h"

namespace base {
class DictionaryValue;
class RefCountedMemory;
}

namespace content {
class WebContents;
}

namespace printing {

class PdfPrinterHandler;
class PrinterHandler;
class PrintPreviewUI;

// Must match print_preview.PrinterType in
// chrome/browser/resources/print_preview/native_layer.js
enum PrinterType {
  kPrivetPrinter,
  kExtensionPrinter,
  kPdfPrinter,
  kLocalPrinter,
  kCloudPrinter
};

// The handler for Javascript messages related to the print preview dialog.
class PrintPreviewHandler : public content::WebUIMessageHandler,
                            public signin::IdentityManager::Observer {
 public:
  PrintPreviewHandler();
  ~PrintPreviewHandler() override;

  // WebUIMessageHandler implementation.
  void RegisterMessages() override;
  void OnJavascriptAllowed() override;
  void OnJavascriptDisallowed() override;

  // IdentityManager::Observer implementation.
  void OnAccountsInCookieUpdated(
      const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
      const GoogleServiceAuthError& error) override;

  // Called when print preview failed. |request_id| identifies the request that
  // failed.
  void OnPrintPreviewFailed(int request_id);

  // Called when print preview is cancelled due to a new request. |request_id|
  // identifies the cancelled request.
  void OnPrintPreviewCancelled(int request_id);

  // Called when printer settings were invalid. |request_id| identifies the
  // request that requested the printer with invalid settings.
  void OnInvalidPrinterSettings(int request_id);

  // Called when print preview is ready.
  void OnPrintPreviewReady(int preview_uid, int request_id);

  // Called when a print request is cancelled due to its initiator closing.
  void OnPrintRequestCancelled();

  // Send the print preset options from the document.
  void SendPrintPresetOptions(bool disable_scaling,
                              int copies,
                              int duplex,
                              int request_id);

  // Send the print preview page count and fit to page scaling
  void SendPageCountReady(int page_count,
                          int fit_to_page_scaling,
                          int request_id);

  // Send the default page layout
  void SendPageLayoutReady(const base::DictionaryValue& layout,
                           bool has_custom_page_size_style,
                           int request_id);

  // Notify the WebUI that the page preview is ready.
  void SendPagePreviewReady(int page_index,
                            int preview_uid,
                            int preview_request_id);

  int regenerate_preview_request_count() const {
    return regenerate_preview_request_count_;
  }

  // Notifies PDF Printer Handler that |path| was selected. Used for tests.
  void FileSelectedForTesting(const base::FilePath& path,
                              int index,
                              void* params);

  // Sets |pdf_file_saved_closure_| to |closure|.
  void SetPdfSavedClosureForTesting(base::OnceClosure closure);

  // Fires the 'enable-manipulate-settings-for-test' WebUI event.
  void SendEnableManipulateSettingsForTest();

  // Fires the 'manipulate-settings-for-test' WebUI event with |settings|.
  void SendManipulateSettingsForTest(const base::DictionaryValue& settings);

 protected:
  // Protected so unit tests can override.
  virtual PrinterHandler* GetPrinterHandler(PrinterType printer_type);
  virtual bool IsCloudPrintEnabled();

  // Shuts down the initiator renderer. Called when a bad IPC message is
  // received.
  virtual void BadMessageReceived();

  // Gets the initiator for the print preview dialog.
  virtual content::WebContents* GetInitiator() const;

  // Register/unregister from notifications of changes done to the GAIA
  // cookie. Protected so unit tests can override.
  virtual void RegisterForGaiaCookieChanges();
  virtual void UnregisterForGaiaCookieChanges();

 private:
  friend class PrintPreviewPdfGeneratedBrowserTest;
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewPdfGeneratedBrowserTest,
                           MANUAL_DummyTest);
  friend class PrintPreviewHandlerTest;
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewHandlerTest, GetPrinters);
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewHandlerTest, GetPrinterCapabilities);
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewHandlerTest, Print);
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewHandlerTest, GetPreview);
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewHandlerTest, SendPreviewUpdates);
  friend class PrintPreviewHandlerFailingTest;
  FRIEND_TEST_ALL_PREFIXES(PrintPreviewHandlerFailingTest,
                           GetPrinterCapabilities);

#if defined(OS_CHROMEOS)
  class AccessTokenService;
#endif

  content::WebContents* preview_web_contents() const;

  PrintPreviewUI* print_preview_ui() const;

  PrefService* GetPrefs() const;

  // Whether the the handler should be receiving messages from the renderer to
  // forward to the Print Preview JS in response to preview request with id
  // |request_id|. Kills the renderer if the handler should not be receiving
  // messages, or if |request_id| does not correspond to an outstanding request.
  bool ShouldReceiveRendererMessage(int request_id);

  // Gets the preview callback id associated with |request_id| and removes it
  // from the |preview_callbacks_| map. Returns an empty string and kills the
  // renderer if no callback is found, the handler should not be receiving
  // messages, or if |request_id| is invalid.
  std::string GetCallbackId(int request_id);

  // Gets the list of printers. First element of |args| is the Javascript
  // callback, second element of |args| is the printer type to fetch.
  void HandleGetPrinters(const base::ListValue* args);

  // Grants an extension access to a provisional printer.  First element of
  // |args| is the provisional printer ID.
  void HandleGrantExtensionPrinterAccess(const base::ListValue* args);

  // Asks the initiator renderer to generate a preview.  First element of |args|
  // is a job settings JSON string.
  void HandleGetPreview(const base::ListValue* args);

  // Gets the job settings from Web UI and initiate printing. First element of
  // |args| is a job settings JSON string.
  void HandlePrint(const base::ListValue* args);

  // Handles the request to hide the preview dialog for printing.
  // |args| is unused.
  void HandleHidePreview(const base::ListValue* args);

  // Handles the request to cancel the pending print request. |args| is unused.
  void HandleCancelPendingPrintRequest(const base::ListValue* args);

  // Handles a request to store data that the web ui wishes to persist.
  // First element of |args| is the data to persist.
  void HandleSaveAppState(const base::ListValue* args);

  // Gets the printer capabilities. Fist element of |args| is the Javascript
  // callback, second element is the printer ID of the printer whose
  // capabilities are requested, and the third element is the type of the
  // printer whose capabilities are requested.
  void HandleGetPrinterCapabilities(const base::ListValue* args);

  // Performs printer setup. First element of |args| is the printer name.
  void HandlePrinterSetup(const base::ListValue* args);

#if BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)
  // Asks the initiator renderer to show the native print system dialog. |args|
  // is unused.
  void HandleShowSystemDialog(const base::ListValue* args);
#endif

  // Opens a new tab to allow the user to sign into cloud print. |args| holds
  // a boolean indicating whether the user is adding an account.
  void HandleSignin(const base::ListValue* args);

  // Called when the tab opened by HandleSignIn() is closed.
  void OnSignInTabClosed();

#if defined(OS_CHROMEOS)
  // Generates new token and sends back to UI.
  void HandleGetAccessToken(const base::ListValue* args);
#endif

  // Gathers UMA stats when the print preview dialog is about to close.
  // |args| is unused.
  void HandleClosePreviewDialog(const base::ListValue* args);

  // Asks the browser for several settings that are needed before the first
  // preview is displayed.
  void HandleGetInitialSettings(const base::ListValue* args);

#if defined(OS_CHROMEOS)
  // Opens printer settings in the Chrome OS Settings App.
  void HandleOpenPrinterSettings(const base::ListValue* args);
#endif

  void SendInitialSettings(const std::string& callback_id,
                           const std::string& default_printer);

#if defined(OS_CHROMEOS)
  // Send OAuth2 access token.
  void SendAccessToken(const std::string& callback_id,
                       const std::string& access_token);
#endif

  // Sends the printer capabilities to the Web UI. |settings_info| contains
  // printer capabilities information. If |settings_info| is empty, sends
  // error notification to the Web UI instead.
  void SendPrinterCapabilities(const std::string& callback_id,
                               base::Value settings_info);

  // Send the result of performing printer setup. |settings_info| contains
  // printer capabilities.
  void SendPrinterSetup(const std::string& callback_id,
                        const std::string& printer_name,
                        base::Value settings_info);

  // Send the PDF data to the cloud to print.
  void SendCloudPrintJob(const std::string& callback_id,
                         const base::RefCountedMemory* data);

  // Closes the preview dialog.
  void ClosePreviewDialog();

  // Clears initiator details for the print preview dialog.
  void ClearInitiatorDetails();

  // Populates |settings| according to the current locale.
  void GetLocaleInformation(base::Value* settings);

  // Populates |settings| with the list of logged in accounts.
  void GetUserAccountList(base::Value* settings);

  PdfPrinterHandler* GetPdfPrinterHandler();

  // Called when printers are detected.
  // |printer_type|: The type of printers that were added.
  // |printers|: A non-empty list containing information about the printer or
  //     printers that have been added.
  void OnAddedPrinters(PrinterType printer_type,
                       const base::ListValue& printers);

  // Called when printer search is done for some destination type.
  // |callback_id|: The javascript callback to call.
  void OnGetPrintersDone(const std::string& callback_id);

  // Called when an extension reports information requested for a provisional
  // printer.
  // |callback_id|: The javascript callback to resolve or reject.
  // |printer_info|: The data reported by the extension.
  void OnGotExtensionPrinterInfo(const std::string& callback_id,
                                 const base::DictionaryValue& printer_info);

  // Called when an extension or privet print job is completed.
  // |callback_id|: The javascript callback to run.
  // |error|: The returned print job error. Useful for reporting a specific
  //     error. None type implies no error.
  void OnPrintResult(const std::string& callback_id,
                     const base::Value& error);

  // A count of how many requests received to regenerate preview data.
  // Initialized to 0 then incremented and emitted to a histogram.
  int regenerate_preview_request_count_;

  // A count of how many requests received to show manage printers dialog.
  int manage_printers_dialog_request_count_;

  // Whether we have already logged a failed print preview.
  bool reported_failed_preview_;

  // Whether we have already logged the number of printers this session.
  bool has_logged_printers_count_;

  // Whether Google Cloud Print is enabled for the active profile.
  bool cloud_print_enabled_ = false;

  // The settings used for the most recent preview request.
  base::Value last_preview_settings_;

#if defined(OS_CHROMEOS)
  // Holds token service to get OAuth2 access tokens.
  std::unique_ptr<AccessTokenService> token_service_;
#endif

  // Pointer to the identity manager service so that print preview can listen
  // for GAIA cookie changes.
  signin::IdentityManager* identity_manager_;

  // Handles requests for cloud printers. Created lazily by calling
  // GetPrinterHandler().
  std::unique_ptr<PrinterHandler> cloud_printer_handler_;

  // Handles requests for extension printers. Created lazily by calling
  // GetPrinterHandler().
  std::unique_ptr<PrinterHandler> extension_printer_handler_;

  // Handles requests for privet printers. Created lazily by calling
  // GetPrinterHandler().
  std::unique_ptr<PrinterHandler> privet_printer_handler_;

  // Handles requests for printing to PDF. Created lazily by calling
  // GetPrinterHandler().
  std::unique_ptr<PrinterHandler> pdf_printer_handler_;

  // Handles requests for printing to local printers. Created lazily by calling
  // GetPrinterHandler().
  std::unique_ptr<PrinterHandler> local_printer_handler_;

  // Maps preview request ids to callbacks.
  std::map<int, std::string> preview_callbacks_;

  // Set of preview request ids for failed previews.
  std::set<int> preview_failures_;

  base::WeakPtrFactory<PrintPreviewHandler> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(PrintPreviewHandler);
};

}  // namespace printing

#endif  // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_HANDLER_H_