1// Copyright 2013 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_LOCAL_DISCOVERY_LOCAL_DISCOVERY_UI_HANDLER_H_
6#define CHROME_BROWSER_UI_WEBUI_LOCAL_DISCOVERY_LOCAL_DISCOVERY_UI_HANDLER_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/cancelable_callback.h"
13#include "base/prefs/pref_member.h"
14#include "chrome/browser/local_discovery/cloud_device_list.h"
15#include "chrome/browser/local_discovery/cloud_print_printer_list.h"
16#include "chrome/browser/local_discovery/privet_device_lister.h"
17#include "chrome/browser/local_discovery/privet_http.h"
18#include "chrome/browser/local_discovery/privetv3_setup_flow.h"
19#include "components/signin/core/browser/signin_manager.h"
20#include "content/public/browser/web_ui_message_handler.h"
21
22#if defined(ENABLE_FULL_PRINTING) && !defined(OS_CHROMEOS)
23#define CLOUD_PRINT_CONNECTOR_UI_AVAILABLE
24#endif
25
26#if defined(ENABLE_WIFI_BOOTSTRAPPING)
27#include "chrome/browser/local_discovery/wifi/bootstrapping_device_lister.h"
28#include "chrome/browser/local_discovery/wifi/wifi_manager.h"
29#endif
30
31// TODO(noamsml): Factor out full registration flow into single class
32namespace local_discovery {
33
34class PrivetConfirmApiCallFlow;
35class PrivetHTTPAsynchronousFactory;
36class PrivetHTTPResolution;
37class PrivetV1HTTPClient;
38class ServiceDiscoverySharedClient;
39
40// UI Handler for chrome://devices/
41// It listens to local discovery notifications and passes those notifications
42// into the Javascript to update the page.
43class LocalDiscoveryUIHandler : public content::WebUIMessageHandler,
44                                public PrivetRegisterOperation::Delegate,
45                                public PrivetV3SetupFlow::Delegate,
46                                public PrivetDeviceLister::Delegate,
47                                public CloudDeviceListDelegate,
48                                public SigninManagerBase::Observer {
49 public:
50  LocalDiscoveryUIHandler();
51  virtual ~LocalDiscoveryUIHandler();
52
53  static bool GetHasVisible();
54
55  // WebUIMessageHandler implementation.
56  virtual void RegisterMessages() OVERRIDE;
57  // PrivetRegisterOperation::Delegate implementation.
58  virtual void OnPrivetRegisterClaimToken(
59      PrivetRegisterOperation* operation,
60      const std::string& token,
61      const GURL& url) OVERRIDE;
62  virtual void OnPrivetRegisterError(
63      PrivetRegisterOperation* operation,
64      const std::string& action,
65      PrivetRegisterOperation::FailureReason reason,
66      int printer_http_code,
67      const base::DictionaryValue* json) OVERRIDE;
68  virtual void OnPrivetRegisterDone(
69      PrivetRegisterOperation* operation,
70      const std::string& device_id) OVERRIDE;
71
72  // PrivetV3SetupFlow::Delegate implementation.
73  virtual scoped_ptr<GCDApiFlow> CreateApiFlow() OVERRIDE;
74  virtual void GetWiFiCredentials(const CredentialsCallback& callback) OVERRIDE;
75  virtual void SwitchToSetupWiFi(const ResultCallback& callback) OVERRIDE;
76  virtual void CreatePrivetV3Client(
77      const std::string& service_name,
78      const PrivetClientCallback& callback) OVERRIDE;
79  virtual void ConfirmSecurityCode(const std::string& confirmation_code,
80                                   const ResultCallback& callback) OVERRIDE;
81  virtual void RestoreWifi(const ResultCallback& callback) OVERRIDE;
82  virtual void OnSetupDone() OVERRIDE;
83  virtual void OnSetupError() OVERRIDE;
84
85  // PrivetDeviceLister::Delegate implementation.
86  virtual void DeviceChanged(bool added,
87                             const std::string& name,
88                             const DeviceDescription& description) OVERRIDE;
89  virtual void DeviceRemoved(const std::string& name) OVERRIDE;
90  virtual void DeviceCacheFlushed() OVERRIDE;
91
92  // CloudDeviceListDelegate implementation.
93  virtual void OnDeviceListReady(const std::vector<Device>& devices) OVERRIDE;
94  virtual void OnDeviceListUnavailable() OVERRIDE;
95
96  // SigninManagerBase::Observer implementation.
97  virtual void GoogleSigninSucceeded(const std::string& account_id,
98                                     const std::string& username,
99                                     const std::string& password) OVERRIDE;
100  virtual void GoogleSignedOut(const std::string& account_id,
101                               const std::string& username) OVERRIDE;
102
103 private:
104  typedef std::map<std::string, DeviceDescription> DeviceDescriptionMap;
105
106  // Message handlers:
107  // For when the page is ready to receive device notifications.
108  void HandleStart(const base::ListValue* args);
109
110  // For when a visibility change occurs.
111  void HandleIsVisible(const base::ListValue* args);
112
113  // For when a user choice is made.
114  void HandleRegisterDevice(const base::ListValue* args);
115
116  // For when a code is confirmed.
117  void HandleConfirmCode(const base::ListValue* args);
118
119  // For when a cancellation is made.
120  void HandleCancelRegistration(const base::ListValue* args);
121
122  // For requesting the device list.
123  void HandleRequestDeviceList(const base::ListValue* args);
124
125  // For opening URLs (relative to the Google Cloud Print base URL) in a new
126  // tab.
127  void HandleOpenCloudPrintURL(const base::ListValue* args);
128
129  // For showing sync login UI.
130  void HandleShowSyncUI(const base::ListValue* args);
131
132  // For when the IP address of the printer has been resolved for registration.
133  void StartRegisterHTTP(scoped_ptr<PrivetHTTPClient> http_client);
134
135  // For when the confirm operation on the cloudprint server has finished
136  // executing.
137  void OnConfirmDone(GCDApiFlow::Status status);
138
139  // Signal to the web interface an error has ocurred while registering.
140  void SendRegisterError();
141
142  // Singal to the web interface that registration has finished.
143  void SendRegisterDone(const std::string& service_name);
144
145  // Set the visibility of the page.
146  void SetIsVisible(bool visible);
147
148  // Get the sync account email.
149  std::string GetSyncAccount();
150
151  // Reset and cancel the current registration.
152  void ResetCurrentRegistration();
153
154  // Creates |PrivetV3HTTPClient| privet from |PrivetHTTPClient| and calls
155  // callback.
156  void PrivetClientToV3(const PrivetClientCallback& callback,
157                        scoped_ptr<PrivetHTTPClient> client);
158
159  // Announcement hasn't been sent for a certain time after registration
160  // finished. Consider it failed.
161  // TODO(noamsml): Re-resolve service first.
162  void OnAnnouncementTimeoutReached();
163
164  void CheckUserLoggedIn();
165
166  void CheckListingDone();
167
168  bool IsUserSupervisedOrOffTheRecord();
169
170#if defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE)
171  void StartCloudPrintConnector();
172  void OnCloudPrintPrefsChanged();
173  void ShowCloudPrintSetupDialog(const base::ListValue* args);
174  void HandleDisableCloudPrintConnector(const base::ListValue* args);
175  void SetupCloudPrintConnectorSection();
176  void RemoveCloudPrintConnectorSection();
177  void RefreshCloudPrintStatusFromService();
178#endif
179
180#if defined(ENABLE_WIFI_BOOTSTRAPPING)
181  void StartWifiBootstrapping();
182  void OnBootstrappingDeviceChanged(
183      bool available,
184      const wifi::BootstrappingDeviceDescription& description);
185#endif
186
187  // A map of current device descriptions provided by the PrivetDeviceLister.
188  DeviceDescriptionMap device_descriptions_;
189
190  // The service discovery client used listen for devices on the local network.
191  scoped_refptr<ServiceDiscoverySharedClient> service_discovery_client_;
192
193  // A factory for creating the privet HTTP Client.
194  scoped_ptr<PrivetHTTPAsynchronousFactory> privet_http_factory_;
195
196  // An object representing the resolution process for the privet_http_factory.
197  scoped_ptr<PrivetHTTPResolution> privet_resolution_;
198
199  // The current HTTP client (used for the current operation).
200  scoped_ptr<PrivetV1HTTPClient> current_http_client_;
201
202  // The current register operation. Only one allowed at any time.
203  scoped_ptr<PrivetRegisterOperation> current_register_operation_;
204
205  // The current Privet v3 setup operation. Only one allowed at any time.
206  scoped_ptr<PrivetV3SetupFlow> current_setup_operation_;
207
208  // The current confirm call used during the registration flow.
209  scoped_ptr<GCDApiFlow> confirm_api_call_flow_;
210
211  // The device lister used to list devices on the local network.
212  scoped_ptr<PrivetDeviceLister> privet_lister_;
213
214  // Whether or not the page is marked as visible.
215  bool is_visible_;
216
217  // List of printers from cloud print.
218  scoped_ptr<GCDApiFlow> cloud_print_printer_list_;
219  scoped_ptr<GCDApiFlow> cloud_device_list_;
220  std::vector<Device> cloud_devices_;
221  int failed_list_count_;
222  int succeded_list_count_;
223  ResultCallback device_code_callback_;
224
225#if defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE)
226  StringPrefMember cloud_print_connector_email_;
227  BooleanPrefMember cloud_print_connector_enabled_;
228  bool cloud_print_connector_ui_enabled_;
229#endif
230
231#if defined(ENABLE_WIFI_BOOTSTRAPPING)
232  scoped_ptr<wifi::WifiManager> wifi_manager_;
233  scoped_ptr<wifi::BootstrappingDeviceLister> bootstrapping_device_lister_;
234#endif
235
236  DISALLOW_COPY_AND_ASSIGN(LocalDiscoveryUIHandler);
237};
238
239#undef CLOUD_PRINT_CONNECTOR_UI_AVAILABLE
240
241}  // namespace local_discovery
242#endif  // CHROME_BROWSER_UI_WEBUI_LOCAL_DISCOVERY_LOCAL_DISCOVERY_UI_HANDLER_H_
243