1 // Copyright 2016 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_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_
6 #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_
7 
8 #include <map>
9 #include <memory>
10 #include <string>
11 #include <vector>
12 
13 #include "base/memory/weak_ptr.h"
14 #include "base/scoped_observer.h"
15 #include "chrome/browser/chromeos/printing/cups_printers_manager.h"
16 #include "chrome/browser/chromeos/printing/printer_configurer.h"
17 #include "chrome/browser/chromeos/printing/printer_event_tracker.h"
18 #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
19 #include "chromeos/printing/ppd_provider.h"
20 #include "chromeos/printing/printer_configuration.h"
21 #include "printing/printer_query_result.h"
22 #include "ui/shell_dialogs/select_file_dialog.h"
23 
24 namespace base {
25 class FilePath;
26 class ListValue;
27 }  // namespace base
28 
29 namespace local_discovery {
30 class EndpointResolver;
31 }  // namespace local_discovery
32 
33 namespace printing {
34 struct PrinterStatus;
35 }  // namespace printing
36 
37 class GURL;
38 class Profile;
39 
40 namespace chromeos {
41 
42 class ServerPrintersFetcher;
43 
44 namespace settings {
45 
46 // Chrome OS CUPS printing settings page UI handler.
47 class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
48                             public ui::SelectFileDialog::Listener,
49                             public CupsPrintersManager::Observer {
50  public:
51   static std::unique_ptr<CupsPrintersHandler> CreateForTesting(
52       Profile* profile,
53       scoped_refptr<PpdProvider> ppd_provider,
54       std::unique_ptr<PrinterConfigurer> printer_configurer,
55       CupsPrintersManager* printers_manager);
56 
57   CupsPrintersHandler(Profile* profile, CupsPrintersManager* printers_manager);
58   ~CupsPrintersHandler() override;
59 
60   // SettingsPageUIHandler overrides:
61   void RegisterMessages() override;
62   void OnJavascriptAllowed() override;
63   void OnJavascriptDisallowed() override;
64 
65   void SetWebUIForTest(content::WebUI* web_ui);
66 
67  private:
68   CupsPrintersHandler(Profile* profile,
69                       scoped_refptr<PpdProvider> ppd_provider,
70                       std::unique_ptr<PrinterConfigurer> printer_configurer,
71                       CupsPrintersManager* printers_manager);
72 
73   // Gets all CUPS printers and return it to WebUI.
74   void HandleGetCupsPrintersList(const base::ListValue* args);
75   void HandleUpdateCupsPrinter(const base::ListValue* args);
76   void HandleRemoveCupsPrinter(const base::ListValue* args);
77 
78   // For a CupsPrinterInfo in |args|, retrieves the relevant PrinterInfo object
79   // using an IPP call to the printer.
80   void HandleGetPrinterInfo(const base::ListValue* args);
81 
82   // Handles the callback for HandleGetPrinterInfo. |callback_id| is the
83   // identifier to resolve the correct Promise. |result| indicates if the query
84   // was successful. |printer_status| contains the current status of the
85   // printer. |make| is the detected printer manufacturer. |model| is the
86   // detected model. |make_and_model| is the unparsed printer-make-and-model
87   // string. |ipp_everywhere| indicates if configuration using the CUPS IPP
88   // Everywhere driver should be attempted. If |result| is not SUCCESS, the
89   // values of |printer_status|, |make|, |model|, |make_and_model|, and
90   // |ipp_everywhere| are not specified.
91   void OnAutoconfQueried(const std::string& callback_id,
92                          printing::PrinterQueryResult result,
93                          const printing::PrinterStatus& printer_status,
94                          const std::string& make,
95                          const std::string& model,
96                          const std::string& make_and_model,
97                          const std::vector<std::string>& document_formats,
98                          bool ipp_everywhere);
99 
100   // Handles the callback for HandleGetPrinterInfo for a discovered printer.
101   void OnAutoconfQueriedDiscovered(
102       const std::string& callback_id,
103       Printer printer,
104       printing::PrinterQueryResult result,
105       const printing::PrinterStatus& printer_status,
106       const std::string& make,
107       const std::string& model,
108       const std::string& make_and_model,
109       const std::vector<std::string>& document_formats,
110       bool ipp_everywhere);
111 
112   // Callback for PPD matching attempts;
113   void OnPpdResolved(const std::string& callback_id,
114                      base::Value info,
115                      PpdProvider::CallbackResultCode res,
116                      const Printer::PpdReference& ppd_ref,
117                      const std::string& usb_manufacturer);
118 
119   void HandleAddCupsPrinter(const base::ListValue* args);
120 
121   void HandleReconfigureCupsPrinter(const base::ListValue* args);
122 
123   void AddOrReconfigurePrinter(const base::ListValue* args,
124                                bool is_printer_edit);
125 
126   // Handles the result of adding a printer which the user specified the
127   // location of (i.e. a printer that was not 'discovered' automatically).
128   void OnAddedOrEditedSpecifiedPrinter(const std::string& callback_id,
129                                        const Printer& printer,
130                                        bool is_printer_edit,
131                                        PrinterSetupResult result);
132 
133   // Handles the result of failure to add a printer. |result_code| is used to
134   // determine the reason for the failure.
135   void OnAddOrEditPrinterError(const std::string& callback_id,
136                                PrinterSetupResult result_code);
137 
138   // Get a list of all manufacturers for which we have at least one model of
139   // printer supported.  Takes one argument, the callback id for the result.
140   // The callback will be invoked with {success: <boolean>, models:
141   // <Array<string>>}.
142   void HandleGetCupsPrinterManufacturers(const base::ListValue* args);
143 
144   // Given a manufacturer, get a list of all models of printers for which we can
145   // get drivers.  Takes two arguments - the callback id and the manufacturer
146   // name for which we want to list models.  The callback will be called with
147   // {success: <boolean>, models: Array<string>}.
148   void HandleGetCupsPrinterModels(const base::ListValue* args);
149 
150   void HandleSelectPPDFile(const base::ListValue* args);
151 
152   // PpdProvider callback handlers.
153   void ResolveManufacturersDone(const std::string& callback_id,
154                                 PpdProvider::CallbackResultCode result_code,
155                                 const std::vector<std::string>& available);
156   void ResolvePrintersDone(const std::string& manufacturer,
157                            const std::string& callback_id,
158                            PpdProvider::CallbackResultCode result_code,
159                            const PpdProvider::ResolvedPrintersList& printers);
160 
161   void HandleStartDiscovery(const base::ListValue* args);
162   void HandleStopDiscovery(const base::ListValue* args);
163 
164   // Logs printer set ups that are abandoned.
165   void HandleSetUpCancel(const base::ListValue* args);
166 
167   // Given a printer id, find the corresponding ppdManufacturer and ppdModel.
168   void HandleGetPrinterPpdManufacturerAndModel(const base::ListValue* args);
169   void OnGetPrinterPpdManufacturerAndModel(
170       const std::string& callback_id,
171       PpdProvider::CallbackResultCode result_code,
172       const std::string& manufacturer,
173       const std::string& model);
174 
175   // Emits the updated discovered printer list after new printers are received.
176   void UpdateDiscoveredPrinters();
177 
178   // Attempt to add a discovered printer.
179   void HandleAddDiscoveredPrinter(const base::ListValue* args);
180 
181   // Post printer setup callback.
182   void OnAddedDiscoveredPrinter(const std::string& callback_id,
183                                 const Printer& printer,
184                                 PrinterSetupResult result_code);
185 
186   // Code common between the discovered and manual add printer code paths.
187   void OnAddedOrEditedPrinterCommon(const Printer& printer,
188                                     PrinterSetupResult result_code,
189                                     bool is_automatic);
190 
191   // CupsPrintersManager::Observer override:
192   void OnPrintersChanged(PrinterClass printer_class,
193                          const std::vector<Printer>& printers) override;
194 
195   // Handles getting the EULA URL if available.
196   void HandleGetEulaUrl(const base::ListValue* args);
197 
198   // Post EULA URL callback.
199   void OnGetEulaUrl(const std::string& callback_id,
200                     PpdProvider::CallbackResultCode result,
201                     const std::string& eula_url);
202 
203   // ui::SelectFileDialog::Listener override:
204   void FileSelected(const base::FilePath& path,
205                     int index,
206                     void* params) override;
207 
208   // Used by FileSelected() in order to verify whether the beginning contents of
209   // the selected file contain the magic number present in all PPD files. |path|
210   // is used for display in the UI as this function calls back into javascript
211   // with |path| as the result.
212   void VerifyPpdContents(const base::FilePath& path,
213                          const std::string& contents);
214 
215   // Fires the on-manually-add-discovered-printer event with the appropriate
216   // parameters.  See https://crbug.com/835476
217   void FireManuallyAddDiscoveredPrinter(const Printer& printer);
218 
219   void OnIpResolved(const std::string& callback_id,
220                     const Printer& printer,
221                     const net::IPEndPoint& endpoint);
222 
223   void HandleQueryPrintServer(const base::ListValue* args);
224 
225   void QueryPrintServer(const std::string& callback_id,
226                         const GURL& server_url,
227                         bool should_fallback);
228 
229   void OnQueryPrintServerCompleted(
230       const std::string& callback_id,
231       bool should_fallback,
232       const ServerPrintersFetcher* sender,
233       const GURL& server_url,
234       std::vector<PrinterDetector::DetectedPrinter>&& returned_printers);
235 
236   void HandleOpenPrintManagementApp(const base::ListValue* args);
237 
238   Profile* profile_;
239 
240   // Discovery support.  discovery_active_ tracks whether or not the UI
241   // currently wants updates about printer availability.  The two vectors track
242   // the most recent list of printers in each class.
243   bool discovery_active_ = false;
244   std::vector<Printer> discovered_printers_;
245   std::vector<Printer> automatic_printers_;
246 
247   // These must be initialized before printers_manager_, as they are
248   // used by callbacks that may be issued immediately by printers_manager_.
249   //
250   // TODO(crbug/757887) - Remove this subtle initialization constraint.
251   scoped_refptr<PpdProvider> ppd_provider_;
252   std::unique_ptr<PrinterConfigurer> printer_configurer_;
253 
254   // Cached list of {printer name, PpdReference} pairs for each manufacturer
255   // that has been resolved in the lifetime of this object.
256   std::map<std::string, PpdProvider::ResolvedPrintersList> resolved_printers_;
257 
258   scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
259   std::string webui_callback_id_;
260   CupsPrintersManager* printers_manager_;
261   std::unique_ptr<local_discovery::EndpointResolver> endpoint_resolver_;
262 
263   std::unique_ptr<ServerPrintersFetcher> server_printers_fetcher_;
264 
265   ScopedObserver<CupsPrintersManager, CupsPrintersManager::Observer>
266       printers_manager_observer_;
267 
268   base::WeakPtrFactory<CupsPrintersHandler> weak_factory_{this};
269 
270   DISALLOW_COPY_AND_ASSIGN(CupsPrintersHandler);
271 };
272 
273 }  // namespace settings
274 }  // namespace chromeos
275 
276 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_
277