bluetooth_device_chromeos.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_device_chromeos.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <stdio.h>
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/metrics/histogram.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_adapter_client.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_device_client.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_input_client.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/bus.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_chromeos.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "device/bluetooth/bluetooth_pairing_chromeos.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_profile_chromeos.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothDevice;
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Histogram enumerations for pairing results.
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum UMAPairingResult {
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_SUCCESS,
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_INPROGRESS,
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_FAILED,
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_AUTH_FAILED,
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_AUTH_CANCELED,
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_AUTH_REJECTED,
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_AUTH_TIMEOUT,
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE,
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_UNKNOWN_ERROR,
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // NOTE: Add new pairing results immediately above this line. Make sure to
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // update the enum list in tools/histogram/histograms.xml accordinly.
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_PAIRING_RESULT_COUNT
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ParseModalias(const dbus::ObjectPath& object_path,
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   BluetoothDevice::VendorIDSource* vendor_id_source,
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   uint16* vendor_id,
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   uint16* product_id,
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   uint16* device_id) {
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  chromeos::BluetoothDeviceClient::Properties* properties =
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      chromeos::DBusThreadManager::Get()->GetBluetoothDeviceClient()->
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          GetProperties(object_path);
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(properties);
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string modalias = properties->modalias.value();
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice::VendorIDSource source_value;
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int vendor_value, product_value, device_value;
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (sscanf(modalias.c_str(), "bluetooth:v%04xp%04xd%04x",
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             &vendor_value, &product_value, &device_value) == 3) {
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    source_value = BluetoothDevice::VENDOR_ID_BLUETOOTH;
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else if (sscanf(modalias.c_str(), "usb:v%04xp%04xd%04x",
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    &vendor_value, &product_value, &device_value) == 3) {
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    source_value = BluetoothDevice::VENDOR_ID_USB;
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (vendor_id_source != NULL)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    *vendor_id_source = source_value;
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (vendor_id != NULL)
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    *vendor_id = vendor_value;
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (product_id != NULL)
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    *product_id = product_value;
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (device_id != NULL)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    *device_id = device_value;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RecordPairingResult(BluetoothDevice::ConnectErrorCode error_code) {
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMAPairingResult pairing_result;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (error_code) {
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BluetoothDevice::ERROR_INPROGRESS:
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pairing_result = UMA_PAIRING_RESULT_INPROGRESS;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BluetoothDevice::ERROR_FAILED:
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pairing_result = UMA_PAIRING_RESULT_FAILED;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BluetoothDevice::ERROR_AUTH_FAILED:
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pairing_result = UMA_PAIRING_RESULT_AUTH_FAILED;
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BluetoothDevice::ERROR_AUTH_CANCELED:
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pairing_result = UMA_PAIRING_RESULT_AUTH_CANCELED;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BluetoothDevice::ERROR_AUTH_REJECTED:
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pairing_result = UMA_PAIRING_RESULT_AUTH_REJECTED;
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BluetoothDevice::ERROR_AUTH_TIMEOUT:
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pairing_result = UMA_PAIRING_RESULT_AUTH_TIMEOUT;
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BluetoothDevice::ERROR_UNSUPPORTED_DEVICE:
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pairing_result = UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pairing_result = UMA_PAIRING_RESULT_UNKNOWN_ERROR;
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult",
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            pairing_result,
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            UMA_PAIRING_RESULT_COUNT);
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos {
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothDeviceChromeOS::BluetoothDeviceChromeOS(
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    BluetoothAdapterChromeOS* adapter,
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const dbus::ObjectPath& object_path)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : adapter_(adapter),
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      object_path_(object_path),
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      num_connecting_calls_(0),
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_ptr_factory_(this) {
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() {
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)uint32 BluetoothDeviceChromeOS::GetBluetoothClass() const {
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothDeviceClient::Properties* properties =
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DBusThreadManager::Get()->GetBluetoothDeviceClient()->
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetProperties(object_path_);
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(properties);
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return properties->bluetooth_class.value();
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string BluetoothDeviceChromeOS::GetDeviceName() const {
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothDeviceClient::Properties* properties =
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DBusThreadManager::Get()->GetBluetoothDeviceClient()->
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetProperties(object_path_);
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(properties);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return properties->alias.value();
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string BluetoothDeviceChromeOS::GetAddress() const {
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothDeviceClient::Properties* properties =
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DBusThreadManager::Get()->GetBluetoothDeviceClient()->
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetProperties(object_path_);
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(properties);
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return properties->address.value();
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothDevice::VendorIDSource
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothDeviceChromeOS::GetVendorIDSource() const {
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  VendorIDSource vendor_id_source = VENDOR_ID_UNKNOWN;
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ParseModalias(object_path_, &vendor_id_source, NULL, NULL, NULL);
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return vendor_id_source;
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)uint16 BluetoothDeviceChromeOS::GetVendorID() const {
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint16 vendor_id  = 0;
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ParseModalias(object_path_, NULL, &vendor_id, NULL, NULL);
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return vendor_id;
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)uint16 BluetoothDeviceChromeOS::GetProductID() const {
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint16 product_id  = 0;
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ParseModalias(object_path_, NULL, NULL, &product_id, NULL);
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return product_id;
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)uint16 BluetoothDeviceChromeOS::GetDeviceID() const {
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint16 device_id  = 0;
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ParseModalias(object_path_, NULL, NULL, NULL, &device_id);
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return device_id;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsPaired() const {
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothDeviceClient::Properties* properties =
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DBusThreadManager::Get()->GetBluetoothDeviceClient()->
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetProperties(object_path_);
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(properties);
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Trusted devices are devices that don't support pairing but that the
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // user has explicitly connected; it makes no sense for UI purposes to
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // treat them differently from each other.
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return properties->paired.value() || properties->trusted.value();
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsConnected() const {
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothDeviceClient::Properties* properties =
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DBusThreadManager::Get()->GetBluetoothDeviceClient()->
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetProperties(object_path_);
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(properties);
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return properties->connected.value();
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsConnectable() const {
2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothInputClient::Properties* input_properties =
2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DBusThreadManager::Get()->GetBluetoothInputClient()->
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetProperties(object_path_);
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // GetProperties returns NULL when the device does not implement the given
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // interface. Non HID devices are normally connectable.
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!input_properties)
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return input_properties->reconnect_mode.value() != "device";
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsConnecting() const {
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return num_connecting_calls_ > 0;
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)BluetoothDeviceChromeOS::UUIDList BluetoothDeviceChromeOS::GetUUIDs() const {
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothDeviceClient::Properties* properties =
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DBusThreadManager::Get()->GetBluetoothDeviceClient()->
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetProperties(object_path_);
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(properties);
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return properties->uuids.value();
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::ExpectingPinCode() const {
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return pairing_.get() && pairing_->ExpectingPinCode();
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::ExpectingPasskey() const {
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return pairing_.get() && pairing_->ExpectingPasskey();
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::ExpectingConfirmation() const {
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return pairing_.get() && pairing_->ExpectingConfirmation();
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::Connect(
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    BluetoothDevice::PairingDelegate* pairing_delegate,
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ConnectErrorCallback& error_callback) {
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (num_connecting_calls_++ == 0)
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->NotifyDeviceChanged(this);
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Connecting, " << num_connecting_calls_
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          << " in progress";
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsPaired() || !pairing_delegate || !IsPairable()) {
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // No need to pair, or unable to, skip straight to connection.
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ConnectInternal(false, callback, error_callback);
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Initiate high-security connection with pairing.
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    BeginPairing(pairing_delegate);
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DBusThreadManager::Get()->GetBluetoothDeviceClient()->
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        Pair(object_path_,
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             base::Bind(&BluetoothDeviceChromeOS::OnPair,
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        weak_ptr_factory_.GetWeakPtr(),
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        callback, error_callback),
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             base::Bind(&BluetoothDeviceChromeOS::OnPairError,
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        weak_ptr_factory_.GetWeakPtr(),
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        error_callback));
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetPinCode(const std::string& pincode) {
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!pairing_.get())
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pairing_->SetPinCode(pincode);
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetPasskey(uint32 passkey) {
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!pairing_.get())
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pairing_->SetPasskey(passkey);
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ConfirmPairing() {
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!pairing_.get())
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pairing_->ConfirmPairing();
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::RejectPairing() {
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!pairing_.get())
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pairing_->RejectPairing();
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::CancelPairing() {
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool canceled = false;
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If there is a callback in progress that we can reply to then use that
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // to cancel the current pairing request.
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (pairing_.get() && pairing_->CancelPairing())
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    canceled = true;
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If not we have to send an explicit CancelPairing() to the device instead.
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!canceled) {
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    VLOG(1) << object_path_.value() << ": No pairing context or callback. "
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            << "Sending explicit cancel";
3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DBusThreadManager::Get()->GetBluetoothDeviceClient()->
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CancelPairing(
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            object_path_,
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            base::Bind(&base::DoNothing),
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            base::Bind(&BluetoothDeviceChromeOS::OnCancelPairingError,
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       weak_ptr_factory_.GetWeakPtr()));
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Since there is no callback to this method it's possible that the pairing
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // delegate is going to be freed before things complete (indeed it's
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // documented that this is the method you should call while freeing the
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pairing delegate), so clear our the context holding on to it.
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EndPairing();
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::Disconnect(const base::Closure& callback,
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                         const ErrorCallback& error_callback) {
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Disconnecting";
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DBusThreadManager::Get()->GetBluetoothDeviceClient()->
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Disconnect(
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          object_path_,
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          base::Bind(&BluetoothDeviceChromeOS::OnDisconnect,
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr(),
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     callback),
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          base::Bind(&BluetoothDeviceChromeOS::OnDisconnectError,
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr(),
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     error_callback));
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::Forget(const ErrorCallback& error_callback) {
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Removing device";
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DBusThreadManager::Get()->GetBluetoothAdapterClient()->
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      RemoveDevice(
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          adapter_->object_path_,
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          object_path_,
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          base::Bind(&base::DoNothing),
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          base::Bind(&BluetoothDeviceChromeOS::OnForgetError,
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr(),
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     error_callback));
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ConnectToService(
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& service_uuid,
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const SocketCallback& callback) {
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(keybuk): implement
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.Run(scoped_refptr<device::BluetoothSocket>());
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ConnectToProfile(
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    device::BluetoothProfile* profile,
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothProfileChromeOS* profile_chromeos =
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      static_cast<BluetoothProfileChromeOS*>(profile);
359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Connecting profile: "
360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          << profile_chromeos->uuid();
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DBusThreadManager::Get()->GetBluetoothDeviceClient()->
362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      ConnectProfile(
363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          object_path_,
364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          profile_chromeos->uuid(),
365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          base::Bind(
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              &BluetoothDeviceChromeOS::OnConnectProfile,
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              weak_ptr_factory_.GetWeakPtr(),
368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              profile,
369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              callback),
370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          base::Bind(
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              &BluetoothDeviceChromeOS::OnConnectProfileError,
372b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              weak_ptr_factory_.GetWeakPtr(),
373b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              profile,
374b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              error_callback));
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetOutOfBandPairingData(
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const device::BluetoothOutOfBandPairingData& data,
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(keybuk): implement
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_callback.Run();
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ClearOutOfBandPairingData(
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback) {
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(keybuk): implement
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_callback.Run();
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothPairingChromeOS* BluetoothDeviceChromeOS::BeginPairing(
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    BluetoothDevice::PairingDelegate* pairing_delegate) {
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pairing_.reset(new BluetoothPairingChromeOS(this, pairing_delegate));
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return pairing_.get();
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothDeviceChromeOS::EndPairing() {
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pairing_.reset();
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothPairingChromeOS* BluetoothDeviceChromeOS::GetPairing() const {
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return pairing_.get();
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ConnectInternal(
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool after_pairing,
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ConnectErrorCallback& error_callback) {
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Connecting";
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DBusThreadManager::Get()->GetBluetoothDeviceClient()->
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Connect(
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          object_path_,
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          base::Bind(&BluetoothDeviceChromeOS::OnConnect,
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr(),
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     after_pairing,
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     callback),
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          base::Bind(&BluetoothDeviceChromeOS::OnConnectError,
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr(),
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     after_pairing,
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     error_callback));
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnect(bool after_pairing,
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                        const base::Closure& callback) {
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (--num_connecting_calls_ == 0)
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->NotifyDeviceChanged(this);
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(num_connecting_calls_ >= 0);
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Connected, " << num_connecting_calls_
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        << " still in progress";
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetTrusted();
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (after_pairing)
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult",
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              UMA_PAIRING_RESULT_SUCCESS,
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              UMA_PAIRING_RESULT_COUNT);
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.Run();
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnectError(
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool after_pairing,
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ConnectErrorCallback& error_callback,
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_name,
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_message) {
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (--num_connecting_calls_ == 0)
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->NotifyDeviceChanged(this);
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(num_connecting_calls_ >= 0);
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LOG(WARNING) << object_path_.value() << ": Failed to connect device: "
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               << error_name << ": " << error_message;
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": " << num_connecting_calls_
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          << " still in progress";
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Determine the error code from error_name.
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ConnectErrorCode error_code = ERROR_UNKNOWN;
459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error_name == bluetooth_device::kErrorFailed) {
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_code = ERROR_FAILED;
461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (error_name == bluetooth_device::kErrorInProgress) {
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_code = ERROR_INPROGRESS;
463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (error_name == bluetooth_device::kErrorNotSupported) {
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_code = ERROR_UNSUPPORTED_DEVICE;
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (after_pairing)
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RecordPairingResult(error_code);
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_callback.Run(error_code);
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnPair(
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback,
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ConnectErrorCallback& error_callback) {
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Paired";
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EndPairing();
478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ConnectInternal(true, callback, error_callback);
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnPairError(
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ConnectErrorCallback& error_callback,
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_name,
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_message) {
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (--num_connecting_calls_ == 0)
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->NotifyDeviceChanged(this);
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(num_connecting_calls_ >= 0);
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LOG(WARNING) << object_path_.value() << ": Failed to pair device: "
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               << error_name << ": " << error_message;
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": " << num_connecting_calls_
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          << " still in progress";
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EndPairing();
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Determine the error code from error_name.
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ConnectErrorCode error_code = ERROR_UNKNOWN;
499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error_name == bluetooth_device::kErrorConnectionAttemptFailed) {
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_code = ERROR_FAILED;
501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (error_name == bluetooth_device::kErrorFailed) {
502b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    error_code = ERROR_FAILED;
503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (error_name == bluetooth_device::kErrorAuthenticationFailed) {
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_code = ERROR_AUTH_FAILED;
505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (error_name == bluetooth_device::kErrorAuthenticationCanceled) {
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_code = ERROR_AUTH_CANCELED;
507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (error_name == bluetooth_device::kErrorAuthenticationRejected) {
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_code = ERROR_AUTH_REJECTED;
509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (error_name == bluetooth_device::kErrorAuthenticationTimeout) {
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_code = ERROR_AUTH_TIMEOUT;
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RecordPairingResult(error_code);
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_callback.Run(error_code);
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnCancelPairingError(
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_name,
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_message) {
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LOG(WARNING) << object_path_.value() << ": Failed to cancel pairing: "
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               << error_name << ": " << error_message;
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetTrusted() {
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Unconditionally send the property change, rather than checking the value
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // first; there's no harm in doing this and it solves any race conditions
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with the property becoming true or false and this call happening before
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // we get the D-Bus signal about the earlier change.
5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DBusThreadManager::Get()->GetBluetoothDeviceClient()->
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetProperties(object_path_)->trusted.Set(
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          true,
5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          base::Bind(&BluetoothDeviceChromeOS::OnSetTrusted,
5337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr()));
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnSetTrusted(bool success) {
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LOG_IF(WARNING, !success) << object_path_.value()
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            << ": Failed to set device as trusted";
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnDisconnect(const base::Closure& callback) {
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Disconnected";
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.Run();
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnDisconnectError(
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback,
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_name,
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_message) {
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LOG(WARNING) << object_path_.value() << ": Failed to disconnect device: "
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               << error_name << ": " << error_message;
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_callback.Run();
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnForgetError(
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ErrorCallback& error_callback,
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_name,
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error_message) {
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LOG(WARNING) << object_path_.value() << ": Failed to remove device: "
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               << error_name << ": " << error_message;
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_callback.Run();
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnectProfile(
565b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    device::BluetoothProfile* profile,
566b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const base::Closure& callback) {
5677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothProfileChromeOS* profile_chromeos =
5687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      static_cast<BluetoothProfileChromeOS*>(profile);
569b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Profile connected: "
570b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          << profile_chromeos->uuid();
571b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  callback.Run();
572b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
573b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
5747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnectProfileError(
575b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    device::BluetoothProfile* profile,
576b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const ErrorCallback& error_callback,
577b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const std::string& error_name,
578b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const std::string& error_message) {
5797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BluetoothProfileChromeOS* profile_chromeos =
5807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      static_cast<BluetoothProfileChromeOS*>(profile);
581b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  VLOG(1) << object_path_.value() << ": Profile connection failed: "
582b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          << profile_chromeos->uuid() << ": "
583b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          << error_name << ": " << error_message;
584b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  error_callback.Run();
585b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
586b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace chromeos
588