| 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 |