summaryrefslogtreecommitdiffstats
path: root/chromium/device/bluetooth/bluetooth_pairing_chromeos.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/device/bluetooth/bluetooth_pairing_chromeos.cc')
-rw-r--r--chromium/device/bluetooth/bluetooth_pairing_chromeos.cc273
1 files changed, 273 insertions, 0 deletions
diff --git a/chromium/device/bluetooth/bluetooth_pairing_chromeos.cc b/chromium/device/bluetooth/bluetooth_pairing_chromeos.cc
new file mode 100644
index 00000000000..dc73f6d7f6c
--- /dev/null
+++ b/chromium/device/bluetooth/bluetooth_pairing_chromeos.cc
@@ -0,0 +1,273 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/bluetooth_pairing_chromeos.h"
+
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_device_chromeos.h"
+
+using device::BluetoothDevice;
+
+namespace {
+
+// Histogram enumerations for pairing methods.
+enum UMAPairingMethod {
+ UMA_PAIRING_METHOD_NONE,
+ UMA_PAIRING_METHOD_REQUEST_PINCODE,
+ UMA_PAIRING_METHOD_REQUEST_PASSKEY,
+ UMA_PAIRING_METHOD_DISPLAY_PINCODE,
+ UMA_PAIRING_METHOD_DISPLAY_PASSKEY,
+ UMA_PAIRING_METHOD_CONFIRM_PASSKEY,
+ // NOTE: Add new pairing methods immediately above this line. Make sure to
+ // update the enum list in tools/histogram/histograms.xml accordingly.
+ UMA_PAIRING_METHOD_COUNT
+};
+
+// Number of keys that will be entered for a passkey, six digits plus the
+// final enter.
+const uint16 kPasskeyMaxKeysEntered = 7;
+
+} // namespace
+
+namespace chromeos {
+
+BluetoothPairingChromeOS::BluetoothPairingChromeOS(
+ BluetoothDeviceChromeOS* device,
+ BluetoothDevice::PairingDelegate* pairing_delegate)
+ : device_(device),
+ pairing_delegate_(pairing_delegate),
+ pairing_delegate_used_(false) {
+ VLOG(1) << "Created BluetoothPairingChromeOS for "
+ << device_->GetAddress();
+}
+
+BluetoothPairingChromeOS::~BluetoothPairingChromeOS() {
+ VLOG(1) << "Destroying BluetoothPairingChromeOS for "
+ << device_->GetAddress();
+
+ if (!pairing_delegate_used_) {
+ UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
+ UMA_PAIRING_METHOD_NONE,
+ UMA_PAIRING_METHOD_COUNT);
+ }
+
+ if (!pincode_callback_.is_null()) {
+ pincode_callback_.Run(
+ BluetoothAgentServiceProvider::Delegate::CANCELLED, "");
+ }
+
+ if (!passkey_callback_.is_null()) {
+ passkey_callback_.Run(
+ BluetoothAgentServiceProvider::Delegate::CANCELLED, 0);
+ }
+
+ if (!confirmation_callback_.is_null()) {
+ confirmation_callback_.Run(
+ BluetoothAgentServiceProvider::Delegate::CANCELLED);
+ }
+
+ pairing_delegate_ = NULL;
+}
+
+void BluetoothPairingChromeOS::RequestPinCode(
+ const BluetoothAgentServiceProvider::Delegate::PinCodeCallback& callback) {
+ UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
+ UMA_PAIRING_METHOD_REQUEST_PINCODE,
+ UMA_PAIRING_METHOD_COUNT);
+
+ ResetCallbacks();
+ pincode_callback_ = callback;
+ pairing_delegate_used_ = true;
+ pairing_delegate_->RequestPinCode(device_);
+}
+
+bool BluetoothPairingChromeOS::ExpectingPinCode() const {
+ return !pincode_callback_.is_null();
+}
+
+void BluetoothPairingChromeOS::SetPinCode(const std::string& pincode) {
+ if (pincode_callback_.is_null())
+ return;
+
+ pincode_callback_.Run(BluetoothAgentServiceProvider::Delegate::SUCCESS,
+ pincode);
+ pincode_callback_.Reset();
+
+ // If this is not an outgoing connection to the device, clean up the pairing
+ // context since the pairing is done. The outgoing connection case is cleaned
+ // up in the callback for the underlying Pair() call.
+ if (!device_->IsConnecting())
+ device_->EndPairing();
+}
+
+void BluetoothPairingChromeOS::DisplayPinCode(const std::string& pincode) {
+ UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
+ UMA_PAIRING_METHOD_DISPLAY_PINCODE,
+ UMA_PAIRING_METHOD_COUNT);
+
+ ResetCallbacks();
+ pairing_delegate_used_ = true;
+ pairing_delegate_->DisplayPinCode(device_, pincode);
+
+ // If this is not an outgoing connection to the device, the pairing context
+ // needs to be cleaned up again as there's no reliable indication of
+ // completion of incoming pairing.
+ if (!device_->IsConnecting())
+ device_->EndPairing();
+}
+
+void BluetoothPairingChromeOS::RequestPasskey(
+ const BluetoothAgentServiceProvider::Delegate::PasskeyCallback& callback) {
+ UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
+ UMA_PAIRING_METHOD_REQUEST_PASSKEY,
+ UMA_PAIRING_METHOD_COUNT);
+
+ ResetCallbacks();
+ passkey_callback_ = callback;
+ pairing_delegate_used_ = true;
+ pairing_delegate_->RequestPasskey(device_);
+}
+
+bool BluetoothPairingChromeOS::ExpectingPasskey() const {
+ return !passkey_callback_.is_null();
+}
+
+void BluetoothPairingChromeOS::SetPasskey(uint32 passkey) {
+ if (passkey_callback_.is_null())
+ return;
+
+ passkey_callback_.Run(BluetoothAgentServiceProvider::Delegate::SUCCESS,
+ passkey);
+ passkey_callback_.Reset();
+
+ // If this is not an outgoing connection to the device, clean up the pairing
+ // context since the pairing is done. The outgoing connection case is cleaned
+ // up in the callback for the underlying Pair() call.
+ if (!device_->IsConnecting())
+ device_->EndPairing();
+}
+
+void BluetoothPairingChromeOS::DisplayPasskey(uint32 passkey) {
+ UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
+ UMA_PAIRING_METHOD_DISPLAY_PASSKEY,
+ UMA_PAIRING_METHOD_COUNT);
+
+ ResetCallbacks();
+ pairing_delegate_used_ = true;
+ pairing_delegate_->DisplayPasskey(device_, passkey);
+
+}
+
+void BluetoothPairingChromeOS::KeysEntered(uint16 entered) {
+ pairing_delegate_used_ = true;
+ pairing_delegate_->KeysEntered(device_, entered);
+
+ // If this is not an outgoing connection to the device, the pairing context
+ // needs to be cleaned up again as there's no reliable indication of
+ // completion of incoming pairing.
+ if (entered >= kPasskeyMaxKeysEntered && !device_->IsConnecting())
+ device_->EndPairing();
+}
+
+void BluetoothPairingChromeOS::RequestConfirmation(
+ uint32 passkey,
+ const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
+ callback) {
+ UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
+ UMA_PAIRING_METHOD_CONFIRM_PASSKEY,
+ UMA_PAIRING_METHOD_COUNT);
+
+ ResetCallbacks();
+ confirmation_callback_ = callback;
+ pairing_delegate_used_ = true;
+ pairing_delegate_->ConfirmPasskey(device_, passkey);
+}
+
+void BluetoothPairingChromeOS::RequestAuthorization(
+ const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
+ callback) {
+ UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
+ UMA_PAIRING_METHOD_NONE,
+ UMA_PAIRING_METHOD_COUNT);
+
+ ResetCallbacks();
+ confirmation_callback_ = callback;
+ pairing_delegate_used_ = true;
+ pairing_delegate_->AuthorizePairing(device_);
+}
+
+bool BluetoothPairingChromeOS::ExpectingConfirmation() const {
+ return !confirmation_callback_.is_null();
+}
+
+void BluetoothPairingChromeOS::ConfirmPairing() {
+ if (confirmation_callback_.is_null())
+ return;
+
+ confirmation_callback_.Run(BluetoothAgentServiceProvider::Delegate::SUCCESS);
+ confirmation_callback_.Reset();
+
+ // If this is not an outgoing connection to the device, clean up the pairing
+ // context since the pairing is done. The outgoing connection case is cleaned
+ // up in the callback for the underlying Pair() call.
+ if (!device_->IsConnecting())
+ device_->EndPairing();
+}
+
+bool BluetoothPairingChromeOS::RejectPairing() {
+ return RunPairingCallbacks(
+ BluetoothAgentServiceProvider::Delegate::REJECTED);
+}
+
+bool BluetoothPairingChromeOS::CancelPairing() {
+ return RunPairingCallbacks(
+ BluetoothAgentServiceProvider::Delegate::CANCELLED);
+}
+
+BluetoothDevice::PairingDelegate*
+BluetoothPairingChromeOS::GetPairingDelegate() const {
+ return pairing_delegate_;
+}
+
+void BluetoothPairingChromeOS::ResetCallbacks() {
+ pincode_callback_.Reset();
+ passkey_callback_.Reset();
+ confirmation_callback_.Reset();
+}
+
+bool BluetoothPairingChromeOS::RunPairingCallbacks(
+ BluetoothAgentServiceProvider::Delegate::Status status) {
+ pairing_delegate_used_ = true;
+
+ bool callback_run = false;
+ if (!pincode_callback_.is_null()) {
+ pincode_callback_.Run(status, "");
+ pincode_callback_.Reset();
+ callback_run = true;
+ }
+
+ if (!passkey_callback_.is_null()) {
+ passkey_callback_.Run(status, 0);
+ passkey_callback_.Reset();
+ callback_run = true;
+ }
+
+ if (!confirmation_callback_.is_null()) {
+ confirmation_callback_.Run(status);
+ confirmation_callback_.Reset();
+ callback_run = true;
+ }
+
+ // If this is not an outgoing connection to the device, clean up the pairing
+ // context since the pairing is done. The outgoing connection case is cleaned
+ // up in the callback for the underlying Pair() call.
+ if (!device_->IsConnecting())
+ device_->EndPairing();
+
+ return callback_run;
+}
+
+} // namespace chromeos