| Index: device/bluetooth/bluetooth_device_experimental_chromeos.cc
|
| diff --git a/device/bluetooth/bluetooth_device_experimental_chromeos.cc b/device/bluetooth/bluetooth_device_experimental_chromeos.cc
|
| index 09c1ddf37764ea0a3cc59c0df97688e2c38d2675..3e114399724d2ea298654b5f20361fbe79f16d04 100644
|
| --- a/device/bluetooth/bluetooth_device_experimental_chromeos.cc
|
| +++ b/device/bluetooth/bluetooth_device_experimental_chromeos.cc
|
| @@ -5,6 +5,9 @@
|
| #include "device/bluetooth/bluetooth_device_experimental_chromeos.h"
|
|
|
| #include "base/bind.h"
|
| +#include "base/metrics/histogram.h"
|
| +#include "base/string_util.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| #include "chromeos/dbus/dbus_thread_manager.h"
|
| #include "chromeos/dbus/experimental_bluetooth_adapter_client.h"
|
| #include "chromeos/dbus/experimental_bluetooth_agent_manager_client.h"
|
| @@ -25,6 +28,67 @@ namespace {
|
| // (which we fail in OnRegisterAgentError with ERROR_INPROGRESS).
|
| const char kAgentPath[] = "/org/chromium/bluetooth_agent";
|
|
|
| +// 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 accordinly.
|
| + UMA_PAIRING_METHOD_COUNT
|
| +};
|
| +
|
| +// Histogram enumerations for pairing results.
|
| +enum UMAPairingResult {
|
| + UMA_PAIRING_RESULT_SUCCESS,
|
| + UMA_PAIRING_RESULT_INPROGRESS,
|
| + UMA_PAIRING_RESULT_FAILED,
|
| + UMA_PAIRING_RESULT_AUTH_FAILED,
|
| + UMA_PAIRING_RESULT_AUTH_CANCELED,
|
| + UMA_PAIRING_RESULT_AUTH_REJECTED,
|
| + UMA_PAIRING_RESULT_AUTH_TIMEOUT,
|
| + UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE,
|
| + UMA_PAIRING_RESULT_UNKNOWN_ERROR,
|
| + // NOTE: Add new pairing results immediately above this line. Make sure to
|
| + // update the enum list in tools/histogram/histograms.xml accordinly.
|
| + UMA_PAIRING_RESULT_COUNT
|
| +};
|
| +
|
| +void ParseModalias(const dbus::ObjectPath& object_path,
|
| + uint16 *vendor_id,
|
| + uint16 *product_id,
|
| + uint16 *device_id) {
|
| + chromeos::ExperimentalBluetoothDeviceClient::Properties* properties =
|
| + chromeos::DBusThreadManager::Get()->
|
| + GetExperimentalBluetoothDeviceClient()->GetProperties(object_path);
|
| + DCHECK(properties);
|
| +
|
| + std::string modalias = properties->modalias.value();
|
| + if (StartsWithASCII(modalias, "usb:", false) && modalias.length() == 19) {
|
| + // usb:vXXXXpXXXXdXXXX
|
| + if (modalias[4] == 'v' && vendor_id != NULL) {
|
| + uint64 component = 0;
|
| + base::HexStringToUInt64(modalias.substr(5, 4), &component);
|
| + *vendor_id = component;
|
| + }
|
| +
|
| + if (modalias[9] == 'p' && product_id != NULL) {
|
| + uint64 component = 0;
|
| + base::HexStringToUInt64(modalias.substr(10, 4), &component);
|
| + *product_id = component;
|
| + }
|
| +
|
| + if (modalias[14] == 'd' && device_id != NULL) {
|
| + uint64 component = 0;
|
| + base::HexStringToUInt64(modalias.substr(15, 4), &component);
|
| + *device_id = component;
|
| + }
|
| + }
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace chromeos {
|
| @@ -36,6 +100,7 @@ BluetoothDeviceExperimentalChromeOS::BluetoothDeviceExperimentalChromeOS(
|
| object_path_(object_path),
|
| num_connecting_calls_(0),
|
| pairing_delegate_(NULL),
|
| + pairing_delegate_used_(false),
|
| weak_ptr_factory_(this) {
|
| }
|
|
|
| @@ -69,6 +134,24 @@ std::string BluetoothDeviceExperimentalChromeOS::GetAddress() const {
|
| return properties->address.value();
|
| }
|
|
|
| +uint16 BluetoothDeviceExperimentalChromeOS::GetVendorID() const {
|
| + uint16 vendor_id = 0;
|
| + ParseModalias(object_path_, &vendor_id, NULL, NULL);
|
| + return vendor_id;
|
| +}
|
| +
|
| +uint16 BluetoothDeviceExperimentalChromeOS::GetProductID() const {
|
| + uint16 product_id = 0;
|
| + ParseModalias(object_path_, NULL, &product_id, NULL);
|
| + return product_id;
|
| +}
|
| +
|
| +uint16 BluetoothDeviceExperimentalChromeOS::GetDeviceID() const {
|
| + uint16 device_id = 0;
|
| + ParseModalias(object_path_, NULL, NULL, &device_id);
|
| + return device_id;
|
| +}
|
| +
|
| bool BluetoothDeviceExperimentalChromeOS::IsPaired() const {
|
| ExperimentalBluetoothDeviceClient::Properties* properties =
|
| DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
|
| @@ -161,6 +244,7 @@ void BluetoothDeviceExperimentalChromeOS::Connect(
|
| DCHECK(agent_.get() == NULL);
|
|
|
| pairing_delegate_ = pairing_delegate;
|
| + pairing_delegate_used_ = false;
|
|
|
| // The agent path is relatively meaningless since BlueZ only supports
|
| // one per application at a time.
|
| @@ -310,6 +394,10 @@ void BluetoothDeviceExperimentalChromeOS::RequestPinCode(
|
| DCHECK(device_path == object_path_);
|
| VLOG(1) << object_path_.value() << ": RequestPinCode";
|
|
|
| + UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
|
| + UMA_PAIRING_METHOD_REQUEST_PINCODE,
|
| + UMA_PAIRING_METHOD_COUNT);
|
| +
|
| DCHECK(pairing_delegate_);
|
| DCHECK(pincode_callback_.is_null());
|
| pincode_callback_ = callback;
|
| @@ -323,6 +411,10 @@ void BluetoothDeviceExperimentalChromeOS::DisplayPinCode(
|
| DCHECK(device_path == object_path_);
|
| VLOG(1) << object_path_.value() << ": DisplayPinCode: " << pincode;
|
|
|
| + UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
|
| + UMA_PAIRING_METHOD_DISPLAY_PINCODE,
|
| + UMA_PAIRING_METHOD_COUNT);
|
| +
|
| DCHECK(pairing_delegate_);
|
| pairing_delegate_->DisplayPinCode(this, pincode);
|
| }
|
| @@ -334,6 +426,10 @@ void BluetoothDeviceExperimentalChromeOS::RequestPasskey(
|
| DCHECK(device_path == object_path_);
|
| VLOG(1) << object_path_.value() << ": RequestPasskey";
|
|
|
| + UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
|
| + UMA_PAIRING_METHOD_REQUEST_PASSKEY,
|
| + UMA_PAIRING_METHOD_COUNT);
|
| +
|
| DCHECK(pairing_delegate_);
|
| DCHECK(passkey_callback_.is_null());
|
| passkey_callback_ = callback;
|
| @@ -349,6 +445,11 @@ void BluetoothDeviceExperimentalChromeOS::DisplayPasskey(
|
| VLOG(1) << object_path_.value() << ": DisplayPasskey: " << passkey
|
| << " (" << entered << " entered)";
|
|
|
| + if (entered == 0)
|
| + UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
|
| + UMA_PAIRING_METHOD_DISPLAY_PASSKEY,
|
| + UMA_PAIRING_METHOD_COUNT);
|
| +
|
| DCHECK(pairing_delegate_);
|
| if (entered == 0)
|
| pairing_delegate_->DisplayPasskey(this, passkey);
|
| @@ -363,6 +464,10 @@ void BluetoothDeviceExperimentalChromeOS::RequestConfirmation(
|
| DCHECK(device_path == object_path_);
|
| VLOG(1) << object_path_.value() << ": RequestConfirmation: " << passkey;
|
|
|
| + UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
|
| + UMA_PAIRING_METHOD_CONFIRM_PASSKEY,
|
| + UMA_PAIRING_METHOD_COUNT);
|
| +
|
| DCHECK(pairing_delegate_);
|
| DCHECK(confirmation_callback_.is_null());
|
| confirmation_callback_ = callback;
|
| @@ -446,6 +551,7 @@ void BluetoothDeviceExperimentalChromeOS::OnConnectError(
|
| error_code = ERROR_UNSUPPORTED_DEVICE;
|
| }
|
|
|
| + RecordPairingResult(false, error_code);
|
| error_callback.Run(error_code);
|
| }
|
|
|
| @@ -486,6 +592,7 @@ void BluetoothDeviceExperimentalChromeOS::OnRegisterAgentError(
|
| if (error_name == bluetooth_adapter::kErrorAlreadyExists)
|
| error_code = ERROR_INPROGRESS;
|
|
|
| + RecordPairingResult(false, error_code);
|
| error_callback.Run(error_code);
|
| }
|
|
|
| @@ -493,6 +600,11 @@ void BluetoothDeviceExperimentalChromeOS::OnPair(
|
| const base::Closure& callback,
|
| const ConnectErrorCallback& error_callback) {
|
| VLOG(1) << object_path_.value() << ": Paired";
|
| +
|
| + if (!pairing_delegate_used_)
|
| + UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
|
| + UMA_PAIRING_METHOD_NONE,
|
| + UMA_PAIRING_METHOD_COUNT);
|
| UnregisterAgent();
|
| SetTrusted();
|
| ConnectInternal(callback, error_callback);
|
| @@ -527,6 +639,7 @@ void BluetoothDeviceExperimentalChromeOS::OnPairError(
|
| error_code = ERROR_AUTH_TIMEOUT;
|
| }
|
|
|
| + RecordPairingResult(false, error_code);
|
| error_callback.Run(error_code);
|
| }
|
|
|
| @@ -636,4 +749,43 @@ bool BluetoothDeviceExperimentalChromeOS::RunPairingCallbacks(Status status) {
|
| return callback_run;
|
| }
|
|
|
| +void BluetoothDeviceExperimentalChromeOS::RecordPairingResult(
|
| + bool success,
|
| + ConnectErrorCode error_code) {
|
| + UMAPairingResult pairing_result;
|
| + if (success) {
|
| + pairing_result = UMA_PAIRING_RESULT_SUCCESS;
|
| + } else {
|
| + switch (error_code) {
|
| + case ERROR_INPROGRESS:
|
| + pairing_result = UMA_PAIRING_RESULT_INPROGRESS;
|
| + break;
|
| + case ERROR_FAILED:
|
| + pairing_result = UMA_PAIRING_RESULT_FAILED;
|
| + break;
|
| + case ERROR_AUTH_FAILED:
|
| + pairing_result = UMA_PAIRING_RESULT_AUTH_FAILED;
|
| + break;
|
| + case ERROR_AUTH_CANCELED:
|
| + pairing_result = UMA_PAIRING_RESULT_AUTH_CANCELED;
|
| + break;
|
| + case ERROR_AUTH_REJECTED:
|
| + pairing_result = UMA_PAIRING_RESULT_AUTH_REJECTED;
|
| + break;
|
| + case ERROR_AUTH_TIMEOUT:
|
| + pairing_result = UMA_PAIRING_RESULT_AUTH_TIMEOUT;
|
| + break;
|
| + case ERROR_UNSUPPORTED_DEVICE:
|
| + pairing_result = UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE;
|
| + break;
|
| + default:
|
| + pairing_result = UMA_PAIRING_RESULT_UNKNOWN_ERROR;
|
| + }
|
| + }
|
| +
|
| + UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult",
|
| + pairing_result,
|
| + UMA_PAIRING_RESULT_COUNT);
|
| +}
|
| +
|
| } // namespace chromeos
|
|
|