1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_HANDLER_H_
6#define CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_HANDLER_H_
7
8#include <string>
9
10#include "base/files/file_path.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/memory/weak_ptr.h"
14#include "chrome/browser/printing/print_view_manager_observer.h"
15#include "content/public/browser/web_ui_message_handler.h"
16#include "ui/shell_dialogs/select_file_dialog.h"
17
18#if defined(ENABLE_SERVICE_DISCOVERY)
19#include "chrome/browser/local_discovery/privet_local_printer_lister.h"
20#include "chrome/browser/local_discovery/service_discovery_shared_client.h"
21#endif  // ENABLE_SERVICE_DISCOVERY
22
23class PrintSystemTaskProxy;
24
25namespace base {
26class DictionaryValue;
27class RefCountedBytes;
28}
29
30namespace content {
31class WebContents;
32}
33
34namespace gfx {
35class Size;
36}
37
38// The handler for Javascript messages related to the print preview dialog.
39class PrintPreviewHandler
40    : public content::WebUIMessageHandler,
41#if defined(ENABLE_SERVICE_DISCOVERY)
42      public local_discovery::PrivetLocalPrinterLister::Delegate,
43      public local_discovery::PrivetLocalPrintOperation::Delegate,
44#endif
45      public ui::SelectFileDialog::Listener,
46      public printing::PrintViewManagerObserver {
47 public:
48  PrintPreviewHandler();
49  virtual ~PrintPreviewHandler();
50
51  // WebUIMessageHandler implementation.
52  virtual void RegisterMessages() OVERRIDE;
53
54  // SelectFileDialog::Listener implementation.
55  virtual void FileSelected(const base::FilePath& path,
56                            int index,
57                            void* params) OVERRIDE;
58  virtual void FileSelectionCanceled(void* params) OVERRIDE;
59
60  // PrintViewManagerObserver implementation.
61  virtual void OnPrintDialogShown() OVERRIDE;
62
63  // Displays a modal dialog, prompting the user to select a file.
64  void SelectFile(const base::FilePath& default_path);
65
66  // Called when the print preview dialog is destroyed. This is the last time
67  // this object has access to the PrintViewManager in order to disconnect the
68  // observer.
69  void OnPrintPreviewDialogDestroyed();
70
71  // Called when print preview failed.
72  void OnPrintPreviewFailed();
73
74  // Called when the user press ctrl+shift+p to display the native system
75  // dialog.
76  void ShowSystemDialog();
77
78#if defined(ENABLE_SERVICE_DISCOVERY)
79  // PrivetLocalPrinterLister::Delegate implementation.
80  virtual void LocalPrinterChanged(
81      bool added,
82      const std::string& name,
83      bool has_local_printing,
84      const local_discovery::DeviceDescription& description) OVERRIDE;
85  virtual void LocalPrinterRemoved(const std::string& name) OVERRIDE;
86  virtual void LocalPrinterCacheFlushed() OVERRIDE;
87
88  // PrivetLocalPrintOperation::Delegate implementation.
89  virtual void OnPrivetPrintingDone(
90      const local_discovery::PrivetLocalPrintOperation*
91      print_operation) OVERRIDE;
92  virtual void OnPrivetPrintingError(
93      const local_discovery::PrivetLocalPrintOperation* print_operation,
94        int http_code) OVERRIDE;
95#endif  // ENABLE_SERVICE_DISCOVERY
96  int regenerate_preview_request_count() const {
97    return regenerate_preview_request_count_;
98  }
99
100 private:
101  class AccessTokenService;
102
103  static bool PrivetPrintingEnabled();
104
105  content::WebContents* preview_web_contents() const;
106
107  // Gets the list of printers. |args| is unused.
108  void HandleGetPrinters(const base::ListValue* args);
109
110  // Starts getting all local privet printers. |arg| is unused.
111  void HandleGetPrivetPrinters(const base::ListValue* args);
112
113  // Stops getting all local privet printers. |arg| is unused.
114  void HandleStopGetPrivetPrinters(const base::ListValue* args);
115
116  // Asks the initiator renderer to generate a preview.  First element of |args|
117  // is a job settings JSON string.
118  void HandleGetPreview(const base::ListValue* args);
119
120  // Gets the job settings from Web UI and initiate printing. First element of
121  // |args| is a job settings JSON string.
122  void HandlePrint(const base::ListValue* args);
123
124  // Handles the request to hide the preview dialog for printing.
125  // |args| is unused.
126  void HandleHidePreview(const base::ListValue* args);
127
128  // Handles the request to cancel the pending print request. |args| is unused.
129  void HandleCancelPendingPrintRequest(const base::ListValue* args);
130
131  // Handles a request to store data that the web ui wishes to persist.
132  // First element of |args| is the data to persist.
133  void HandleSaveAppState(const base::ListValue* args);
134
135  // Gets the printer capabilities. First element of |args| is the printer name.
136  void HandleGetPrinterCapabilities(const base::ListValue* args);
137
138  // Asks the initiator renderer to show the native print system dialog. |args|
139  // is unused.
140  void HandleShowSystemDialog(const base::ListValue* args);
141
142  // Callback for the signin dialog to call once signin is complete.
143  void OnSigninComplete();
144
145  // Brings up a dialog to allow the user to sign into cloud print.
146  // |args| is unused.
147  void HandleSignin(const base::ListValue* args);
148
149  // Generates new token and sends back to UI.
150  void HandleGetAccessToken(const base::ListValue* args);
151
152  // Brings up a web page to allow the user to configure cloud print.
153  // |args| is unused.
154  void HandleManageCloudPrint(const base::ListValue* args);
155
156  // Gathers UMA stats when the print preview dialog is about to close.
157  // |args| is unused.
158  void HandleClosePreviewDialog(const base::ListValue* args);
159
160  // Asks the browser to show the native printer management dialog.
161  // |args| is unused.
162  void HandleManagePrinters(const base::ListValue* args);
163
164  // Asks the browser to show the cloud print dialog. |args| is signle int with
165  // page count.
166  void HandlePrintWithCloudPrintDialog(const base::ListValue* args);
167
168  // Asks the browser for several settings that are needed before the first
169  // preview is displayed.
170  void HandleGetInitialSettings(const base::ListValue* args);
171
172  // Reports histogram data for a print preview UI action. |args| should consist
173  // of two elements: the bucket name, and the bucket event.
174  void HandleReportUiEvent(const base::ListValue* args);
175
176  // Forces the opening of a new tab. |args| should consist of one element: the
177  // URL to set the new tab to.
178  //
179  // NOTE: This is needed to open FedEx confirmation window as a new tab.
180  // Javascript's "window.open" opens a new window popup (since initiated from
181  // async HTTP request) and worse yet, on Windows and Chrome OS, the opened
182  // window opens behind the initiator window.
183  void HandleForceOpenNewTab(const base::ListValue* args);
184
185  void HandleGetPrivetPrinterCapabilities(const base::ListValue* arg);
186
187  void SendInitialSettings(const std::string& default_printer);
188
189  // Send OAuth2 access token.
190  void SendAccessToken(const std::string& type,
191                       const std::string& access_token);
192
193  // Sends the printer capabilities to the Web UI. |settings_info| contains
194  // printer capabilities information.
195  void SendPrinterCapabilities(const base::DictionaryValue* settings_info);
196
197  // Sends error notification to the Web UI when unable to return the printer
198  // capabilities.
199  void SendFailedToGetPrinterCapabilities(const std::string& printer_name);
200
201  // Send the list of printers to the Web UI.
202  void SetupPrinterList(const base::ListValue* printers);
203
204  // Send whether cloud print integration should be enabled.
205  void SendCloudPrintEnabled();
206
207  // Send the PDF data to the cloud to print.
208  void SendCloudPrintJob(const base::RefCountedBytes* data);
209
210  // Handles printing to PDF.
211  void PrintToPdf();
212
213  // Asks the browser to show the cloud print dialog.
214  void PrintWithCloudPrintDialog();
215
216  // Gets the initiator for the print preview dialog.
217  content::WebContents* GetInitiator() const;
218
219  // Closes the preview dialog.
220  void ClosePreviewDialog();
221
222  // Adds all the recorded stats taken so far to histogram counts.
223  void ReportStats();
224
225  // Clears initiator details for the print preview dialog.
226  void ClearInitiatorDetails();
227
228  // Posts a task to save |data| to pdf at |print_to_pdf_path_|.
229  void PostPrintToPdfTask();
230
231  // Populates |settings| according to the current locale.
232  void GetNumberFormatAndMeasurementSystem(base::DictionaryValue* settings);
233
234  bool GetPreviewDataAndTitle(scoped_refptr<base::RefCountedBytes>* data,
235                              base::string16* title) const;
236
237#if defined(USE_CUPS)
238  void SaveCUPSColorSetting(const base::DictionaryValue* settings);
239
240  void ConvertColorSettingToCUPSColorModel(
241      base::DictionaryValue* settings) const;
242#endif
243
244#if defined(ENABLE_SERVICE_DISCOVERY)
245  void OnPrivetCapabilities(const base::DictionaryValue* capabilities);
246  void PrivetCapabilitiesUpdateClient(
247      scoped_ptr<local_discovery::PrivetHTTPClient> http_client);
248  void PrivetLocalPrintUpdateClient(
249      std::string print_ticket,
250      std::string capabilities,
251      gfx::Size page_size,
252      scoped_ptr<local_discovery::PrivetHTTPClient> http_client);
253  bool PrivetUpdateClient(
254      scoped_ptr<local_discovery::PrivetHTTPClient> http_client);
255  void StartPrivetLocalPrint(const std::string& print_ticket,
256                             const std::string& capabilities,
257                             const gfx::Size& page_size);
258  void SendPrivetCapabilitiesError(const std::string& id);
259  void PrintToPrivetPrinter(const std::string& printer_name,
260                            const std::string& print_ticket,
261                            const std::string& capabilities,
262                            const gfx::Size& page_size);
263  bool CreatePrivetHTTP(
264      const std::string& name,
265      const local_discovery::PrivetHTTPAsynchronousFactory::ResultCallback&
266          callback);
267  void FillPrinterDescription(
268      const std::string& name,
269      const local_discovery::DeviceDescription& description,
270      bool has_local_printing,
271      base::DictionaryValue* printer_value);
272#endif
273
274  // The underlying dialog object.
275  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
276
277  // A count of how many requests received to regenerate preview data.
278  // Initialized to 0 then incremented and emitted to a histogram.
279  int regenerate_preview_request_count_;
280
281  // A count of how many requests received to show manage printers dialog.
282  int manage_printers_dialog_request_count_;
283  int manage_cloud_printers_dialog_request_count_;
284
285  // Whether we have already logged a failed print preview.
286  bool reported_failed_preview_;
287
288  // Whether we have already logged the number of printers this session.
289  bool has_logged_printers_count_;
290
291  // Holds the path to the print to pdf request. It is empty if no such request
292  // exists.
293  base::FilePath print_to_pdf_path_;
294
295  // Holds token service to get OAuth2 access tokens.
296  scoped_ptr<AccessTokenService> token_service_;
297
298#if defined(ENABLE_SERVICE_DISCOVERY)
299  scoped_refptr<local_discovery::ServiceDiscoverySharedClient>
300      service_discovery_client_;
301  scoped_ptr<local_discovery::PrivetLocalPrinterLister> printer_lister_;
302
303  scoped_ptr<local_discovery::PrivetHTTPAsynchronousFactory>
304      privet_http_factory_;
305  scoped_ptr<local_discovery::PrivetHTTPResolution> privet_http_resolution_;
306  scoped_ptr<local_discovery::PrivetV1HTTPClient> privet_http_client_;
307  scoped_ptr<local_discovery::PrivetJSONOperation>
308      privet_capabilities_operation_;
309  scoped_ptr<local_discovery::PrivetLocalPrintOperation>
310      privet_local_print_operation_;
311#endif
312
313  base::WeakPtrFactory<PrintPreviewHandler> weak_factory_;
314
315  DISALLOW_COPY_AND_ASSIGN(PrintPreviewHandler);
316};
317
318#endif  // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_HANDLER_H_
319