1// Copyright 2014 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_CHROMEOS_LOGIN_HID_DETECTION_SCREEN_HANDLER_H_
6#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_HID_DETECTION_SCREEN_HANDLER_H_
7
8#include <string>
9#include <vector>
10
11#include "base/compiler_specific.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/memory/weak_ptr.h"
14#include "base/prefs/pref_registry_simple.h"
15#include "base/values.h"
16#include "chrome/browser/chromeos/device/input_service_proxy.h"
17#include "chrome/browser/chromeos/login/screens/hid_detection_screen_actor.h"
18#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
19#include "content/public/browser/web_ui.h"
20#include "device/bluetooth/bluetooth_adapter.h"
21#include "device/bluetooth/bluetooth_device.h"
22#include "device/bluetooth/bluetooth_discovery_session.h"
23
24namespace base {
25class DictionaryValue;
26}
27
28namespace chromeos {
29
30class CoreOobeActor;
31
32// WebUI implementation of HIDDetectionScreenActor.
33class HIDDetectionScreenHandler
34    : public HIDDetectionScreenActor,
35      public BaseScreenHandler,
36      public device::BluetoothAdapter::Observer,
37      public device::BluetoothDevice::PairingDelegate,
38      public InputServiceProxy::Observer {
39 public:
40  typedef device::InputServiceLinux::InputDeviceInfo InputDeviceInfo;
41
42  explicit HIDDetectionScreenHandler(CoreOobeActor* core_oobe_actor);
43  virtual ~HIDDetectionScreenHandler();
44
45  // HIDDetectionScreenActor implementation:
46  virtual void Show() OVERRIDE;
47  virtual void Hide() OVERRIDE;
48  virtual void SetDelegate(Delegate* delegate) OVERRIDE;
49  virtual void CheckIsScreenRequired(
50      const base::Callback<void(bool)>& on_check_done) OVERRIDE;
51
52  // BaseScreenHandler implementation:
53  virtual void DeclareLocalizedValues(LocalizedValuesBuilder* builder) OVERRIDE;
54  virtual void Initialize() OVERRIDE;
55
56  // WebUIMessageHandler implementation:
57  virtual void RegisterMessages() OVERRIDE;
58
59  // device::BluetoothDevice::PairingDelegate implementation:
60  virtual void RequestPinCode(device::BluetoothDevice* device) OVERRIDE;
61  virtual void RequestPasskey(device::BluetoothDevice* device) OVERRIDE;
62  virtual void DisplayPinCode(device::BluetoothDevice* device,
63                              const std::string& pincode) OVERRIDE;
64  virtual void DisplayPasskey(
65      device::BluetoothDevice* device, uint32 passkey) OVERRIDE;
66  virtual void KeysEntered(device::BluetoothDevice* device,
67                           uint32 entered) OVERRIDE;
68  virtual void ConfirmPasskey(
69      device::BluetoothDevice* device, uint32 passkey) OVERRIDE;
70  virtual void AuthorizePairing(device::BluetoothDevice* device) OVERRIDE;
71
72  // device::BluetoothAdapter::Observer implementation.
73  virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter,
74                                     bool present) OVERRIDE;
75  virtual void DeviceAdded(device::BluetoothAdapter* adapter,
76                           device::BluetoothDevice* device) OVERRIDE;
77  virtual void DeviceChanged(device::BluetoothAdapter* adapter,
78                             device::BluetoothDevice* device) OVERRIDE;
79  virtual void DeviceRemoved(device::BluetoothAdapter* adapter,
80                             device::BluetoothDevice* device) OVERRIDE;
81
82  // InputServiceProxy::Observer implementation.
83  virtual void OnInputDeviceAdded(const InputDeviceInfo& info) OVERRIDE;
84  virtual void OnInputDeviceRemoved(const std::string& id) OVERRIDE;
85
86  // Registers the preference for derelict state.
87  static void RegisterPrefs(PrefRegistrySimple* registry);
88
89 private:
90  // Types of dialog leaving scenarios for UMA metric.
91  enum ContinueScenarioType {
92    // Only pointing device detected, user pressed 'Continue'.
93    POINTING_DEVICE_ONLY_DETECTED,
94
95    // Only keyboard detected, user pressed 'Continue'.
96    KEYBOARD_DEVICE_ONLY_DETECTED,
97
98    // All devices detected.
99    All_DEVICES_DETECTED,
100
101    // Must be last enum element.
102    CONTINUE_SCENARIO_TYPE_SIZE
103  };
104
105  void InitializeAdapter(scoped_refptr<device::BluetoothAdapter> adapter);
106
107  // Sends a notification to the Web UI of the status of available Bluetooth/USB
108  // pointing device.
109  void SendPointingDeviceNotification();
110
111  // Sends a notification to the Web UI of the status of available Bluetooth/USB
112  // keyboard device.
113  void SendKeyboardDeviceNotification(base::DictionaryValue* params);
114
115  // Updates internal state and UI (if ready) using list of connected devices.
116  void ProcessConnectedDevicesList(const std::vector<InputDeviceInfo>& devices);
117
118  // Checks for lack of mouse or keyboard. If found starts BT devices update.
119  // Initiates BTAdapter if it's not active and BT devices update required.
120  void TryInitiateBTDevicesUpdate();
121
122  // Processes list of input devices returned by InputServiceProxy on the check
123  // request. Calls the callback that expects true if screen is required.
124  void OnGetInputDevicesListForCheck(
125      const base::Callback<void(bool)>& on_check_done,
126      const std::vector<InputDeviceInfo>& devices);
127
128  // Processes list of input devices returned by InputServiceProxy on regular
129  // request.
130  void OnGetInputDevicesList(const std::vector<InputDeviceInfo>& devices);
131
132  void StartBTDiscoverySession();
133
134  // Called by device::BluetoothDevice on a successful pairing and connection
135  // to a device.
136  void BTConnected(device::BluetoothDevice::DeviceType device_type);
137
138  // Called by device::BluetoothDevice in response to a failure to
139  // connect to the device with bluetooth address |address| due to an error
140  // encoded in |error_code|.
141  void BTConnectError(const std::string& address,
142                      device::BluetoothDevice::DeviceType device_type,
143                      device::BluetoothDevice::ConnectErrorCode error_code);
144
145  // JS messages handlers.
146  void HandleOnContinue();
147
148  Delegate* delegate_;
149
150  CoreOobeActor* core_oobe_actor_;
151
152  // Keeps whether screen should be shown right after initialization.
153  bool show_on_init_;
154
155  // Displays in the UI a connecting to the device |device| message.
156  void DeviceConnecting(device::BluetoothDevice* device);
157
158  // Called by device::BluetoothAdapter in response to a successful request
159  // to initiate a discovery session.
160  void OnStartDiscoverySession(
161      scoped_ptr<device::BluetoothDiscoverySession> discovery_session);
162
163  // Called by device::BluetoothAdapter in response to a failure to
164  // initiate a discovery session.
165  void FindDevicesError();
166
167  // Called by device::BluetoothAdapter in response to a failure to
168  // power BT adapter.
169  void SetPoweredError();
170
171  // Called by device::BluetoothAdapter in response to a failure to
172  // power off BT adapter.
173  void SetPoweredOffError();
174
175  // Called for revision of active devices. If current-placement is available
176  // for mouse or keyboard device, sets one of active devices as current or
177  // tries to connect some BT device if no appropriate devices are connected.
178  void UpdateDevices();
179
180  // Tries to connect some BT devices if no type-appropriate devices are
181  // connected.
182  void UpdateBTDevices();
183
184  // Tries to connect given BT device.
185  void ConnectBTDevice(device::BluetoothDevice* device);
186
187  // Tries to connect given BT device as pointing one.
188  void TryPairingAsPointingDevice(device::BluetoothDevice* device);
189
190  // Tries to connect given BT device as keyboard.
191  void TryPairingAsKeyboardDevice(device::BluetoothDevice* device);
192
193  // Default bluetooth adapter, used for all operations.
194  scoped_refptr<device::BluetoothAdapter> adapter_;
195
196  InputServiceProxy input_service_proxy_;
197
198  // The current device discovery session. Only one active discovery session is
199  // kept at a time and the instance that |discovery_session_| points to gets
200  // replaced by a new one when a new discovery session is initiated.
201  scoped_ptr<device::BluetoothDiscoverySession> discovery_session_;
202
203  // Current pointing device, if any.
204  std::string pointing_device_name_;
205  std::string pointing_device_id_;
206  bool mouse_is_pairing_;
207  InputDeviceInfo::Type pointing_device_connect_type_;
208
209  // Current keyboard device, if any.
210  std::string keyboard_device_name_;
211  std::string keyboard_device_id_;
212  bool keyboard_is_pairing_;
213  InputDeviceInfo::Type keyboard_device_connect_type_;
214
215  bool switch_on_adapter_when_ready_;
216
217  // State of BT adapter before screen-initiated changes.
218  scoped_ptr<bool> adapter_initially_powered_;
219
220  base::WeakPtrFactory<HIDDetectionScreenHandler> weak_ptr_factory_;
221
222  DISALLOW_COPY_AND_ASSIGN(HIDDetectionScreenHandler);
223};
224
225}  // namespace chromeos
226
227#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_HID_DETECTION_SCREEN_HANDLER_H_
228
229