1 // Copyright 2013 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.
5 #include "device/bluetooth/bluetooth_device_chromeos.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/histogram.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h"
14 #include "chromeos/dbus/bluetooth_adapter_client.h"
15 #include "chromeos/dbus/bluetooth_device_client.h"
16 #include "chromeos/dbus/bluetooth_gatt_service_client.h"
17 #include "chromeos/dbus/bluetooth_input_client.h"
18 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
21 #include "device/bluetooth/bluetooth_gatt_connection_chromeos.h"
22 #include "device/bluetooth/bluetooth_pairing_chromeos.h"
23 #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
24 #include "device/bluetooth/bluetooth_socket.h"
25 #include "device/bluetooth/bluetooth_socket_chromeos.h"
26 #include "device/bluetooth/bluetooth_socket_thread.h"
27 #include "device/bluetooth/bluetooth_uuid.h"
28 #include "third_party/cros_system_api/dbus/service_constants.h"
30 using device::BluetoothDevice
;
31 using device::BluetoothSocket
;
32 using device::BluetoothUUID
;
36 // Histogram enumerations for pairing results.
37 enum UMAPairingResult
{
38 UMA_PAIRING_RESULT_SUCCESS
,
39 UMA_PAIRING_RESULT_INPROGRESS
,
40 UMA_PAIRING_RESULT_FAILED
,
41 UMA_PAIRING_RESULT_AUTH_FAILED
,
42 UMA_PAIRING_RESULT_AUTH_CANCELED
,
43 UMA_PAIRING_RESULT_AUTH_REJECTED
,
44 UMA_PAIRING_RESULT_AUTH_TIMEOUT
,
45 UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE
,
46 UMA_PAIRING_RESULT_UNKNOWN_ERROR
,
47 // NOTE: Add new pairing results immediately above this line. Make sure to
48 // update the enum list in tools/histogram/histograms.xml accordinly.
49 UMA_PAIRING_RESULT_COUNT
52 void ParseModalias(const dbus::ObjectPath
& object_path
,
53 BluetoothDevice::VendorIDSource
* vendor_id_source
,
57 chromeos::BluetoothDeviceClient::Properties
* properties
=
58 chromeos::DBusThreadManager::Get()->GetBluetoothDeviceClient()->
59 GetProperties(object_path
);
62 std::string modalias
= properties
->modalias
.value();
63 BluetoothDevice::VendorIDSource source_value
;
64 int vendor_value
, product_value
, device_value
;
66 if (sscanf(modalias
.c_str(), "bluetooth:v%04xp%04xd%04x",
67 &vendor_value
, &product_value
, &device_value
) == 3) {
68 source_value
= BluetoothDevice::VENDOR_ID_BLUETOOTH
;
69 } else if (sscanf(modalias
.c_str(), "usb:v%04xp%04xd%04x",
70 &vendor_value
, &product_value
, &device_value
) == 3) {
71 source_value
= BluetoothDevice::VENDOR_ID_USB
;
76 if (vendor_id_source
!= NULL
)
77 *vendor_id_source
= source_value
;
78 if (vendor_id
!= NULL
)
79 *vendor_id
= vendor_value
;
80 if (product_id
!= NULL
)
81 *product_id
= product_value
;
82 if (device_id
!= NULL
)
83 *device_id
= device_value
;
86 void RecordPairingResult(BluetoothDevice::ConnectErrorCode error_code
) {
87 UMAPairingResult pairing_result
;
89 case BluetoothDevice::ERROR_INPROGRESS
:
90 pairing_result
= UMA_PAIRING_RESULT_INPROGRESS
;
92 case BluetoothDevice::ERROR_FAILED
:
93 pairing_result
= UMA_PAIRING_RESULT_FAILED
;
95 case BluetoothDevice::ERROR_AUTH_FAILED
:
96 pairing_result
= UMA_PAIRING_RESULT_AUTH_FAILED
;
98 case BluetoothDevice::ERROR_AUTH_CANCELED
:
99 pairing_result
= UMA_PAIRING_RESULT_AUTH_CANCELED
;
101 case BluetoothDevice::ERROR_AUTH_REJECTED
:
102 pairing_result
= UMA_PAIRING_RESULT_AUTH_REJECTED
;
104 case BluetoothDevice::ERROR_AUTH_TIMEOUT
:
105 pairing_result
= UMA_PAIRING_RESULT_AUTH_TIMEOUT
;
107 case BluetoothDevice::ERROR_UNSUPPORTED_DEVICE
:
108 pairing_result
= UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE
;
111 pairing_result
= UMA_PAIRING_RESULT_UNKNOWN_ERROR
;
114 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult",
116 UMA_PAIRING_RESULT_COUNT
);
123 BluetoothDeviceChromeOS::BluetoothDeviceChromeOS(
124 BluetoothAdapterChromeOS
* adapter
,
125 const dbus::ObjectPath
& object_path
,
126 scoped_refptr
<base::SequencedTaskRunner
> ui_task_runner
,
127 scoped_refptr
<device::BluetoothSocketThread
> socket_thread
)
129 object_path_(object_path
),
130 num_connecting_calls_(0),
131 connection_monitor_started_(false),
132 ui_task_runner_(ui_task_runner
),
133 socket_thread_(socket_thread
),
134 weak_ptr_factory_(this) {
135 DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this);
137 // Add all known GATT services.
138 const std::vector
<dbus::ObjectPath
> gatt_services
=
139 DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetServices();
140 for (std::vector
<dbus::ObjectPath
>::const_iterator it
= gatt_services
.begin();
141 it
!= gatt_services
.end(); ++it
) {
142 GattServiceAdded(*it
);
146 BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() {
147 DBusThreadManager::Get()->GetBluetoothGattServiceClient()->
148 RemoveObserver(this);
150 // Copy the GATT services list here and clear the original so that when we
151 // send GattServiceRemoved(), GetGattServices() returns no services.
152 GattServiceMap gatt_services
= gatt_services_
;
153 gatt_services_
.clear();
154 for (GattServiceMap::iterator iter
= gatt_services
.begin();
155 iter
!= gatt_services
.end(); ++iter
) {
157 adapter_
->NotifyGattServiceRemoved(
158 static_cast<BluetoothRemoteGattServiceChromeOS
*>(iter
->second
));
163 uint32
BluetoothDeviceChromeOS::GetBluetoothClass() const {
164 BluetoothDeviceClient::Properties
* properties
=
165 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
166 GetProperties(object_path_
);
169 return properties
->bluetooth_class
.value();
172 std::string
BluetoothDeviceChromeOS::GetDeviceName() const {
173 BluetoothDeviceClient::Properties
* properties
=
174 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
175 GetProperties(object_path_
);
178 return properties
->alias
.value();
181 std::string
BluetoothDeviceChromeOS::GetAddress() const {
182 BluetoothDeviceClient::Properties
* properties
=
183 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
184 GetProperties(object_path_
);
187 return CanonicalizeAddress(properties
->address
.value());
190 BluetoothDevice::VendorIDSource
191 BluetoothDeviceChromeOS::GetVendorIDSource() const {
192 VendorIDSource vendor_id_source
= VENDOR_ID_UNKNOWN
;
193 ParseModalias(object_path_
, &vendor_id_source
, NULL
, NULL
, NULL
);
194 return vendor_id_source
;
197 uint16
BluetoothDeviceChromeOS::GetVendorID() const {
198 uint16 vendor_id
= 0;
199 ParseModalias(object_path_
, NULL
, &vendor_id
, NULL
, NULL
);
203 uint16
BluetoothDeviceChromeOS::GetProductID() const {
204 uint16 product_id
= 0;
205 ParseModalias(object_path_
, NULL
, NULL
, &product_id
, NULL
);
209 uint16
BluetoothDeviceChromeOS::GetDeviceID() const {
210 uint16 device_id
= 0;
211 ParseModalias(object_path_
, NULL
, NULL
, NULL
, &device_id
);
215 int BluetoothDeviceChromeOS::GetRSSI() const {
216 BluetoothDeviceClient::Properties
* properties
=
217 DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
221 if (!IsConnected()) {
223 return kUnknownPower
;
226 return connection_monitor_started_
? properties
->connection_rssi
.value()
230 int BluetoothDeviceChromeOS::GetCurrentHostTransmitPower() const {
231 BluetoothDeviceClient::Properties
* properties
=
232 DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
236 return IsConnected() && connection_monitor_started_
237 ? properties
->connection_tx_power
.value()
241 int BluetoothDeviceChromeOS::GetMaximumHostTransmitPower() const {
242 BluetoothDeviceClient::Properties
* properties
=
243 DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
247 return IsConnected() ? properties
->connection_tx_power_max
.value()
251 bool BluetoothDeviceChromeOS::IsPaired() const {
252 BluetoothDeviceClient::Properties
* properties
=
253 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
254 GetProperties(object_path_
);
257 // Trusted devices are devices that don't support pairing but that the
258 // user has explicitly connected; it makes no sense for UI purposes to
259 // treat them differently from each other.
260 return properties
->paired
.value() || properties
->trusted
.value();
263 bool BluetoothDeviceChromeOS::IsConnected() const {
264 BluetoothDeviceClient::Properties
* properties
=
265 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
266 GetProperties(object_path_
);
269 return properties
->connected
.value();
272 bool BluetoothDeviceChromeOS::IsConnectable() const {
273 BluetoothInputClient::Properties
* input_properties
=
274 DBusThreadManager::Get()->GetBluetoothInputClient()->
275 GetProperties(object_path_
);
276 // GetProperties returns NULL when the device does not implement the given
277 // interface. Non HID devices are normally connectable.
278 if (!input_properties
)
281 return input_properties
->reconnect_mode
.value() != "device";
284 bool BluetoothDeviceChromeOS::IsConnecting() const {
285 return num_connecting_calls_
> 0;
288 BluetoothDeviceChromeOS::UUIDList
BluetoothDeviceChromeOS::GetUUIDs() const {
289 BluetoothDeviceClient::Properties
* properties
=
290 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
291 GetProperties(object_path_
);
294 std::vector
<device::BluetoothUUID
> uuids
;
295 const std::vector
<std::string
> &dbus_uuids
= properties
->uuids
.value();
296 for (std::vector
<std::string
>::const_iterator iter
= dbus_uuids
.begin();
297 iter
!= dbus_uuids
.end(); ++iter
) {
298 device::BluetoothUUID
uuid(*iter
);
299 DCHECK(uuid
.IsValid());
300 uuids
.push_back(uuid
);
305 bool BluetoothDeviceChromeOS::ExpectingPinCode() const {
306 return pairing_
.get() && pairing_
->ExpectingPinCode();
309 bool BluetoothDeviceChromeOS::ExpectingPasskey() const {
310 return pairing_
.get() && pairing_
->ExpectingPasskey();
313 bool BluetoothDeviceChromeOS::ExpectingConfirmation() const {
314 return pairing_
.get() && pairing_
->ExpectingConfirmation();
317 void BluetoothDeviceChromeOS::Connect(
318 BluetoothDevice::PairingDelegate
* pairing_delegate
,
319 const base::Closure
& callback
,
320 const ConnectErrorCallback
& error_callback
) {
321 if (num_connecting_calls_
++ == 0)
322 adapter_
->NotifyDeviceChanged(this);
324 VLOG(1) << object_path_
.value() << ": Connecting, " << num_connecting_calls_
327 if (IsPaired() || !pairing_delegate
|| !IsPairable()) {
328 // No need to pair, or unable to, skip straight to connection.
329 ConnectInternal(false, callback
, error_callback
);
331 // Initiate high-security connection with pairing.
332 BeginPairing(pairing_delegate
);
334 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
336 base::Bind(&BluetoothDeviceChromeOS::OnPair
,
337 weak_ptr_factory_
.GetWeakPtr(),
338 callback
, error_callback
),
339 base::Bind(&BluetoothDeviceChromeOS::OnPairError
,
340 weak_ptr_factory_
.GetWeakPtr(),
345 void BluetoothDeviceChromeOS::SetPinCode(const std::string
& pincode
) {
349 pairing_
->SetPinCode(pincode
);
352 void BluetoothDeviceChromeOS::SetPasskey(uint32 passkey
) {
356 pairing_
->SetPasskey(passkey
);
359 void BluetoothDeviceChromeOS::ConfirmPairing() {
363 pairing_
->ConfirmPairing();
366 void BluetoothDeviceChromeOS::RejectPairing() {
370 pairing_
->RejectPairing();
373 void BluetoothDeviceChromeOS::CancelPairing() {
374 bool canceled
= false;
376 // If there is a callback in progress that we can reply to then use that
377 // to cancel the current pairing request.
378 if (pairing_
.get() && pairing_
->CancelPairing())
381 // If not we have to send an explicit CancelPairing() to the device instead.
383 VLOG(1) << object_path_
.value() << ": No pairing context or callback. "
384 << "Sending explicit cancel";
385 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
388 base::Bind(&base::DoNothing
),
389 base::Bind(&BluetoothDeviceChromeOS::OnCancelPairingError
,
390 weak_ptr_factory_
.GetWeakPtr()));
393 // Since there is no callback to this method it's possible that the pairing
394 // delegate is going to be freed before things complete (indeed it's
395 // documented that this is the method you should call while freeing the
396 // pairing delegate), so clear our the context holding on to it.
400 void BluetoothDeviceChromeOS::Disconnect(const base::Closure
& callback
,
401 const ErrorCallback
& error_callback
) {
402 VLOG(1) << object_path_
.value() << ": Disconnecting";
403 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
406 base::Bind(&BluetoothDeviceChromeOS::OnDisconnect
,
407 weak_ptr_factory_
.GetWeakPtr(),
409 base::Bind(&BluetoothDeviceChromeOS::OnDisconnectError
,
410 weak_ptr_factory_
.GetWeakPtr(),
414 void BluetoothDeviceChromeOS::Forget(const ErrorCallback
& error_callback
) {
415 VLOG(1) << object_path_
.value() << ": Removing device";
416 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
418 adapter_
->object_path(),
420 base::Bind(&base::DoNothing
),
421 base::Bind(&BluetoothDeviceChromeOS::OnForgetError
,
422 weak_ptr_factory_
.GetWeakPtr(),
426 void BluetoothDeviceChromeOS::ConnectToService(
427 const BluetoothUUID
& uuid
,
428 const ConnectToServiceCallback
& callback
,
429 const ConnectToServiceErrorCallback
& error_callback
) {
430 VLOG(1) << object_path_
.value() << ": Connecting to service: "
431 << uuid
.canonical_value();
432 scoped_refptr
<BluetoothSocketChromeOS
> socket
=
433 BluetoothSocketChromeOS::CreateBluetoothSocket(
434 ui_task_runner_
, socket_thread_
);
435 socket
->Connect(this, uuid
, BluetoothSocketChromeOS::SECURITY_LEVEL_MEDIUM
,
436 base::Bind(callback
, socket
), error_callback
);
439 void BluetoothDeviceChromeOS::ConnectToServiceInsecurely(
440 const BluetoothUUID
& uuid
,
441 const ConnectToServiceCallback
& callback
,
442 const ConnectToServiceErrorCallback
& error_callback
) {
443 VLOG(1) << object_path_
.value() << ": Connecting insecurely to service: "
444 << uuid
.canonical_value();
445 scoped_refptr
<BluetoothSocketChromeOS
> socket
=
446 BluetoothSocketChromeOS::CreateBluetoothSocket(
447 ui_task_runner_
, socket_thread_
);
448 socket
->Connect(this, uuid
, BluetoothSocketChromeOS::SECURITY_LEVEL_LOW
,
449 base::Bind(callback
, socket
), error_callback
);
452 void BluetoothDeviceChromeOS::CreateGattConnection(
453 const GattConnectionCallback
& callback
,
454 const ConnectErrorCallback
& error_callback
) {
455 // TODO(armansito): Until there is a way to create a reference counted GATT
456 // connection in bluetoothd, simply do a regular connect.
458 base::Bind(&BluetoothDeviceChromeOS::OnCreateGattConnection
,
459 weak_ptr_factory_
.GetWeakPtr(),
464 void BluetoothDeviceChromeOS::StartConnectionMonitor(
465 const base::Closure
& callback
,
466 const ErrorCallback
& error_callback
) {
467 DBusThreadManager::Get()->GetBluetoothDeviceClient()->StartConnectionMonitor(
469 base::Bind(&BluetoothDeviceChromeOS::OnStartConnectionMonitor
,
470 weak_ptr_factory_
.GetWeakPtr(),
472 base::Bind(&BluetoothDeviceChromeOS::OnStartConnectionMonitorError
,
473 weak_ptr_factory_
.GetWeakPtr(),
477 BluetoothPairingChromeOS
* BluetoothDeviceChromeOS::BeginPairing(
478 BluetoothDevice::PairingDelegate
* pairing_delegate
) {
479 pairing_
.reset(new BluetoothPairingChromeOS(this, pairing_delegate
));
480 return pairing_
.get();
483 void BluetoothDeviceChromeOS::EndPairing() {
487 BluetoothPairingChromeOS
* BluetoothDeviceChromeOS::GetPairing() const {
488 return pairing_
.get();
491 void BluetoothDeviceChromeOS::GattServiceAdded(
492 const dbus::ObjectPath
& object_path
) {
493 if (GetGattService(object_path
.value())) {
494 VLOG(1) << "Remote GATT service already exists: " << object_path
.value();
498 BluetoothGattServiceClient::Properties
* properties
=
499 DBusThreadManager::Get()->GetBluetoothGattServiceClient()->
500 GetProperties(object_path
);
502 if (properties
->device
.value() != object_path_
) {
503 VLOG(2) << "Remote GATT service does not belong to this device.";
507 VLOG(1) << "Adding new remote GATT service for device: " << GetAddress();
509 BluetoothRemoteGattServiceChromeOS
* service
=
510 new BluetoothRemoteGattServiceChromeOS(adapter_
, this, object_path
);
512 gatt_services_
[service
->GetIdentifier()] = service
;
513 DCHECK(service
->object_path() == object_path
);
514 DCHECK(service
->GetUUID().IsValid());
517 adapter_
->NotifyGattServiceAdded(service
);
520 void BluetoothDeviceChromeOS::GattServiceRemoved(
521 const dbus::ObjectPath
& object_path
) {
522 GattServiceMap::iterator iter
= gatt_services_
.find(object_path
.value());
523 if (iter
== gatt_services_
.end()) {
524 VLOG(3) << "Unknown GATT service removed: " << object_path
.value();
528 VLOG(1) << "Removing remote GATT service from device: " << GetAddress();
530 BluetoothRemoteGattServiceChromeOS
* service
=
531 static_cast<BluetoothRemoteGattServiceChromeOS
*>(iter
->second
);
532 DCHECK(service
->object_path() == object_path
);
533 gatt_services_
.erase(iter
);
536 adapter_
->NotifyGattServiceRemoved(service
);
541 void BluetoothDeviceChromeOS::ConnectInternal(
543 const base::Closure
& callback
,
544 const ConnectErrorCallback
& error_callback
) {
545 VLOG(1) << object_path_
.value() << ": Connecting";
546 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
549 base::Bind(&BluetoothDeviceChromeOS::OnConnect
,
550 weak_ptr_factory_
.GetWeakPtr(),
553 base::Bind(&BluetoothDeviceChromeOS::OnConnectError
,
554 weak_ptr_factory_
.GetWeakPtr(),
559 void BluetoothDeviceChromeOS::OnConnect(bool after_pairing
,
560 const base::Closure
& callback
) {
561 if (--num_connecting_calls_
== 0)
562 adapter_
->NotifyDeviceChanged(this);
564 DCHECK(num_connecting_calls_
>= 0);
565 VLOG(1) << object_path_
.value() << ": Connected, " << num_connecting_calls_
566 << " still in progress";
571 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult",
572 UMA_PAIRING_RESULT_SUCCESS
,
573 UMA_PAIRING_RESULT_COUNT
);
578 void BluetoothDeviceChromeOS::OnCreateGattConnection(
579 const GattConnectionCallback
& callback
) {
580 scoped_ptr
<device::BluetoothGattConnection
> conn(
581 new BluetoothGattConnectionChromeOS(
582 adapter_
, GetAddress(), object_path_
));
583 callback
.Run(conn
.Pass());
586 void BluetoothDeviceChromeOS::OnConnectError(
588 const ConnectErrorCallback
& error_callback
,
589 const std::string
& error_name
,
590 const std::string
& error_message
) {
591 if (--num_connecting_calls_
== 0)
592 adapter_
->NotifyDeviceChanged(this);
594 DCHECK(num_connecting_calls_
>= 0);
595 LOG(WARNING
) << object_path_
.value() << ": Failed to connect device: "
596 << error_name
<< ": " << error_message
;
597 VLOG(1) << object_path_
.value() << ": " << num_connecting_calls_
598 << " still in progress";
600 // Determine the error code from error_name.
601 ConnectErrorCode error_code
= ERROR_UNKNOWN
;
602 if (error_name
== bluetooth_device::kErrorFailed
) {
603 error_code
= ERROR_FAILED
;
604 } else if (error_name
== bluetooth_device::kErrorInProgress
) {
605 error_code
= ERROR_INPROGRESS
;
606 } else if (error_name
== bluetooth_device::kErrorNotSupported
) {
607 error_code
= ERROR_UNSUPPORTED_DEVICE
;
611 RecordPairingResult(error_code
);
612 error_callback
.Run(error_code
);
615 void BluetoothDeviceChromeOS::OnPair(
616 const base::Closure
& callback
,
617 const ConnectErrorCallback
& error_callback
) {
618 VLOG(1) << object_path_
.value() << ": Paired";
622 ConnectInternal(true, callback
, error_callback
);
625 void BluetoothDeviceChromeOS::OnPairError(
626 const ConnectErrorCallback
& error_callback
,
627 const std::string
& error_name
,
628 const std::string
& error_message
) {
629 if (--num_connecting_calls_
== 0)
630 adapter_
->NotifyDeviceChanged(this);
632 DCHECK(num_connecting_calls_
>= 0);
633 LOG(WARNING
) << object_path_
.value() << ": Failed to pair device: "
634 << error_name
<< ": " << error_message
;
635 VLOG(1) << object_path_
.value() << ": " << num_connecting_calls_
636 << " still in progress";
640 // Determine the error code from error_name.
641 ConnectErrorCode error_code
= ERROR_UNKNOWN
;
642 if (error_name
== bluetooth_device::kErrorConnectionAttemptFailed
) {
643 error_code
= ERROR_FAILED
;
644 } else if (error_name
== bluetooth_device::kErrorFailed
) {
645 error_code
= ERROR_FAILED
;
646 } else if (error_name
== bluetooth_device::kErrorAuthenticationFailed
) {
647 error_code
= ERROR_AUTH_FAILED
;
648 } else if (error_name
== bluetooth_device::kErrorAuthenticationCanceled
) {
649 error_code
= ERROR_AUTH_CANCELED
;
650 } else if (error_name
== bluetooth_device::kErrorAuthenticationRejected
) {
651 error_code
= ERROR_AUTH_REJECTED
;
652 } else if (error_name
== bluetooth_device::kErrorAuthenticationTimeout
) {
653 error_code
= ERROR_AUTH_TIMEOUT
;
656 RecordPairingResult(error_code
);
657 error_callback
.Run(error_code
);
660 void BluetoothDeviceChromeOS::OnCancelPairingError(
661 const std::string
& error_name
,
662 const std::string
& error_message
) {
663 LOG(WARNING
) << object_path_
.value() << ": Failed to cancel pairing: "
664 << error_name
<< ": " << error_message
;
667 void BluetoothDeviceChromeOS::SetTrusted() {
668 // Unconditionally send the property change, rather than checking the value
669 // first; there's no harm in doing this and it solves any race conditions
670 // with the property becoming true or false and this call happening before
671 // we get the D-Bus signal about the earlier change.
672 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
673 GetProperties(object_path_
)->trusted
.Set(
675 base::Bind(&BluetoothDeviceChromeOS::OnSetTrusted
,
676 weak_ptr_factory_
.GetWeakPtr()));
679 void BluetoothDeviceChromeOS::OnSetTrusted(bool success
) {
680 LOG_IF(WARNING
, !success
) << object_path_
.value()
681 << ": Failed to set device as trusted";
684 void BluetoothDeviceChromeOS::OnStartConnectionMonitor(
685 const base::Closure
& callback
) {
686 connection_monitor_started_
= true;
690 void BluetoothDeviceChromeOS::OnStartConnectionMonitorError(
691 const ErrorCallback
& error_callback
,
692 const std::string
& error_name
,
693 const std::string
& error_message
) {
694 LOG(WARNING
) << object_path_
.value()
695 << ": Failed to start connection monitor: " << error_name
<< ": "
697 error_callback
.Run();
700 void BluetoothDeviceChromeOS::OnDisconnect(const base::Closure
& callback
) {
701 VLOG(1) << object_path_
.value() << ": Disconnected";
705 void BluetoothDeviceChromeOS::OnDisconnectError(
706 const ErrorCallback
& error_callback
,
707 const std::string
& error_name
,
708 const std::string
& error_message
) {
709 LOG(WARNING
) << object_path_
.value() << ": Failed to disconnect device: "
710 << error_name
<< ": " << error_message
;
711 error_callback
.Run();
714 void BluetoothDeviceChromeOS::OnForgetError(
715 const ErrorCallback
& error_callback
,
716 const std::string
& error_name
,
717 const std::string
& error_message
) {
718 LOG(WARNING
) << object_path_
.value() << ": Failed to remove device: "
719 << error_name
<< ": " << error_message
;
720 error_callback
.Run();
723 } // namespace chromeos