1 // Copyright (c) 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 "chromeos/dbus/fake_bluetooth_device_client.h"
10 #include <sys/socket.h>
18 #include "base/bind.h"
19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/message_loop/message_loop.h"
22 #include "base/rand_util.h"
23 #include "base/stl_util.h"
24 #include "base/threading/worker_pool.h"
25 #include "base/time/time.h"
26 #include "chromeos/dbus/dbus_thread_manager.h"
27 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
28 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
29 #include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
30 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
31 #include "chromeos/dbus/fake_bluetooth_input_client.h"
32 #include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
33 #include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
34 #include "dbus/file_descriptor.h"
35 #include "dbus/object_path.h"
36 #include "third_party/cros_system_api/dbus/service_constants.h"
40 // Default interval between simulated events.
41 const int kSimulationIntervalMs
= 750;
43 // Minimum and maximum bounds for randomly generated RSSI values.
44 const int kMinRSSI
= -90;
45 const int kMaxRSSI
= -30;
48 void SimulatedProfileSocket(int fd
) {
49 // Simulate a server-side socket of a profile; read data from the socket,
50 // write it back, and then close.
55 len
= read(fd
, buf
, sizeof buf
);
62 len
= write(fd
, buf
, count
);
71 void SimpleErrorCallback(const std::string
& error_name
,
72 const std::string
& error_message
) {
73 VLOG(1) << "Bluetooth Error: " << error_name
<< ": " << error_message
;
80 const char FakeBluetoothDeviceClient::kPairedDevicePath
[] =
82 const char FakeBluetoothDeviceClient::kPairedDeviceAddress
[] =
84 const char FakeBluetoothDeviceClient::kPairedDeviceName
[] =
86 const uint32
FakeBluetoothDeviceClient::kPairedDeviceClass
= 0x000104;
88 const char FakeBluetoothDeviceClient::kLegacyAutopairPath
[] =
90 const char FakeBluetoothDeviceClient::kLegacyAutopairAddress
[] =
92 const char FakeBluetoothDeviceClient::kLegacyAutopairName
[] =
93 "Bluetooth 2.0 Mouse";
94 const uint32
FakeBluetoothDeviceClient::kLegacyAutopairClass
= 0x002580;
96 const char FakeBluetoothDeviceClient::kDisplayPinCodePath
[] =
98 const char FakeBluetoothDeviceClient::kDisplayPinCodeAddress
[] =
100 const char FakeBluetoothDeviceClient::kDisplayPinCodeName
[] =
101 "Bluetooth 2.0 Keyboard";
102 const uint32
FakeBluetoothDeviceClient::kDisplayPinCodeClass
= 0x002540;
104 const char FakeBluetoothDeviceClient::kVanishingDevicePath
[] =
106 const char FakeBluetoothDeviceClient::kVanishingDeviceAddress
[] =
108 const char FakeBluetoothDeviceClient::kVanishingDeviceName
[] =
110 const uint32
FakeBluetoothDeviceClient::kVanishingDeviceClass
= 0x000104;
112 const char FakeBluetoothDeviceClient::kConnectUnpairablePath
[] =
114 const char FakeBluetoothDeviceClient::kConnectUnpairableAddress
[] =
116 const char FakeBluetoothDeviceClient::kConnectUnpairableName
[] =
118 const uint32
FakeBluetoothDeviceClient::kConnectUnpairableClass
= 0x002580;
120 const char FakeBluetoothDeviceClient::kDisplayPasskeyPath
[] =
122 const char FakeBluetoothDeviceClient::kDisplayPasskeyAddress
[] =
124 const char FakeBluetoothDeviceClient::kDisplayPasskeyName
[] =
125 "Bluetooth 2.1+ Keyboard";
126 const uint32
FakeBluetoothDeviceClient::kDisplayPasskeyClass
= 0x002540;
128 const char FakeBluetoothDeviceClient::kRequestPinCodePath
[] =
130 const char FakeBluetoothDeviceClient::kRequestPinCodeAddress
[] =
132 const char FakeBluetoothDeviceClient::kRequestPinCodeName
[] =
134 const uint32
FakeBluetoothDeviceClient::kRequestPinCodeClass
= 0x240408;
136 const char FakeBluetoothDeviceClient::kConfirmPasskeyPath
[] =
138 const char FakeBluetoothDeviceClient::kConfirmPasskeyAddress
[] =
140 const char FakeBluetoothDeviceClient::kConfirmPasskeyName
[] =
142 const uint32
FakeBluetoothDeviceClient::kConfirmPasskeyClass
= 0x7a020c;
144 const char FakeBluetoothDeviceClient::kRequestPasskeyPath
[] =
146 const char FakeBluetoothDeviceClient::kRequestPasskeyAddress
[] =
148 const char FakeBluetoothDeviceClient::kRequestPasskeyName
[] =
150 const uint32
FakeBluetoothDeviceClient::kRequestPasskeyClass
= 0x7a020c;
152 const char FakeBluetoothDeviceClient::kUnconnectableDevicePath
[] =
154 const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress
[] =
156 const char FakeBluetoothDeviceClient::kUnconnectableDeviceName
[] =
157 "Unconnectable Device";
158 const uint32
FakeBluetoothDeviceClient::kUnconnectableDeviceClass
= 0x7a020c;
160 const char FakeBluetoothDeviceClient::kUnpairableDevicePath
[] =
162 const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress
[] =
164 const char FakeBluetoothDeviceClient::kUnpairableDeviceName
[] =
166 const uint32
FakeBluetoothDeviceClient::kUnpairableDeviceClass
= 0x002540;
168 const char FakeBluetoothDeviceClient::kJustWorksPath
[] =
170 const char FakeBluetoothDeviceClient::kJustWorksAddress
[] =
172 const char FakeBluetoothDeviceClient::kJustWorksName
[] =
174 const uint32
FakeBluetoothDeviceClient::kJustWorksClass
= 0x240428;
176 const char FakeBluetoothDeviceClient::kLowEnergyPath
[] =
178 const char FakeBluetoothDeviceClient::kLowEnergyAddress
[] =
180 const char FakeBluetoothDeviceClient::kLowEnergyName
[] =
181 "Bluetooth 4.0 Heart Rate Monitor";
182 const uint32
FakeBluetoothDeviceClient::kLowEnergyClass
=
183 0x000918; // Major class "Health", Minor class "Heart/Pulse Rate Monitor."
185 FakeBluetoothDeviceClient::Properties::Properties(
186 const PropertyChangedCallback
& callback
)
187 : BluetoothDeviceClient::Properties(
189 bluetooth_device::kBluetoothDeviceInterface
,
193 FakeBluetoothDeviceClient::Properties::~Properties() {
196 void FakeBluetoothDeviceClient::Properties::Get(
197 dbus::PropertyBase
* property
,
198 dbus::PropertySet::GetCallback callback
) {
199 VLOG(1) << "Get " << property
->name();
203 void FakeBluetoothDeviceClient::Properties::GetAll() {
207 void FakeBluetoothDeviceClient::Properties::Set(
208 dbus::PropertyBase
*property
,
209 dbus::PropertySet::SetCallback callback
) {
210 VLOG(1) << "Set " << property
->name();
211 if (property
->name() == trusted
.name()) {
213 property
->ReplaceValueWithSetValue();
219 FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
220 : simulation_interval_ms_(kSimulationIntervalMs
),
221 discovery_simulation_step_(0),
222 incoming_pairing_simulation_step_(0),
223 pairing_cancelled_(false),
224 connection_monitor_started_(false) {
225 Properties
* properties
= new Properties(base::Bind(
226 &FakeBluetoothDeviceClient::OnPropertyChanged
,
227 base::Unretained(this),
228 dbus::ObjectPath(kPairedDevicePath
)));
229 properties
->address
.ReplaceValue(kPairedDeviceAddress
);
230 properties
->bluetooth_class
.ReplaceValue(kPairedDeviceClass
);
231 properties
->name
.ReplaceValue("Fake Device (Name)");
232 properties
->alias
.ReplaceValue(kPairedDeviceName
);
233 properties
->paired
.ReplaceValue(true);
234 properties
->trusted
.ReplaceValue(true);
235 properties
->adapter
.ReplaceValue(
236 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
));
238 std::vector
<std::string
> uuids
;
239 uuids
.push_back("00001800-0000-1000-8000-00805f9b34fb");
240 uuids
.push_back("00001801-0000-1000-8000-00805f9b34fb");
241 properties
->uuids
.ReplaceValue(uuids
);
243 properties
->modalias
.ReplaceValue("usb:v05ACp030Dd0306");
245 properties_map_
[dbus::ObjectPath(kPairedDevicePath
)] = properties
;
246 device_list_
.push_back(dbus::ObjectPath(kPairedDevicePath
));
249 FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() {
250 // Clean up Properties structures
251 STLDeleteValues(&properties_map_
);
254 void FakeBluetoothDeviceClient::Init(dbus::Bus
* bus
) {
257 void FakeBluetoothDeviceClient::AddObserver(Observer
* observer
) {
258 observers_
.AddObserver(observer
);
261 void FakeBluetoothDeviceClient::RemoveObserver(Observer
* observer
) {
262 observers_
.RemoveObserver(observer
);
265 std::vector
<dbus::ObjectPath
> FakeBluetoothDeviceClient::GetDevicesForAdapter(
266 const dbus::ObjectPath
& adapter_path
) {
268 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
))
271 return std::vector
<dbus::ObjectPath
>();
274 FakeBluetoothDeviceClient::Properties
*
275 FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath
& object_path
) {
276 PropertiesMap::iterator iter
= properties_map_
.find(object_path
);
277 if (iter
!= properties_map_
.end())
282 void FakeBluetoothDeviceClient::Connect(
283 const dbus::ObjectPath
& object_path
,
284 const base::Closure
& callback
,
285 const ErrorCallback
& error_callback
) {
286 VLOG(1) << "Connect: " << object_path
.value();
287 Properties
* properties
= GetProperties(object_path
);
289 if (properties
->connected
.value() == true) {
290 // Already connected.
295 if (properties
->paired
.value() != true &&
296 object_path
!= dbus::ObjectPath(kConnectUnpairablePath
)) {
298 error_callback
.Run(bluetooth_device::kErrorFailed
, "Not paired");
300 } else if (properties
->paired
.value() == true &&
301 object_path
== dbus::ObjectPath(kUnconnectableDevicePath
)) {
302 // Must not be paired
303 error_callback
.Run(bluetooth_device::kErrorFailed
,
304 "Connection fails while paired");
308 // The device can be connected.
309 properties
->connected
.ReplaceValue(true);
312 // Expose GATT services if connected to LE device.
313 if (object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
314 FakeBluetoothGattServiceClient
* gatt_service_client
=
315 static_cast<FakeBluetoothGattServiceClient
*>(
316 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
317 gatt_service_client
->ExposeHeartRateService(
318 dbus::ObjectPath(kLowEnergyPath
));
321 AddInputDeviceIfNeeded(object_path
, properties
);
324 void FakeBluetoothDeviceClient::Disconnect(
325 const dbus::ObjectPath
& object_path
,
326 const base::Closure
& callback
,
327 const ErrorCallback
& error_callback
) {
328 VLOG(1) << "Disconnect: " << object_path
.value();
329 Properties
* properties
= GetProperties(object_path
);
331 if (!properties
->connected
.value()) {
332 error_callback
.Run("org.bluez.Error.NotConnected", "Not Connected");
336 // Hide the Heart Rate Service if disconnected from LE device.
337 if (object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
338 FakeBluetoothGattServiceClient
* gatt_service_client
=
339 static_cast<FakeBluetoothGattServiceClient
*>(
340 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
341 gatt_service_client
->HideHeartRateService();
345 properties
->connected
.ReplaceValue(false);
348 void FakeBluetoothDeviceClient::ConnectProfile(
349 const dbus::ObjectPath
& object_path
,
350 const std::string
& uuid
,
351 const base::Closure
& callback
,
352 const ErrorCallback
& error_callback
) {
353 VLOG(1) << "ConnectProfile: " << object_path
.value() << " " << uuid
;
355 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
356 static_cast<FakeBluetoothProfileManagerClient
*>(
357 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
358 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
359 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(uuid
);
360 if (profile_service_provider
== NULL
) {
361 error_callback
.Run(kNoResponseError
, "Missing profile");
365 // Make a socket pair of a compatible type with the type used by Bluetooth;
366 // spin up a thread to simulate the server side and wrap the client side in
367 // a D-Bus file descriptor object.
368 int socket_type
= SOCK_STREAM
;
369 if (uuid
== FakeBluetoothProfileManagerClient::kL2capUuid
)
370 socket_type
= SOCK_SEQPACKET
;
373 if (socketpair(AF_UNIX
, socket_type
, 0, fds
) < 0) {
374 error_callback
.Run(kNoResponseError
, "socketpair call failed");
379 args
= fcntl(fds
[1], F_GETFL
, NULL
);
381 error_callback
.Run(kNoResponseError
, "failed to get socket flags");
386 if (fcntl(fds
[1], F_SETFL
, args
) < 0) {
387 error_callback
.Run(kNoResponseError
, "failed to set socket non-blocking");
391 base::WorkerPool::GetTaskRunner(false)->PostTask(
393 base::Bind(&SimulatedProfileSocket
,
396 scoped_ptr
<dbus::FileDescriptor
> fd(new dbus::FileDescriptor(fds
[1]));
398 // Post the new connection to the service provider.
399 BluetoothProfileServiceProvider::Delegate::Options options
;
401 profile_service_provider
->NewConnection(
405 base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback
,
406 base::Unretained(this),
412 void FakeBluetoothDeviceClient::DisconnectProfile(
413 const dbus::ObjectPath
& object_path
,
414 const std::string
& uuid
,
415 const base::Closure
& callback
,
416 const ErrorCallback
& error_callback
) {
417 VLOG(1) << "DisconnectProfile: " << object_path
.value() << " " << uuid
;
419 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
420 static_cast<FakeBluetoothProfileManagerClient
*>(
421 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
422 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
423 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(uuid
);
424 if (profile_service_provider
== NULL
) {
425 error_callback
.Run(kNoResponseError
, "Missing profile");
429 profile_service_provider
->RequestDisconnection(
431 base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback
,
432 base::Unretained(this),
438 void FakeBluetoothDeviceClient::Pair(
439 const dbus::ObjectPath
& object_path
,
440 const base::Closure
& callback
,
441 const ErrorCallback
& error_callback
) {
442 VLOG(1) << "Pair: " << object_path
.value();
443 Properties
* properties
= GetProperties(object_path
);
445 if (properties
->paired
.value() == true) {
451 SimulatePairing(object_path
, false, callback
, error_callback
);
454 void FakeBluetoothDeviceClient::CancelPairing(
455 const dbus::ObjectPath
& object_path
,
456 const base::Closure
& callback
,
457 const ErrorCallback
& error_callback
) {
458 VLOG(1) << "CancelPairing: " << object_path
.value();
459 pairing_cancelled_
= true;
463 void FakeBluetoothDeviceClient::StartConnectionMonitor(
464 const dbus::ObjectPath
& object_path
,
465 const base::Closure
& callback
,
466 const ErrorCallback
& error_callback
) {
467 VLOG(1) << "StartConnectionMonitor: " << object_path
.value();
468 connection_monitor_started_
= true;
472 void FakeBluetoothDeviceClient::StopConnectionMonitor(
473 const dbus::ObjectPath
& object_path
,
474 const base::Closure
& callback
,
475 const ErrorCallback
& error_callback
) {
476 connection_monitor_started_
= false;
480 void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
481 const dbus::ObjectPath
& adapter_path
) {
482 VLOG(1) << "starting discovery simulation";
484 discovery_simulation_step_
= 1;
486 base::MessageLoop::current()->PostDelayedTask(
488 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer
,
489 base::Unretained(this)),
490 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
493 void FakeBluetoothDeviceClient::EndDiscoverySimulation(
494 const dbus::ObjectPath
& adapter_path
) {
495 VLOG(1) << "stopping discovery simulation";
496 discovery_simulation_step_
= 0;
499 void FakeBluetoothDeviceClient::BeginIncomingPairingSimulation(
500 const dbus::ObjectPath
& adapter_path
) {
501 VLOG(1) << "starting incoming pairing simulation";
503 incoming_pairing_simulation_step_
= 1;
505 base::MessageLoop::current()->PostDelayedTask(
507 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer
,
508 base::Unretained(this)),
509 base::TimeDelta::FromMilliseconds(30 * simulation_interval_ms_
));
512 void FakeBluetoothDeviceClient::EndIncomingPairingSimulation(
513 const dbus::ObjectPath
& adapter_path
) {
514 VLOG(1) << "stopping incoming pairing simulation";
515 incoming_pairing_simulation_step_
= 0;
518 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms
) {
519 simulation_interval_ms_
= interval_ms
;
522 void FakeBluetoothDeviceClient::CreateDevice(
523 const dbus::ObjectPath
& adapter_path
,
524 const dbus::ObjectPath
& device_path
) {
525 if (std::find(device_list_
.begin(),
526 device_list_
.end(), device_path
) != device_list_
.end())
529 Properties
* properties
= new Properties(base::Bind(
530 &FakeBluetoothDeviceClient::OnPropertyChanged
,
531 base::Unretained(this),
533 properties
->adapter
.ReplaceValue(adapter_path
);
535 if (device_path
== dbus::ObjectPath(kLegacyAutopairPath
)) {
536 properties
->address
.ReplaceValue(kLegacyAutopairAddress
);
537 properties
->bluetooth_class
.ReplaceValue(kLegacyAutopairClass
);
538 properties
->name
.ReplaceValue("LegacyAutopair");
539 properties
->alias
.ReplaceValue(kLegacyAutopairName
);
541 std::vector
<std::string
> uuids
;
542 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
543 properties
->uuids
.ReplaceValue(uuids
);
545 } else if (device_path
== dbus::ObjectPath(kDisplayPinCodePath
)) {
546 properties
->address
.ReplaceValue(kDisplayPinCodeAddress
);
547 properties
->bluetooth_class
.ReplaceValue(kDisplayPinCodeClass
);
548 properties
->name
.ReplaceValue("DisplayPinCode");
549 properties
->alias
.ReplaceValue(kDisplayPinCodeName
);
551 std::vector
<std::string
> uuids
;
552 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
553 properties
->uuids
.ReplaceValue(uuids
);
555 } else if (device_path
== dbus::ObjectPath(kVanishingDevicePath
)) {
556 properties
->address
.ReplaceValue(kVanishingDeviceAddress
);
557 properties
->bluetooth_class
.ReplaceValue(kVanishingDeviceClass
);
558 properties
->name
.ReplaceValue("VanishingDevice");
559 properties
->alias
.ReplaceValue(kVanishingDeviceName
);
561 } else if (device_path
== dbus::ObjectPath(kConnectUnpairablePath
)) {
562 properties
->address
.ReplaceValue(kConnectUnpairableAddress
);
563 properties
->bluetooth_class
.ReplaceValue(kConnectUnpairableClass
);
564 properties
->name
.ReplaceValue("ConnectUnpairable");
565 properties
->alias
.ReplaceValue(kConnectUnpairableName
);
567 std::vector
<std::string
> uuids
;
568 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
569 properties
->uuids
.ReplaceValue(uuids
);
571 } else if (device_path
== dbus::ObjectPath(kDisplayPasskeyPath
)) {
572 properties
->address
.ReplaceValue(kDisplayPasskeyAddress
);
573 properties
->bluetooth_class
.ReplaceValue(kDisplayPasskeyClass
);
574 properties
->name
.ReplaceValue("DisplayPasskey");
575 properties
->alias
.ReplaceValue(kDisplayPasskeyName
);
577 std::vector
<std::string
> uuids
;
578 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
579 properties
->uuids
.ReplaceValue(uuids
);
581 } else if (device_path
== dbus::ObjectPath(kRequestPinCodePath
)) {
582 properties
->address
.ReplaceValue(kRequestPinCodeAddress
);
583 properties
->bluetooth_class
.ReplaceValue(kRequestPinCodeClass
);
584 properties
->name
.ReplaceValue("RequestPinCode");
585 properties
->alias
.ReplaceValue(kRequestPinCodeName
);
587 } else if (device_path
== dbus::ObjectPath(kConfirmPasskeyPath
)) {
588 properties
->address
.ReplaceValue(kConfirmPasskeyAddress
);
589 properties
->bluetooth_class
.ReplaceValue(kConfirmPasskeyClass
);
590 properties
->name
.ReplaceValue("ConfirmPasskey");
591 properties
->alias
.ReplaceValue(kConfirmPasskeyName
);
593 } else if (device_path
== dbus::ObjectPath(kRequestPasskeyPath
)) {
594 properties
->address
.ReplaceValue(kRequestPasskeyAddress
);
595 properties
->bluetooth_class
.ReplaceValue(kRequestPasskeyClass
);
596 properties
->name
.ReplaceValue("RequestPasskey");
597 properties
->alias
.ReplaceValue(kRequestPasskeyName
);
599 } else if (device_path
== dbus::ObjectPath(kUnconnectableDevicePath
)) {
600 properties
->address
.ReplaceValue(kUnconnectableDeviceAddress
);
601 properties
->bluetooth_class
.ReplaceValue(kUnconnectableDeviceClass
);
602 properties
->name
.ReplaceValue("UnconnectableDevice");
603 properties
->alias
.ReplaceValue(kUnconnectableDeviceName
);
605 } else if (device_path
== dbus::ObjectPath(kUnpairableDevicePath
)) {
606 properties
->address
.ReplaceValue(kUnpairableDeviceAddress
);
607 properties
->bluetooth_class
.ReplaceValue(kUnpairableDeviceClass
);
608 properties
->name
.ReplaceValue("Fake Unpairable Device");
609 properties
->alias
.ReplaceValue(kUnpairableDeviceName
);
611 } else if (device_path
== dbus::ObjectPath(kJustWorksPath
)) {
612 properties
->address
.ReplaceValue(kJustWorksAddress
);
613 properties
->bluetooth_class
.ReplaceValue(kJustWorksClass
);
614 properties
->name
.ReplaceValue("JustWorks");
615 properties
->alias
.ReplaceValue(kJustWorksName
);
617 } else if (device_path
== dbus::ObjectPath(kLowEnergyPath
)) {
618 properties
->address
.ReplaceValue(kLowEnergyAddress
);
619 properties
->bluetooth_class
.ReplaceValue(kLowEnergyClass
);
620 properties
->name
.ReplaceValue("Heart Rate Monitor");
621 properties
->alias
.ReplaceValue(kLowEnergyName
);
623 std::vector
<std::string
> uuids
;
624 uuids
.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
);
625 properties
->uuids
.ReplaceValue(uuids
);
632 properties_map_
[device_path
] = properties
;
633 device_list_
.push_back(device_path
);
634 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
635 DeviceAdded(device_path
));
638 void FakeBluetoothDeviceClient::RemoveDevice(
639 const dbus::ObjectPath
& adapter_path
,
640 const dbus::ObjectPath
& device_path
) {
641 std::vector
<dbus::ObjectPath
>::iterator listiter
=
642 std::find(device_list_
.begin(), device_list_
.end(), device_path
);
643 if (listiter
== device_list_
.end())
646 PropertiesMap::iterator iter
= properties_map_
.find(device_path
);
647 Properties
* properties
= iter
->second
;
649 VLOG(1) << "removing device: " << properties
->alias
.value();
650 device_list_
.erase(listiter
);
652 // Remove the Input interface if it exists. This should be called before the
653 // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
654 // BluetoothDeviceChromeOS object, including the device_path referenced here.
655 FakeBluetoothInputClient
* fake_bluetooth_input_client
=
656 static_cast<FakeBluetoothInputClient
*>(
657 DBusThreadManager::Get()->GetBluetoothInputClient());
658 fake_bluetooth_input_client
->RemoveInputDevice(device_path
);
660 if (device_path
== dbus::ObjectPath(kLowEnergyPath
)) {
661 FakeBluetoothGattServiceClient
* gatt_service_client
=
662 static_cast<FakeBluetoothGattServiceClient
*>(
663 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
664 gatt_service_client
->HideHeartRateService();
667 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
668 DeviceRemoved(device_path
));
671 properties_map_
.erase(iter
);
674 void FakeBluetoothDeviceClient::OnPropertyChanged(
675 const dbus::ObjectPath
& object_path
,
676 const std::string
& property_name
) {
677 VLOG(2) << "Fake Bluetooth device property changed: " << object_path
.value()
678 << ": " << property_name
;
679 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
680 DevicePropertyChanged(object_path
, property_name
));
683 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
684 if (!discovery_simulation_step_
)
687 // Timer fires every .75s, the numbers below are arbitrary to give a feel
688 // for a discovery process.
689 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_
;
690 if (discovery_simulation_step_
== 2) {
691 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
692 dbus::ObjectPath(kLegacyAutopairPath
));
693 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
694 dbus::ObjectPath(kLowEnergyPath
));
696 } else if (discovery_simulation_step_
== 4) {
697 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
698 base::RandInt(kMinRSSI
, kMaxRSSI
));
699 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
700 dbus::ObjectPath(kDisplayPinCodePath
));
701 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
702 dbus::ObjectPath(kVanishingDevicePath
));
704 } else if (discovery_simulation_step_
== 7) {
705 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
706 dbus::ObjectPath(kConnectUnpairablePath
));
707 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
708 base::RandInt(kMinRSSI
, kMaxRSSI
));
710 } else if (discovery_simulation_step_
== 8) {
711 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
712 dbus::ObjectPath(kDisplayPasskeyPath
));
713 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
714 dbus::ObjectPath(kRequestPinCodePath
));
715 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
716 base::RandInt(kMinRSSI
, kMaxRSSI
));
718 } else if (discovery_simulation_step_
== 10) {
719 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
720 dbus::ObjectPath(kConfirmPasskeyPath
));
721 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
722 dbus::ObjectPath(kRequestPasskeyPath
));
723 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
724 dbus::ObjectPath(kUnconnectableDevicePath
));
725 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
726 dbus::ObjectPath(kUnpairableDevicePath
));
727 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
728 dbus::ObjectPath(kJustWorksPath
));
729 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
730 base::RandInt(kMinRSSI
, kMaxRSSI
));
732 } else if (discovery_simulation_step_
== 13) {
733 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
734 base::RandInt(kMinRSSI
, kMaxRSSI
));
735 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
736 dbus::ObjectPath(kVanishingDevicePath
));
738 } else if (discovery_simulation_step_
== 14) {
739 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
740 base::RandInt(kMinRSSI
, kMaxRSSI
));
745 ++discovery_simulation_step_
;
746 base::MessageLoop::current()->PostDelayedTask(
748 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer
,
749 base::Unretained(this)),
750 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
753 void FakeBluetoothDeviceClient::IncomingPairingSimulationTimer() {
754 if (!incoming_pairing_simulation_step_
)
757 VLOG(1) << "incoming pairing simulation, step "
758 << incoming_pairing_simulation_step_
;
759 switch (incoming_pairing_simulation_step_
) {
761 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
762 dbus::ObjectPath(kConfirmPasskeyPath
));
763 SimulatePairing(dbus::ObjectPath(kConfirmPasskeyPath
), true,
764 base::Bind(&base::DoNothing
),
765 base::Bind(&SimpleErrorCallback
));
768 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
769 dbus::ObjectPath(kJustWorksPath
));
770 SimulatePairing(dbus::ObjectPath(kJustWorksPath
), true,
771 base::Bind(&base::DoNothing
),
772 base::Bind(&SimpleErrorCallback
));
775 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
776 dbus::ObjectPath(kDisplayPinCodePath
));
777 SimulatePairing(dbus::ObjectPath(kDisplayPinCodePath
), true,
778 base::Bind(&base::DoNothing
),
779 base::Bind(&SimpleErrorCallback
));
782 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
783 dbus::ObjectPath(kDisplayPasskeyPath
));
784 SimulatePairing(dbus::ObjectPath(kDisplayPasskeyPath
), true,
785 base::Bind(&base::DoNothing
),
786 base::Bind(&SimpleErrorCallback
));
789 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
790 dbus::ObjectPath(kRequestPinCodePath
));
791 SimulatePairing(dbus::ObjectPath(kRequestPinCodePath
), true,
792 base::Bind(&base::DoNothing
),
793 base::Bind(&SimpleErrorCallback
));
796 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
797 dbus::ObjectPath(kRequestPasskeyPath
));
798 SimulatePairing(dbus::ObjectPath(kRequestPasskeyPath
), true,
799 base::Bind(&base::DoNothing
),
800 base::Bind(&SimpleErrorCallback
));
806 ++incoming_pairing_simulation_step_
;
807 base::MessageLoop::current()->PostDelayedTask(
809 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer
,
810 base::Unretained(this)),
811 base::TimeDelta::FromMilliseconds(45 * simulation_interval_ms_
));
814 void FakeBluetoothDeviceClient::SimulatePairing(
815 const dbus::ObjectPath
& object_path
,
816 bool incoming_request
,
817 const base::Closure
& callback
,
818 const ErrorCallback
& error_callback
) {
819 pairing_cancelled_
= false;
821 FakeBluetoothAgentManagerClient
* fake_bluetooth_agent_manager_client
=
822 static_cast<FakeBluetoothAgentManagerClient
*>(
823 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
824 FakeBluetoothAgentServiceProvider
* agent_service_provider
=
825 fake_bluetooth_agent_manager_client
->GetAgentServiceProvider();
826 CHECK(agent_service_provider
!= NULL
);
828 if (object_path
== dbus::ObjectPath(kLegacyAutopairPath
) ||
829 object_path
== dbus::ObjectPath(kConnectUnpairablePath
) ||
830 object_path
== dbus::ObjectPath(kUnconnectableDevicePath
) ||
831 object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
832 // No need to call anything on the pairing delegate, just wait 3 times
833 // the interval before acting as if the other end accepted it.
834 base::MessageLoop::current()->PostDelayedTask(
836 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
837 base::Unretained(this),
838 object_path
, callback
, error_callback
),
839 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
841 } else if (object_path
== dbus::ObjectPath(kDisplayPinCodePath
)) {
842 // Display a Pincode, and wait 7 times the interval before acting as
843 // if the other end accepted it.
844 agent_service_provider
->DisplayPinCode(object_path
, "123456");
846 base::MessageLoop::current()->PostDelayedTask(
848 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
849 base::Unretained(this),
850 object_path
, callback
, error_callback
),
851 base::TimeDelta::FromMilliseconds(7 * simulation_interval_ms_
));
853 } else if (object_path
== dbus::ObjectPath(kVanishingDevicePath
)) {
854 // The vanishing device simulates being too far away, and thus times out.
855 base::MessageLoop::current()->PostDelayedTask(
857 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing
,
858 base::Unretained(this),
859 object_path
, error_callback
),
860 base::TimeDelta::FromMilliseconds(4 * simulation_interval_ms_
));
862 } else if (object_path
== dbus::ObjectPath(kDisplayPasskeyPath
)) {
863 // Display a passkey, and each interval act as if another key was entered
865 agent_service_provider
->DisplayPasskey(object_path
, 123456, 0);
867 base::MessageLoop::current()->PostDelayedTask(
869 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress
,
870 base::Unretained(this),
871 1, object_path
, callback
, error_callback
),
872 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
874 } else if (object_path
== dbus::ObjectPath(kRequestPinCodePath
)) {
875 // Request a Pincode.
876 agent_service_provider
->RequestPinCode(
878 base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback
,
879 base::Unretained(this),
884 } else if (object_path
== dbus::ObjectPath(kConfirmPasskeyPath
)) {
885 // Request confirmation of a Passkey.
886 agent_service_provider
->RequestConfirmation(
888 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback
,
889 base::Unretained(this),
894 } else if (object_path
== dbus::ObjectPath(kRequestPasskeyPath
)) {
895 // Request a Passkey from the user.
896 agent_service_provider
->RequestPasskey(
898 base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback
,
899 base::Unretained(this),
904 } else if (object_path
== dbus::ObjectPath(kUnpairableDevicePath
)) {
905 // Fails the pairing with an org.bluez.Error.Failed error.
906 base::MessageLoop::current()->PostDelayedTask(
908 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing
,
909 base::Unretained(this),
910 object_path
, error_callback
),
911 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
913 } else if (object_path
== dbus::ObjectPath(kJustWorksPath
)) {
914 if (incoming_request
) {
915 agent_service_provider
->RequestAuthorization(
917 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback
,
918 base::Unretained(this),
924 // No need to call anything on the pairing delegate, just wait 3 times
925 // the interval before acting as if the other end accepted it.
926 base::MessageLoop::current()->PostDelayedTask(
928 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
929 base::Unretained(this),
930 object_path
, callback
, error_callback
),
931 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
936 error_callback
.Run(kNoResponseError
, "No pairing fake");
940 void FakeBluetoothDeviceClient::CompleteSimulatedPairing(
941 const dbus::ObjectPath
& object_path
,
942 const base::Closure
& callback
,
943 const ErrorCallback
& error_callback
) {
944 VLOG(1) << "CompleteSimulatedPairing: " << object_path
.value();
945 if (pairing_cancelled_
) {
946 pairing_cancelled_
= false;
948 error_callback
.Run(bluetooth_device::kErrorAuthenticationCanceled
,
951 Properties
* properties
= GetProperties(object_path
);
953 properties
->paired
.ReplaceValue(true);
956 AddInputDeviceIfNeeded(object_path
, properties
);
960 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing(
961 const dbus::ObjectPath
& object_path
,
962 const ErrorCallback
& error_callback
) {
963 VLOG(1) << "TimeoutSimulatedPairing: " << object_path
.value();
965 error_callback
.Run(bluetooth_device::kErrorAuthenticationTimeout
,
969 void FakeBluetoothDeviceClient::CancelSimulatedPairing(
970 const dbus::ObjectPath
& object_path
,
971 const ErrorCallback
& error_callback
) {
972 VLOG(1) << "CancelSimulatedPairing: " << object_path
.value();
974 error_callback
.Run(bluetooth_device::kErrorAuthenticationCanceled
,
978 void FakeBluetoothDeviceClient::RejectSimulatedPairing(
979 const dbus::ObjectPath
& object_path
,
980 const ErrorCallback
& error_callback
) {
981 VLOG(1) << "RejectSimulatedPairing: " << object_path
.value();
983 error_callback
.Run(bluetooth_device::kErrorAuthenticationRejected
,
987 void FakeBluetoothDeviceClient::FailSimulatedPairing(
988 const dbus::ObjectPath
& object_path
,
989 const ErrorCallback
& error_callback
) {
990 VLOG(1) << "FailSimulatedPairing: " << object_path
.value();
992 error_callback
.Run(bluetooth_device::kErrorFailed
, "Failed");
995 void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded(
996 const dbus::ObjectPath
& object_path
,
997 Properties
* properties
) {
998 // If the paired device is a HID device based on it's bluetooth class,
999 // simulate the Input interface.
1000 FakeBluetoothInputClient
* fake_bluetooth_input_client
=
1001 static_cast<FakeBluetoothInputClient
*>(
1002 DBusThreadManager::Get()->GetBluetoothInputClient());
1004 if ((properties
->bluetooth_class
.value() & 0x001f03) == 0x000500)
1005 fake_bluetooth_input_client
->AddInputDevice(object_path
);
1008 void FakeBluetoothDeviceClient::UpdateDeviceRSSI(
1009 const dbus::ObjectPath
& object_path
,
1011 PropertiesMap::iterator iter
= properties_map_
.find(object_path
);
1012 if (iter
== properties_map_
.end()) {
1013 VLOG(2) << "Fake device does not exist: " << object_path
.value();
1016 Properties
* properties
= iter
->second
;
1018 properties
->rssi
.ReplaceValue(rssi
);
1021 void FakeBluetoothDeviceClient::PinCodeCallback(
1022 const dbus::ObjectPath
& object_path
,
1023 const base::Closure
& callback
,
1024 const ErrorCallback
& error_callback
,
1025 BluetoothAgentServiceProvider::Delegate::Status status
,
1026 const std::string
& pincode
) {
1027 VLOG(1) << "PinCodeCallback: " << object_path
.value();
1029 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1030 base::MessageLoop::current()->PostDelayedTask(
1032 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1033 base::Unretained(this),
1034 object_path
, callback
, error_callback
),
1035 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
1037 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1038 base::MessageLoop::current()->PostDelayedTask(
1040 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1041 base::Unretained(this),
1042 object_path
, error_callback
),
1043 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1045 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1046 base::MessageLoop::current()->PostDelayedTask(
1048 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1049 base::Unretained(this),
1050 object_path
, error_callback
),
1051 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1056 void FakeBluetoothDeviceClient::PasskeyCallback(
1057 const dbus::ObjectPath
& object_path
,
1058 const base::Closure
& callback
,
1059 const ErrorCallback
& error_callback
,
1060 BluetoothAgentServiceProvider::Delegate::Status status
,
1062 VLOG(1) << "PasskeyCallback: " << object_path
.value();
1064 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1065 base::MessageLoop::current()->PostDelayedTask(
1067 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1068 base::Unretained(this),
1069 object_path
, callback
, error_callback
),
1070 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
1072 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1073 base::MessageLoop::current()->PostDelayedTask(
1075 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1076 base::Unretained(this),
1077 object_path
, error_callback
),
1078 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1080 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1081 base::MessageLoop::current()->PostDelayedTask(
1083 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1084 base::Unretained(this),
1085 object_path
, error_callback
),
1086 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1091 void FakeBluetoothDeviceClient::ConfirmationCallback(
1092 const dbus::ObjectPath
& object_path
,
1093 const base::Closure
& callback
,
1094 const ErrorCallback
& error_callback
,
1095 BluetoothAgentServiceProvider::Delegate::Status status
) {
1096 VLOG(1) << "ConfirmationCallback: " << object_path
.value();
1098 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1099 base::MessageLoop::current()->PostDelayedTask(
1101 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1102 base::Unretained(this),
1103 object_path
, callback
, error_callback
),
1104 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
1106 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1107 base::MessageLoop::current()->PostDelayedTask(
1109 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1110 base::Unretained(this),
1111 object_path
, error_callback
),
1112 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1114 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1115 base::MessageLoop::current()->PostDelayedTask(
1117 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1118 base::Unretained(this),
1119 object_path
, error_callback
),
1120 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1125 void FakeBluetoothDeviceClient::SimulateKeypress(
1127 const dbus::ObjectPath
& object_path
,
1128 const base::Closure
& callback
,
1129 const ErrorCallback
& error_callback
) {
1130 VLOG(1) << "SimulateKeypress " << entered
<< ": " << object_path
.value();
1132 FakeBluetoothAgentManagerClient
* fake_bluetooth_agent_manager_client
=
1133 static_cast<FakeBluetoothAgentManagerClient
*>(
1134 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
1135 FakeBluetoothAgentServiceProvider
* agent_service_provider
=
1136 fake_bluetooth_agent_manager_client
->GetAgentServiceProvider();
1138 // The agent service provider object could have been destroyed after the
1139 // pairing is canceled.
1140 if (!agent_service_provider
)
1143 agent_service_provider
->DisplayPasskey(object_path
, 123456, entered
);
1146 base::MessageLoop::current()->PostDelayedTask(
1148 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress
,
1149 base::Unretained(this),
1150 entered
+ 1, object_path
, callback
, error_callback
),
1151 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1154 base::MessageLoop::current()->PostDelayedTask(
1156 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1157 base::Unretained(this),
1158 object_path
, callback
, error_callback
),
1159 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1164 void FakeBluetoothDeviceClient::ConnectionCallback(
1165 const dbus::ObjectPath
& object_path
,
1166 const base::Closure
& callback
,
1167 const ErrorCallback
& error_callback
,
1168 BluetoothProfileServiceProvider::Delegate::Status status
) {
1169 VLOG(1) << "ConnectionCallback: " << object_path
.value();
1171 if (status
== BluetoothProfileServiceProvider::Delegate::SUCCESS
) {
1173 } else if (status
== BluetoothProfileServiceProvider::Delegate::CANCELLED
) {
1174 // TODO(keybuk): tear down this side of the connection
1175 error_callback
.Run(bluetooth_device::kErrorFailed
, "Canceled");
1176 } else if (status
== BluetoothProfileServiceProvider::Delegate::REJECTED
) {
1177 // TODO(keybuk): tear down this side of the connection
1178 error_callback
.Run(bluetooth_device::kErrorFailed
, "Rejected");
1182 void FakeBluetoothDeviceClient::DisconnectionCallback(
1183 const dbus::ObjectPath
& object_path
,
1184 const base::Closure
& callback
,
1185 const ErrorCallback
& error_callback
,
1186 BluetoothProfileServiceProvider::Delegate::Status status
) {
1187 VLOG(1) << "DisconnectionCallback: " << object_path
.value();
1189 if (status
== BluetoothProfileServiceProvider::Delegate::SUCCESS
) {
1190 // TODO(keybuk): tear down this side of the connection
1192 } else if (status
== BluetoothProfileServiceProvider::Delegate::CANCELLED
) {
1193 error_callback
.Run(bluetooth_device::kErrorFailed
, "Canceled");
1194 } else if (status
== BluetoothProfileServiceProvider::Delegate::REJECTED
) {
1195 error_callback
.Run(bluetooth_device::kErrorFailed
, "Rejected");
1199 } // namespace chromeos