OLD | NEW |
| (Empty) |
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 #include "device/bluetooth/bluetooth_pairing_chromeos.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/metrics/histogram.h" | |
9 #include "device/bluetooth/bluetooth_device.h" | |
10 #include "device/bluetooth/bluetooth_device_chromeos.h" | |
11 | |
12 using device::BluetoothDevice; | |
13 | |
14 namespace { | |
15 | |
16 // Histogram enumerations for pairing methods. | |
17 enum UMAPairingMethod { | |
18 UMA_PAIRING_METHOD_NONE, | |
19 UMA_PAIRING_METHOD_REQUEST_PINCODE, | |
20 UMA_PAIRING_METHOD_REQUEST_PASSKEY, | |
21 UMA_PAIRING_METHOD_DISPLAY_PINCODE, | |
22 UMA_PAIRING_METHOD_DISPLAY_PASSKEY, | |
23 UMA_PAIRING_METHOD_CONFIRM_PASSKEY, | |
24 // NOTE: Add new pairing methods immediately above this line. Make sure to | |
25 // update the enum list in tools/histogram/histograms.xml accordingly. | |
26 UMA_PAIRING_METHOD_COUNT | |
27 }; | |
28 | |
29 // Number of keys that will be entered for a passkey, six digits plus the | |
30 // final enter. | |
31 const uint16 kPasskeyMaxKeysEntered = 7; | |
32 | |
33 } // namespace | |
34 | |
35 namespace chromeos { | |
36 | |
37 BluetoothPairingChromeOS::BluetoothPairingChromeOS( | |
38 BluetoothDeviceChromeOS* device, | |
39 BluetoothDevice::PairingDelegate* pairing_delegate) | |
40 : device_(device), | |
41 pairing_delegate_(pairing_delegate), | |
42 pairing_delegate_used_(false) { | |
43 VLOG(1) << "Created BluetoothPairingChromeOS for " | |
44 << device_->GetAddress(); | |
45 } | |
46 | |
47 BluetoothPairingChromeOS::~BluetoothPairingChromeOS() { | |
48 VLOG(1) << "Destroying BluetoothPairingChromeOS for " | |
49 << device_->GetAddress(); | |
50 | |
51 if (!pairing_delegate_used_) { | |
52 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", | |
53 UMA_PAIRING_METHOD_NONE, | |
54 UMA_PAIRING_METHOD_COUNT); | |
55 } | |
56 | |
57 if (!pincode_callback_.is_null()) { | |
58 pincode_callback_.Run( | |
59 bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED, ""); | |
60 } | |
61 | |
62 if (!passkey_callback_.is_null()) { | |
63 passkey_callback_.Run( | |
64 bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED, 0); | |
65 } | |
66 | |
67 if (!confirmation_callback_.is_null()) { | |
68 confirmation_callback_.Run( | |
69 bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED); | |
70 } | |
71 | |
72 pairing_delegate_ = NULL; | |
73 } | |
74 | |
75 void BluetoothPairingChromeOS::RequestPinCode( | |
76 const bluez::BluetoothAgentServiceProvider::Delegate::PinCodeCallback& | |
77 callback) { | |
78 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", | |
79 UMA_PAIRING_METHOD_REQUEST_PINCODE, | |
80 UMA_PAIRING_METHOD_COUNT); | |
81 | |
82 ResetCallbacks(); | |
83 pincode_callback_ = callback; | |
84 pairing_delegate_used_ = true; | |
85 pairing_delegate_->RequestPinCode(device_); | |
86 } | |
87 | |
88 bool BluetoothPairingChromeOS::ExpectingPinCode() const { | |
89 return !pincode_callback_.is_null(); | |
90 } | |
91 | |
92 void BluetoothPairingChromeOS::SetPinCode(const std::string& pincode) { | |
93 if (pincode_callback_.is_null()) | |
94 return; | |
95 | |
96 pincode_callback_.Run(bluez::BluetoothAgentServiceProvider::Delegate::SUCCESS, | |
97 pincode); | |
98 pincode_callback_.Reset(); | |
99 | |
100 // If this is not an outgoing connection to the device, clean up the pairing | |
101 // context since the pairing is done. The outgoing connection case is cleaned | |
102 // up in the callback for the underlying Pair() call. | |
103 if (!device_->IsConnecting()) | |
104 device_->EndPairing(); | |
105 } | |
106 | |
107 void BluetoothPairingChromeOS::DisplayPinCode(const std::string& pincode) { | |
108 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", | |
109 UMA_PAIRING_METHOD_DISPLAY_PINCODE, | |
110 UMA_PAIRING_METHOD_COUNT); | |
111 | |
112 ResetCallbacks(); | |
113 pairing_delegate_used_ = true; | |
114 pairing_delegate_->DisplayPinCode(device_, pincode); | |
115 | |
116 // If this is not an outgoing connection to the device, the pairing context | |
117 // needs to be cleaned up again as there's no reliable indication of | |
118 // completion of incoming pairing. | |
119 if (!device_->IsConnecting()) | |
120 device_->EndPairing(); | |
121 } | |
122 | |
123 void BluetoothPairingChromeOS::RequestPasskey( | |
124 const bluez::BluetoothAgentServiceProvider::Delegate::PasskeyCallback& | |
125 callback) { | |
126 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", | |
127 UMA_PAIRING_METHOD_REQUEST_PASSKEY, | |
128 UMA_PAIRING_METHOD_COUNT); | |
129 | |
130 ResetCallbacks(); | |
131 passkey_callback_ = callback; | |
132 pairing_delegate_used_ = true; | |
133 pairing_delegate_->RequestPasskey(device_); | |
134 } | |
135 | |
136 bool BluetoothPairingChromeOS::ExpectingPasskey() const { | |
137 return !passkey_callback_.is_null(); | |
138 } | |
139 | |
140 void BluetoothPairingChromeOS::SetPasskey(uint32 passkey) { | |
141 if (passkey_callback_.is_null()) | |
142 return; | |
143 | |
144 passkey_callback_.Run(bluez::BluetoothAgentServiceProvider::Delegate::SUCCESS, | |
145 passkey); | |
146 passkey_callback_.Reset(); | |
147 | |
148 // If this is not an outgoing connection to the device, clean up the pairing | |
149 // context since the pairing is done. The outgoing connection case is cleaned | |
150 // up in the callback for the underlying Pair() call. | |
151 if (!device_->IsConnecting()) | |
152 device_->EndPairing(); | |
153 } | |
154 | |
155 void BluetoothPairingChromeOS::DisplayPasskey(uint32 passkey) { | |
156 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", | |
157 UMA_PAIRING_METHOD_DISPLAY_PASSKEY, | |
158 UMA_PAIRING_METHOD_COUNT); | |
159 | |
160 ResetCallbacks(); | |
161 pairing_delegate_used_ = true; | |
162 pairing_delegate_->DisplayPasskey(device_, passkey); | |
163 } | |
164 | |
165 void BluetoothPairingChromeOS::KeysEntered(uint16 entered) { | |
166 pairing_delegate_used_ = true; | |
167 pairing_delegate_->KeysEntered(device_, entered); | |
168 | |
169 // If this is not an outgoing connection to the device, the pairing context | |
170 // needs to be cleaned up again as there's no reliable indication of | |
171 // completion of incoming pairing. | |
172 if (entered >= kPasskeyMaxKeysEntered && !device_->IsConnecting()) | |
173 device_->EndPairing(); | |
174 } | |
175 | |
176 void BluetoothPairingChromeOS::RequestConfirmation( | |
177 uint32 passkey, | |
178 const bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback& | |
179 callback) { | |
180 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", | |
181 UMA_PAIRING_METHOD_CONFIRM_PASSKEY, | |
182 UMA_PAIRING_METHOD_COUNT); | |
183 | |
184 ResetCallbacks(); | |
185 confirmation_callback_ = callback; | |
186 pairing_delegate_used_ = true; | |
187 pairing_delegate_->ConfirmPasskey(device_, passkey); | |
188 } | |
189 | |
190 void BluetoothPairingChromeOS::RequestAuthorization( | |
191 const bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback& | |
192 callback) { | |
193 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", | |
194 UMA_PAIRING_METHOD_NONE, | |
195 UMA_PAIRING_METHOD_COUNT); | |
196 | |
197 ResetCallbacks(); | |
198 confirmation_callback_ = callback; | |
199 pairing_delegate_used_ = true; | |
200 pairing_delegate_->AuthorizePairing(device_); | |
201 } | |
202 | |
203 bool BluetoothPairingChromeOS::ExpectingConfirmation() const { | |
204 return !confirmation_callback_.is_null(); | |
205 } | |
206 | |
207 void BluetoothPairingChromeOS::ConfirmPairing() { | |
208 if (confirmation_callback_.is_null()) | |
209 return; | |
210 | |
211 confirmation_callback_.Run( | |
212 bluez::BluetoothAgentServiceProvider::Delegate::SUCCESS); | |
213 confirmation_callback_.Reset(); | |
214 | |
215 // If this is not an outgoing connection to the device, clean up the pairing | |
216 // context since the pairing is done. The outgoing connection case is cleaned | |
217 // up in the callback for the underlying Pair() call. | |
218 if (!device_->IsConnecting()) | |
219 device_->EndPairing(); | |
220 } | |
221 | |
222 bool BluetoothPairingChromeOS::RejectPairing() { | |
223 return RunPairingCallbacks( | |
224 bluez::BluetoothAgentServiceProvider::Delegate::REJECTED); | |
225 } | |
226 | |
227 bool BluetoothPairingChromeOS::CancelPairing() { | |
228 return RunPairingCallbacks( | |
229 bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED); | |
230 } | |
231 | |
232 BluetoothDevice::PairingDelegate* | |
233 BluetoothPairingChromeOS::GetPairingDelegate() const { | |
234 return pairing_delegate_; | |
235 } | |
236 | |
237 void BluetoothPairingChromeOS::ResetCallbacks() { | |
238 pincode_callback_.Reset(); | |
239 passkey_callback_.Reset(); | |
240 confirmation_callback_.Reset(); | |
241 } | |
242 | |
243 bool BluetoothPairingChromeOS::RunPairingCallbacks( | |
244 bluez::BluetoothAgentServiceProvider::Delegate::Status status) { | |
245 pairing_delegate_used_ = true; | |
246 | |
247 bool callback_run = false; | |
248 if (!pincode_callback_.is_null()) { | |
249 pincode_callback_.Run(status, ""); | |
250 pincode_callback_.Reset(); | |
251 callback_run = true; | |
252 } | |
253 | |
254 if (!passkey_callback_.is_null()) { | |
255 passkey_callback_.Run(status, 0); | |
256 passkey_callback_.Reset(); | |
257 callback_run = true; | |
258 } | |
259 | |
260 if (!confirmation_callback_.is_null()) { | |
261 confirmation_callback_.Run(status); | |
262 confirmation_callback_.Reset(); | |
263 callback_run = true; | |
264 } | |
265 | |
266 // If this is not an outgoing connection to the device, clean up the pairing | |
267 // context since the pairing is done. The outgoing connection case is cleaned | |
268 // up in the callback for the underlying Pair() call. | |
269 if (!device_->IsConnecting()) | |
270 device_->EndPairing(); | |
271 | |
272 return callback_run; | |
273 } | |
274 | |
275 } // namespace chromeos | |
OLD | NEW |