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"
8 #include <sys/socket.h>
16 #include "base/location.h"
17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/rand_util.h"
20 #include "base/single_thread_task_runner.h"
21 #include "base/stl_util.h"
22 #include "base/thread_task_runner_handle.h"
23 #include "base/threading/worker_pool.h"
24 #include "base/time/time.h"
25 #include "chromeos/dbus/dbus_thread_manager.h"
26 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
27 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
28 #include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
29 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
30 #include "chromeos/dbus/fake_bluetooth_input_client.h"
31 #include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
32 #include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
33 #include "dbus/file_descriptor.h"
34 #include "third_party/cros_system_api/dbus/service_constants.h"
38 // Default interval between simulated events.
39 const int kSimulationIntervalMs
= 750;
41 // Minimum and maximum bounds for randomly generated RSSI values.
42 const int kMinRSSI
= -90;
43 const int kMaxRSSI
= -30;
45 // The default value of connection info properties from GetConnInfo().
46 const int kUnkownPower
= 127;
49 void SimulatedProfileSocket(int fd
) {
50 // Simulate a server-side socket of a profile; read data from the socket,
51 // write it back, and then close.
56 len
= read(fd
, buf
, sizeof buf
);
63 len
= write(fd
, buf
, count
);
72 void SimpleErrorCallback(const std::string
& error_name
,
73 const std::string
& error_message
) {
74 VLOG(1) << "Bluetooth Error: " << error_name
<< ": " << error_message
;
81 const char FakeBluetoothDeviceClient::kPairedDevicePath
[] =
83 const char FakeBluetoothDeviceClient::kPairedDeviceAddress
[] =
85 const char FakeBluetoothDeviceClient::kPairedDeviceName
[] =
87 const uint32
FakeBluetoothDeviceClient::kPairedDeviceClass
= 0x000104;
89 const char FakeBluetoothDeviceClient::kLegacyAutopairPath
[] =
91 const char FakeBluetoothDeviceClient::kLegacyAutopairAddress
[] =
93 const char FakeBluetoothDeviceClient::kLegacyAutopairName
[] =
94 "Bluetooth 2.0 Mouse";
95 const uint32
FakeBluetoothDeviceClient::kLegacyAutopairClass
= 0x002580;
97 const char FakeBluetoothDeviceClient::kDisplayPinCodePath
[] =
99 const char FakeBluetoothDeviceClient::kDisplayPinCodeAddress
[] =
101 const char FakeBluetoothDeviceClient::kDisplayPinCodeName
[] =
102 "Bluetooth 2.0 Keyboard";
103 const uint32
FakeBluetoothDeviceClient::kDisplayPinCodeClass
= 0x002540;
105 const char FakeBluetoothDeviceClient::kVanishingDevicePath
[] =
107 const char FakeBluetoothDeviceClient::kVanishingDeviceAddress
[] =
109 const char FakeBluetoothDeviceClient::kVanishingDeviceName
[] =
111 const uint32
FakeBluetoothDeviceClient::kVanishingDeviceClass
= 0x000104;
113 const char FakeBluetoothDeviceClient::kConnectUnpairablePath
[] =
115 const char FakeBluetoothDeviceClient::kConnectUnpairableAddress
[] =
117 const char FakeBluetoothDeviceClient::kConnectUnpairableName
[] =
119 const uint32
FakeBluetoothDeviceClient::kConnectUnpairableClass
= 0x002580;
121 const char FakeBluetoothDeviceClient::kDisplayPasskeyPath
[] =
123 const char FakeBluetoothDeviceClient::kDisplayPasskeyAddress
[] =
125 const char FakeBluetoothDeviceClient::kDisplayPasskeyName
[] =
126 "Bluetooth 2.1+ Keyboard";
127 const uint32
FakeBluetoothDeviceClient::kDisplayPasskeyClass
= 0x002540;
129 const char FakeBluetoothDeviceClient::kRequestPinCodePath
[] =
131 const char FakeBluetoothDeviceClient::kRequestPinCodeAddress
[] =
133 const char FakeBluetoothDeviceClient::kRequestPinCodeName
[] =
135 const uint32
FakeBluetoothDeviceClient::kRequestPinCodeClass
= 0x240408;
137 const char FakeBluetoothDeviceClient::kConfirmPasskeyPath
[] =
139 const char FakeBluetoothDeviceClient::kConfirmPasskeyAddress
[] =
141 const char FakeBluetoothDeviceClient::kConfirmPasskeyName
[] =
143 const uint32
FakeBluetoothDeviceClient::kConfirmPasskeyClass
= 0x7a020c;
145 const char FakeBluetoothDeviceClient::kRequestPasskeyPath
[] =
147 const char FakeBluetoothDeviceClient::kRequestPasskeyAddress
[] =
149 const char FakeBluetoothDeviceClient::kRequestPasskeyName
[] =
151 const uint32
FakeBluetoothDeviceClient::kRequestPasskeyClass
= 0x7a020c;
153 const char FakeBluetoothDeviceClient::kUnconnectableDevicePath
[] =
155 const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress
[] =
157 const char FakeBluetoothDeviceClient::kUnconnectableDeviceName
[] =
158 "Unconnectable Device";
159 const uint32
FakeBluetoothDeviceClient::kUnconnectableDeviceClass
= 0x7a020c;
161 const char FakeBluetoothDeviceClient::kUnpairableDevicePath
[] =
163 const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress
[] =
165 const char FakeBluetoothDeviceClient::kUnpairableDeviceName
[] =
167 const uint32
FakeBluetoothDeviceClient::kUnpairableDeviceClass
= 0x002540;
169 const char FakeBluetoothDeviceClient::kJustWorksPath
[] =
171 const char FakeBluetoothDeviceClient::kJustWorksAddress
[] =
173 const char FakeBluetoothDeviceClient::kJustWorksName
[] =
175 const uint32
FakeBluetoothDeviceClient::kJustWorksClass
= 0x240428;
177 const char FakeBluetoothDeviceClient::kLowEnergyPath
[] =
179 const char FakeBluetoothDeviceClient::kLowEnergyAddress
[] =
181 const char FakeBluetoothDeviceClient::kLowEnergyName
[] =
182 "Bluetooth 4.0 Heart Rate Monitor";
183 const uint32
FakeBluetoothDeviceClient::kLowEnergyClass
=
184 0x000918; // Major class "Health", Minor class "Heart/Pulse Rate Monitor."
186 const char FakeBluetoothDeviceClient::kPairedUnconnectableDevicePath
[] =
188 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress
[] =
190 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceName
[] =
191 "Paired Unconnectable Device";
192 const uint32
FakeBluetoothDeviceClient::kPairedUnconnectableDeviceClass
=
195 FakeBluetoothDeviceClient::Properties::Properties(
196 const PropertyChangedCallback
& callback
)
197 : BluetoothDeviceClient::Properties(
199 bluetooth_device::kBluetoothDeviceInterface
,
203 FakeBluetoothDeviceClient::Properties::~Properties() {
206 void FakeBluetoothDeviceClient::Properties::Get(
207 dbus::PropertyBase
* property
,
208 dbus::PropertySet::GetCallback callback
) {
209 VLOG(1) << "Get " << property
->name();
213 void FakeBluetoothDeviceClient::Properties::GetAll() {
217 void FakeBluetoothDeviceClient::Properties::Set(
218 dbus::PropertyBase
*property
,
219 dbus::PropertySet::SetCallback callback
) {
220 VLOG(1) << "Set " << property
->name();
221 if (property
->name() == trusted
.name()) {
223 property
->ReplaceValueWithSetValue();
229 FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
230 : simulation_interval_ms_(kSimulationIntervalMs
),
231 discovery_simulation_step_(0),
232 incoming_pairing_simulation_step_(0),
233 pairing_cancelled_(false),
234 connection_rssi_(kUnkownPower
),
235 transmit_power_(kUnkownPower
),
236 max_transmit_power_(kUnkownPower
) {
237 Properties
* properties
= new Properties(base::Bind(
238 &FakeBluetoothDeviceClient::OnPropertyChanged
,
239 base::Unretained(this),
240 dbus::ObjectPath(kPairedDevicePath
)));
241 properties
->address
.ReplaceValue(kPairedDeviceAddress
);
242 properties
->bluetooth_class
.ReplaceValue(kPairedDeviceClass
);
243 properties
->name
.ReplaceValue("Fake Device (Name)");
244 properties
->alias
.ReplaceValue(kPairedDeviceName
);
245 properties
->paired
.ReplaceValue(true);
246 properties
->trusted
.ReplaceValue(true);
247 properties
->adapter
.ReplaceValue(
248 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
));
250 std::vector
<std::string
> uuids
;
251 uuids
.push_back("00001800-0000-1000-8000-00805f9b34fb");
252 uuids
.push_back("00001801-0000-1000-8000-00805f9b34fb");
253 properties
->uuids
.ReplaceValue(uuids
);
255 properties
->modalias
.ReplaceValue("usb:v05ACp030Dd0306");
257 properties_map_
[dbus::ObjectPath(kPairedDevicePath
)] = properties
;
258 device_list_
.push_back(dbus::ObjectPath(kPairedDevicePath
));
260 properties
= new Properties(base::Bind(
261 &FakeBluetoothDeviceClient::OnPropertyChanged
, base::Unretained(this),
262 dbus::ObjectPath(kPairedUnconnectableDevicePath
)));
263 properties
->address
.ReplaceValue(kPairedUnconnectableDeviceAddress
);
264 properties
->bluetooth_class
.ReplaceValue(kPairedUnconnectableDeviceClass
);
265 properties
->name
.ReplaceValue("Fake Device 2 (Unconnectable)");
266 properties
->alias
.ReplaceValue(kPairedUnconnectableDeviceName
);
267 properties
->paired
.ReplaceValue(true);
268 properties
->trusted
.ReplaceValue(true);
269 properties
->adapter
.ReplaceValue(
270 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
));
272 properties
->uuids
.ReplaceValue(uuids
);
274 properties
->modalias
.ReplaceValue("usb:v05ACp030Dd0306");
276 properties_map_
[dbus::ObjectPath(kPairedUnconnectableDevicePath
)] =
278 device_list_
.push_back(dbus::ObjectPath(kPairedUnconnectableDevicePath
));
281 FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() {
282 // Clean up Properties structures
283 STLDeleteValues(&properties_map_
);
286 void FakeBluetoothDeviceClient::Init(dbus::Bus
* bus
) {
289 void FakeBluetoothDeviceClient::AddObserver(Observer
* observer
) {
290 observers_
.AddObserver(observer
);
293 void FakeBluetoothDeviceClient::RemoveObserver(Observer
* observer
) {
294 observers_
.RemoveObserver(observer
);
297 std::vector
<dbus::ObjectPath
> FakeBluetoothDeviceClient::GetDevicesForAdapter(
298 const dbus::ObjectPath
& adapter_path
) {
300 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
))
303 return std::vector
<dbus::ObjectPath
>();
306 FakeBluetoothDeviceClient::Properties
*
307 FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath
& object_path
) {
308 PropertiesMap::iterator iter
= properties_map_
.find(object_path
);
309 if (iter
!= properties_map_
.end())
314 void FakeBluetoothDeviceClient::Connect(
315 const dbus::ObjectPath
& object_path
,
316 const base::Closure
& callback
,
317 const ErrorCallback
& error_callback
) {
318 VLOG(1) << "Connect: " << object_path
.value();
319 Properties
* properties
= GetProperties(object_path
);
321 if (properties
->connected
.value() == true) {
322 // Already connected.
327 if (properties
->paired
.value() != true &&
328 object_path
!= dbus::ObjectPath(kConnectUnpairablePath
) &&
329 object_path
!= dbus::ObjectPath(kLowEnergyPath
)) {
331 error_callback
.Run(bluetooth_device::kErrorFailed
, "Not paired");
333 } else if (properties
->paired
.value() == true &&
334 (object_path
== dbus::ObjectPath(kUnconnectableDevicePath
) ||
336 dbus::ObjectPath(kPairedUnconnectableDevicePath
))) {
337 // Must not be paired
338 error_callback
.Run(bluetooth_device::kErrorFailed
,
339 "Connection fails while paired");
343 // The device can be connected.
344 properties
->connected
.ReplaceValue(true);
347 // Expose GATT services if connected to LE device.
348 if (object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
349 FakeBluetoothGattServiceClient
* gatt_service_client
=
350 static_cast<FakeBluetoothGattServiceClient
*>(
351 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
352 gatt_service_client
->ExposeHeartRateService(
353 dbus::ObjectPath(kLowEnergyPath
));
356 AddInputDeviceIfNeeded(object_path
, properties
);
359 void FakeBluetoothDeviceClient::Disconnect(
360 const dbus::ObjectPath
& object_path
,
361 const base::Closure
& callback
,
362 const ErrorCallback
& error_callback
) {
363 VLOG(1) << "Disconnect: " << object_path
.value();
364 Properties
* properties
= GetProperties(object_path
);
366 if (!properties
->connected
.value()) {
367 error_callback
.Run("org.bluez.Error.NotConnected", "Not Connected");
371 // Hide the Heart Rate Service if disconnected from LE device.
372 if (object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
373 FakeBluetoothGattServiceClient
* gatt_service_client
=
374 static_cast<FakeBluetoothGattServiceClient
*>(
375 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
376 gatt_service_client
->HideHeartRateService();
380 properties
->connected
.ReplaceValue(false);
383 void FakeBluetoothDeviceClient::ConnectProfile(
384 const dbus::ObjectPath
& object_path
,
385 const std::string
& uuid
,
386 const base::Closure
& callback
,
387 const ErrorCallback
& error_callback
) {
388 VLOG(1) << "ConnectProfile: " << object_path
.value() << " " << uuid
;
390 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
391 static_cast<FakeBluetoothProfileManagerClient
*>(
392 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
393 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
394 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(uuid
);
395 if (profile_service_provider
== NULL
) {
396 error_callback
.Run(kNoResponseError
, "Missing profile");
400 if (object_path
== dbus::ObjectPath(kPairedUnconnectableDevicePath
)) {
401 error_callback
.Run(bluetooth_device::kErrorFailed
, "unconnectable");
405 // Make a socket pair of a compatible type with the type used by Bluetooth;
406 // spin up a thread to simulate the server side and wrap the client side in
407 // a D-Bus file descriptor object.
408 int socket_type
= SOCK_STREAM
;
409 if (uuid
== FakeBluetoothProfileManagerClient::kL2capUuid
)
410 socket_type
= SOCK_SEQPACKET
;
413 if (socketpair(AF_UNIX
, socket_type
, 0, fds
) < 0) {
414 error_callback
.Run(kNoResponseError
, "socketpair call failed");
419 args
= fcntl(fds
[1], F_GETFL
, NULL
);
421 error_callback
.Run(kNoResponseError
, "failed to get socket flags");
426 if (fcntl(fds
[1], F_SETFL
, args
) < 0) {
427 error_callback
.Run(kNoResponseError
, "failed to set socket non-blocking");
431 base::WorkerPool::GetTaskRunner(false)->PostTask(
433 base::Bind(&SimulatedProfileSocket
,
436 scoped_ptr
<dbus::FileDescriptor
> fd(new dbus::FileDescriptor(fds
[1]));
438 // Post the new connection to the service provider.
439 BluetoothProfileServiceProvider::Delegate::Options options
;
441 profile_service_provider
->NewConnection(
445 base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback
,
446 base::Unretained(this),
452 void FakeBluetoothDeviceClient::DisconnectProfile(
453 const dbus::ObjectPath
& object_path
,
454 const std::string
& uuid
,
455 const base::Closure
& callback
,
456 const ErrorCallback
& error_callback
) {
457 VLOG(1) << "DisconnectProfile: " << object_path
.value() << " " << uuid
;
459 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
460 static_cast<FakeBluetoothProfileManagerClient
*>(
461 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
462 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
463 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(uuid
);
464 if (profile_service_provider
== NULL
) {
465 error_callback
.Run(kNoResponseError
, "Missing profile");
469 profile_service_provider
->RequestDisconnection(
471 base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback
,
472 base::Unretained(this),
478 void FakeBluetoothDeviceClient::Pair(
479 const dbus::ObjectPath
& object_path
,
480 const base::Closure
& callback
,
481 const ErrorCallback
& error_callback
) {
482 VLOG(1) << "Pair: " << object_path
.value();
483 Properties
* properties
= GetProperties(object_path
);
485 if (properties
->paired
.value() == true) {
491 SimulatePairing(object_path
, false, callback
, error_callback
);
494 void FakeBluetoothDeviceClient::CancelPairing(
495 const dbus::ObjectPath
& object_path
,
496 const base::Closure
& callback
,
497 const ErrorCallback
& error_callback
) {
498 VLOG(1) << "CancelPairing: " << object_path
.value();
499 pairing_cancelled_
= true;
503 void FakeBluetoothDeviceClient::GetConnInfo(
504 const dbus::ObjectPath
& object_path
,
505 const ConnInfoCallback
& callback
,
506 const ErrorCallback
& error_callback
) {
507 Properties
* properties
= GetProperties(object_path
);
508 if (!properties
->connected
.value()) {
509 error_callback
.Run("org.bluez.Error.NotConnected", "Not Connected");
513 callback
.Run(connection_rssi_
, transmit_power_
, max_transmit_power_
);
516 void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
517 const dbus::ObjectPath
& adapter_path
) {
518 VLOG(1) << "starting discovery simulation";
520 discovery_simulation_step_
= 1;
522 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
524 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer
,
525 base::Unretained(this)),
526 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
529 void FakeBluetoothDeviceClient::EndDiscoverySimulation(
530 const dbus::ObjectPath
& adapter_path
) {
531 VLOG(1) << "stopping discovery simulation";
532 discovery_simulation_step_
= 0;
535 void FakeBluetoothDeviceClient::BeginIncomingPairingSimulation(
536 const dbus::ObjectPath
& adapter_path
) {
537 VLOG(1) << "starting incoming pairing simulation";
539 incoming_pairing_simulation_step_
= 1;
541 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
543 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer
,
544 base::Unretained(this)),
545 base::TimeDelta::FromMilliseconds(30 * simulation_interval_ms_
));
548 void FakeBluetoothDeviceClient::EndIncomingPairingSimulation(
549 const dbus::ObjectPath
& adapter_path
) {
550 VLOG(1) << "stopping incoming pairing simulation";
551 incoming_pairing_simulation_step_
= 0;
554 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms
) {
555 simulation_interval_ms_
= interval_ms
;
558 void FakeBluetoothDeviceClient::CreateDevice(
559 const dbus::ObjectPath
& adapter_path
,
560 const dbus::ObjectPath
& device_path
) {
561 if (std::find(device_list_
.begin(),
562 device_list_
.end(), device_path
) != device_list_
.end())
565 Properties
* properties
= new Properties(base::Bind(
566 &FakeBluetoothDeviceClient::OnPropertyChanged
,
567 base::Unretained(this),
569 properties
->adapter
.ReplaceValue(adapter_path
);
571 if (device_path
== dbus::ObjectPath(kLegacyAutopairPath
)) {
572 properties
->address
.ReplaceValue(kLegacyAutopairAddress
);
573 properties
->bluetooth_class
.ReplaceValue(kLegacyAutopairClass
);
574 properties
->name
.ReplaceValue("LegacyAutopair");
575 properties
->alias
.ReplaceValue(kLegacyAutopairName
);
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(kDisplayPinCodePath
)) {
582 properties
->address
.ReplaceValue(kDisplayPinCodeAddress
);
583 properties
->bluetooth_class
.ReplaceValue(kDisplayPinCodeClass
);
584 properties
->name
.ReplaceValue("DisplayPinCode");
585 properties
->alias
.ReplaceValue(kDisplayPinCodeName
);
587 std::vector
<std::string
> uuids
;
588 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
589 properties
->uuids
.ReplaceValue(uuids
);
591 } else if (device_path
== dbus::ObjectPath(kVanishingDevicePath
)) {
592 properties
->address
.ReplaceValue(kVanishingDeviceAddress
);
593 properties
->bluetooth_class
.ReplaceValue(kVanishingDeviceClass
);
594 properties
->name
.ReplaceValue("VanishingDevice");
595 properties
->alias
.ReplaceValue(kVanishingDeviceName
);
597 } else if (device_path
== dbus::ObjectPath(kConnectUnpairablePath
)) {
598 properties
->address
.ReplaceValue(kConnectUnpairableAddress
);
599 properties
->bluetooth_class
.ReplaceValue(kConnectUnpairableClass
);
600 properties
->name
.ReplaceValue("ConnectUnpairable");
601 properties
->alias
.ReplaceValue(kConnectUnpairableName
);
603 std::vector
<std::string
> uuids
;
604 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
605 properties
->uuids
.ReplaceValue(uuids
);
607 } else if (device_path
== dbus::ObjectPath(kDisplayPasskeyPath
)) {
608 properties
->address
.ReplaceValue(kDisplayPasskeyAddress
);
609 properties
->bluetooth_class
.ReplaceValue(kDisplayPasskeyClass
);
610 properties
->name
.ReplaceValue("DisplayPasskey");
611 properties
->alias
.ReplaceValue(kDisplayPasskeyName
);
613 std::vector
<std::string
> uuids
;
614 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
615 properties
->uuids
.ReplaceValue(uuids
);
617 } else if (device_path
== dbus::ObjectPath(kRequestPinCodePath
)) {
618 properties
->address
.ReplaceValue(kRequestPinCodeAddress
);
619 properties
->bluetooth_class
.ReplaceValue(kRequestPinCodeClass
);
620 properties
->name
.ReplaceValue("RequestPinCode");
621 properties
->alias
.ReplaceValue(kRequestPinCodeName
);
623 } else if (device_path
== dbus::ObjectPath(kConfirmPasskeyPath
)) {
624 properties
->address
.ReplaceValue(kConfirmPasskeyAddress
);
625 properties
->bluetooth_class
.ReplaceValue(kConfirmPasskeyClass
);
626 properties
->name
.ReplaceValue("ConfirmPasskey");
627 properties
->alias
.ReplaceValue(kConfirmPasskeyName
);
629 } else if (device_path
== dbus::ObjectPath(kRequestPasskeyPath
)) {
630 properties
->address
.ReplaceValue(kRequestPasskeyAddress
);
631 properties
->bluetooth_class
.ReplaceValue(kRequestPasskeyClass
);
632 properties
->name
.ReplaceValue("RequestPasskey");
633 properties
->alias
.ReplaceValue(kRequestPasskeyName
);
635 } else if (device_path
== dbus::ObjectPath(kUnconnectableDevicePath
)) {
636 properties
->address
.ReplaceValue(kUnconnectableDeviceAddress
);
637 properties
->bluetooth_class
.ReplaceValue(kUnconnectableDeviceClass
);
638 properties
->name
.ReplaceValue("UnconnectableDevice");
639 properties
->alias
.ReplaceValue(kUnconnectableDeviceName
);
641 } else if (device_path
== dbus::ObjectPath(kUnpairableDevicePath
)) {
642 properties
->address
.ReplaceValue(kUnpairableDeviceAddress
);
643 properties
->bluetooth_class
.ReplaceValue(kUnpairableDeviceClass
);
644 properties
->name
.ReplaceValue("Fake Unpairable Device");
645 properties
->alias
.ReplaceValue(kUnpairableDeviceName
);
647 } else if (device_path
== dbus::ObjectPath(kJustWorksPath
)) {
648 properties
->address
.ReplaceValue(kJustWorksAddress
);
649 properties
->bluetooth_class
.ReplaceValue(kJustWorksClass
);
650 properties
->name
.ReplaceValue("JustWorks");
651 properties
->alias
.ReplaceValue(kJustWorksName
);
653 } else if (device_path
== dbus::ObjectPath(kLowEnergyPath
)) {
654 properties
->address
.ReplaceValue(kLowEnergyAddress
);
655 properties
->bluetooth_class
.ReplaceValue(kLowEnergyClass
);
656 properties
->name
.ReplaceValue("Heart Rate Monitor");
657 properties
->alias
.ReplaceValue(kLowEnergyName
);
659 std::vector
<std::string
> uuids
;
660 uuids
.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
);
661 properties
->uuids
.ReplaceValue(uuids
);
668 properties_map_
[device_path
] = properties
;
669 device_list_
.push_back(device_path
);
670 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
671 DeviceAdded(device_path
));
674 void FakeBluetoothDeviceClient::RemoveDevice(
675 const dbus::ObjectPath
& adapter_path
,
676 const dbus::ObjectPath
& device_path
) {
677 std::vector
<dbus::ObjectPath
>::iterator listiter
=
678 std::find(device_list_
.begin(), device_list_
.end(), device_path
);
679 if (listiter
== device_list_
.end())
682 PropertiesMap::iterator iter
= properties_map_
.find(device_path
);
683 Properties
* properties
= iter
->second
;
685 VLOG(1) << "removing device: " << properties
->alias
.value();
686 device_list_
.erase(listiter
);
688 // Remove the Input interface if it exists. This should be called before the
689 // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
690 // BluetoothDeviceChromeOS object, including the device_path referenced here.
691 FakeBluetoothInputClient
* fake_bluetooth_input_client
=
692 static_cast<FakeBluetoothInputClient
*>(
693 DBusThreadManager::Get()->GetBluetoothInputClient());
694 fake_bluetooth_input_client
->RemoveInputDevice(device_path
);
696 if (device_path
== dbus::ObjectPath(kLowEnergyPath
)) {
697 FakeBluetoothGattServiceClient
* gatt_service_client
=
698 static_cast<FakeBluetoothGattServiceClient
*>(
699 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
700 gatt_service_client
->HideHeartRateService();
703 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
704 DeviceRemoved(device_path
));
707 properties_map_
.erase(iter
);
710 void FakeBluetoothDeviceClient::OnPropertyChanged(
711 const dbus::ObjectPath
& object_path
,
712 const std::string
& property_name
) {
713 VLOG(2) << "Fake Bluetooth device property changed: " << object_path
.value()
714 << ": " << property_name
;
715 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
716 DevicePropertyChanged(object_path
, property_name
));
719 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
720 if (!discovery_simulation_step_
)
723 // Timer fires every .75s, the numbers below are arbitrary to give a feel
724 // for a discovery process.
725 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_
;
726 if (discovery_simulation_step_
== 2) {
727 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
728 dbus::ObjectPath(kLegacyAutopairPath
));
729 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
730 dbus::ObjectPath(kLowEnergyPath
));
732 } else if (discovery_simulation_step_
== 4) {
733 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
734 base::RandInt(kMinRSSI
, kMaxRSSI
));
735 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
736 dbus::ObjectPath(kDisplayPinCodePath
));
737 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
738 dbus::ObjectPath(kVanishingDevicePath
));
740 } else if (discovery_simulation_step_
== 7) {
741 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
742 dbus::ObjectPath(kConnectUnpairablePath
));
743 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
744 base::RandInt(kMinRSSI
, kMaxRSSI
));
746 } else if (discovery_simulation_step_
== 8) {
747 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
748 dbus::ObjectPath(kDisplayPasskeyPath
));
749 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
750 dbus::ObjectPath(kRequestPinCodePath
));
751 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
752 base::RandInt(kMinRSSI
, kMaxRSSI
));
754 } else if (discovery_simulation_step_
== 10) {
755 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
756 dbus::ObjectPath(kConfirmPasskeyPath
));
757 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
758 dbus::ObjectPath(kRequestPasskeyPath
));
759 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
760 dbus::ObjectPath(kUnconnectableDevicePath
));
761 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
762 dbus::ObjectPath(kUnpairableDevicePath
));
763 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
764 dbus::ObjectPath(kJustWorksPath
));
765 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
766 base::RandInt(kMinRSSI
, kMaxRSSI
));
768 } else if (discovery_simulation_step_
== 13) {
769 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
770 base::RandInt(kMinRSSI
, kMaxRSSI
));
771 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
772 dbus::ObjectPath(kVanishingDevicePath
));
774 } else if (discovery_simulation_step_
== 14) {
775 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
776 base::RandInt(kMinRSSI
, kMaxRSSI
));
781 ++discovery_simulation_step_
;
782 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
784 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer
,
785 base::Unretained(this)),
786 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
789 void FakeBluetoothDeviceClient::IncomingPairingSimulationTimer() {
790 if (!incoming_pairing_simulation_step_
)
793 VLOG(1) << "incoming pairing simulation, step "
794 << incoming_pairing_simulation_step_
;
795 switch (incoming_pairing_simulation_step_
) {
797 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
798 dbus::ObjectPath(kConfirmPasskeyPath
));
799 SimulatePairing(dbus::ObjectPath(kConfirmPasskeyPath
), true,
800 base::Bind(&base::DoNothing
),
801 base::Bind(&SimpleErrorCallback
));
804 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
805 dbus::ObjectPath(kJustWorksPath
));
806 SimulatePairing(dbus::ObjectPath(kJustWorksPath
), true,
807 base::Bind(&base::DoNothing
),
808 base::Bind(&SimpleErrorCallback
));
811 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
812 dbus::ObjectPath(kDisplayPinCodePath
));
813 SimulatePairing(dbus::ObjectPath(kDisplayPinCodePath
), true,
814 base::Bind(&base::DoNothing
),
815 base::Bind(&SimpleErrorCallback
));
818 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
819 dbus::ObjectPath(kDisplayPasskeyPath
));
820 SimulatePairing(dbus::ObjectPath(kDisplayPasskeyPath
), true,
821 base::Bind(&base::DoNothing
),
822 base::Bind(&SimpleErrorCallback
));
825 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
826 dbus::ObjectPath(kRequestPinCodePath
));
827 SimulatePairing(dbus::ObjectPath(kRequestPinCodePath
), true,
828 base::Bind(&base::DoNothing
),
829 base::Bind(&SimpleErrorCallback
));
832 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
833 dbus::ObjectPath(kRequestPasskeyPath
));
834 SimulatePairing(dbus::ObjectPath(kRequestPasskeyPath
), true,
835 base::Bind(&base::DoNothing
),
836 base::Bind(&SimpleErrorCallback
));
842 ++incoming_pairing_simulation_step_
;
843 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
845 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer
,
846 base::Unretained(this)),
847 base::TimeDelta::FromMilliseconds(45 * simulation_interval_ms_
));
850 void FakeBluetoothDeviceClient::SimulatePairing(
851 const dbus::ObjectPath
& object_path
,
852 bool incoming_request
,
853 const base::Closure
& callback
,
854 const ErrorCallback
& error_callback
) {
855 pairing_cancelled_
= false;
857 FakeBluetoothAgentManagerClient
* fake_bluetooth_agent_manager_client
=
858 static_cast<FakeBluetoothAgentManagerClient
*>(
859 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
860 FakeBluetoothAgentServiceProvider
* agent_service_provider
=
861 fake_bluetooth_agent_manager_client
->GetAgentServiceProvider();
862 CHECK(agent_service_provider
!= NULL
);
864 if (object_path
== dbus::ObjectPath(kLegacyAutopairPath
) ||
865 object_path
== dbus::ObjectPath(kConnectUnpairablePath
) ||
866 object_path
== dbus::ObjectPath(kUnconnectableDevicePath
) ||
867 object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
868 // No need to call anything on the pairing delegate, just wait 3 times
869 // the interval before acting as if the other end accepted it.
870 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
872 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
873 base::Unretained(this), object_path
, callback
,
875 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
877 } else if (object_path
== dbus::ObjectPath(kDisplayPinCodePath
)) {
878 // Display a Pincode, and wait 7 times the interval before acting as
879 // if the other end accepted it.
880 agent_service_provider
->DisplayPinCode(object_path
, "123456");
882 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
884 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
885 base::Unretained(this), object_path
, callback
,
887 base::TimeDelta::FromMilliseconds(7 * simulation_interval_ms_
));
889 } else if (object_path
== dbus::ObjectPath(kVanishingDevicePath
)) {
890 // The vanishing device simulates being too far away, and thus times out.
891 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
893 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing
,
894 base::Unretained(this), object_path
, error_callback
),
895 base::TimeDelta::FromMilliseconds(4 * simulation_interval_ms_
));
897 } else if (object_path
== dbus::ObjectPath(kDisplayPasskeyPath
)) {
898 // Display a passkey, and each interval act as if another key was entered
900 agent_service_provider
->DisplayPasskey(object_path
, 123456, 0);
902 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
903 FROM_HERE
, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress
,
904 base::Unretained(this), 1, object_path
, callback
,
906 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
908 } else if (object_path
== dbus::ObjectPath(kRequestPinCodePath
)) {
909 // Request a Pincode.
910 agent_service_provider
->RequestPinCode(
912 base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback
,
913 base::Unretained(this),
918 } else if (object_path
== dbus::ObjectPath(kConfirmPasskeyPath
)) {
919 // Request confirmation of a Passkey.
920 agent_service_provider
->RequestConfirmation(
922 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback
,
923 base::Unretained(this),
928 } else if (object_path
== dbus::ObjectPath(kRequestPasskeyPath
)) {
929 // Request a Passkey from the user.
930 agent_service_provider
->RequestPasskey(
932 base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback
,
933 base::Unretained(this),
938 } else if (object_path
== dbus::ObjectPath(kUnpairableDevicePath
)) {
939 // Fails the pairing with an org.bluez.Error.Failed error.
940 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
942 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing
,
943 base::Unretained(this), object_path
, error_callback
),
944 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
946 } else if (object_path
== dbus::ObjectPath(kJustWorksPath
)) {
947 if (incoming_request
) {
948 agent_service_provider
->RequestAuthorization(
950 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback
,
951 base::Unretained(this),
957 // No need to call anything on the pairing delegate, just wait 3 times
958 // the interval before acting as if the other end accepted it.
959 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
961 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
962 base::Unretained(this), object_path
, callback
,
964 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
968 error_callback
.Run(kNoResponseError
, "No pairing fake");
972 void FakeBluetoothDeviceClient::CompleteSimulatedPairing(
973 const dbus::ObjectPath
& object_path
,
974 const base::Closure
& callback
,
975 const ErrorCallback
& error_callback
) {
976 VLOG(1) << "CompleteSimulatedPairing: " << object_path
.value();
977 if (pairing_cancelled_
) {
978 pairing_cancelled_
= false;
980 error_callback
.Run(bluetooth_device::kErrorAuthenticationCanceled
,
983 Properties
* properties
= GetProperties(object_path
);
985 properties
->paired
.ReplaceValue(true);
988 AddInputDeviceIfNeeded(object_path
, properties
);
992 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing(
993 const dbus::ObjectPath
& object_path
,
994 const ErrorCallback
& error_callback
) {
995 VLOG(1) << "TimeoutSimulatedPairing: " << object_path
.value();
997 error_callback
.Run(bluetooth_device::kErrorAuthenticationTimeout
,
1001 void FakeBluetoothDeviceClient::CancelSimulatedPairing(
1002 const dbus::ObjectPath
& object_path
,
1003 const ErrorCallback
& error_callback
) {
1004 VLOG(1) << "CancelSimulatedPairing: " << object_path
.value();
1006 error_callback
.Run(bluetooth_device::kErrorAuthenticationCanceled
,
1010 void FakeBluetoothDeviceClient::RejectSimulatedPairing(
1011 const dbus::ObjectPath
& object_path
,
1012 const ErrorCallback
& error_callback
) {
1013 VLOG(1) << "RejectSimulatedPairing: " << object_path
.value();
1015 error_callback
.Run(bluetooth_device::kErrorAuthenticationRejected
,
1019 void FakeBluetoothDeviceClient::FailSimulatedPairing(
1020 const dbus::ObjectPath
& object_path
,
1021 const ErrorCallback
& error_callback
) {
1022 VLOG(1) << "FailSimulatedPairing: " << object_path
.value();
1024 error_callback
.Run(bluetooth_device::kErrorFailed
, "Failed");
1027 void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded(
1028 const dbus::ObjectPath
& object_path
,
1029 Properties
* properties
) {
1030 // If the paired device is a HID device based on it's bluetooth class,
1031 // simulate the Input interface.
1032 FakeBluetoothInputClient
* fake_bluetooth_input_client
=
1033 static_cast<FakeBluetoothInputClient
*>(
1034 DBusThreadManager::Get()->GetBluetoothInputClient());
1036 if ((properties
->bluetooth_class
.value() & 0x001f03) == 0x000500)
1037 fake_bluetooth_input_client
->AddInputDevice(object_path
);
1040 void FakeBluetoothDeviceClient::UpdateDeviceRSSI(
1041 const dbus::ObjectPath
& object_path
,
1043 PropertiesMap::iterator iter
= properties_map_
.find(object_path
);
1044 if (iter
== properties_map_
.end()) {
1045 VLOG(2) << "Fake device does not exist: " << object_path
.value();
1048 Properties
* properties
= iter
->second
;
1050 properties
->rssi
.ReplaceValue(rssi
);
1053 void FakeBluetoothDeviceClient::UpdateConnectionInfo(
1054 uint16 connection_rssi
,
1055 uint16 transmit_power
,
1056 uint16 max_transmit_power
) {
1057 connection_rssi_
= connection_rssi
;
1058 transmit_power_
= transmit_power
;
1059 max_transmit_power_
= max_transmit_power
;
1062 void FakeBluetoothDeviceClient::PinCodeCallback(
1063 const dbus::ObjectPath
& object_path
,
1064 const base::Closure
& callback
,
1065 const ErrorCallback
& error_callback
,
1066 BluetoothAgentServiceProvider::Delegate::Status status
,
1067 const std::string
& pincode
) {
1068 VLOG(1) << "PinCodeCallback: " << object_path
.value();
1070 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1071 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1073 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1074 base::Unretained(this), object_path
, callback
,
1076 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
1078 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1079 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1081 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1082 base::Unretained(this), object_path
, error_callback
),
1083 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1085 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1086 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1088 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1089 base::Unretained(this), object_path
, error_callback
),
1090 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1094 void FakeBluetoothDeviceClient::PasskeyCallback(
1095 const dbus::ObjectPath
& object_path
,
1096 const base::Closure
& callback
,
1097 const ErrorCallback
& error_callback
,
1098 BluetoothAgentServiceProvider::Delegate::Status status
,
1100 VLOG(1) << "PasskeyCallback: " << object_path
.value();
1102 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1103 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1105 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1106 base::Unretained(this), object_path
, callback
,
1108 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
1110 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1111 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1113 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1114 base::Unretained(this), object_path
, error_callback
),
1115 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1117 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1118 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1120 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1121 base::Unretained(this), object_path
, error_callback
),
1122 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1126 void FakeBluetoothDeviceClient::ConfirmationCallback(
1127 const dbus::ObjectPath
& object_path
,
1128 const base::Closure
& callback
,
1129 const ErrorCallback
& error_callback
,
1130 BluetoothAgentServiceProvider::Delegate::Status status
) {
1131 VLOG(1) << "ConfirmationCallback: " << object_path
.value();
1133 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1134 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1136 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1137 base::Unretained(this), object_path
, callback
,
1139 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
1141 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1142 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1144 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1145 base::Unretained(this), object_path
, error_callback
),
1146 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1148 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1149 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1151 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1152 base::Unretained(this), object_path
, error_callback
),
1153 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1157 void FakeBluetoothDeviceClient::SimulateKeypress(
1159 const dbus::ObjectPath
& object_path
,
1160 const base::Closure
& callback
,
1161 const ErrorCallback
& error_callback
) {
1162 VLOG(1) << "SimulateKeypress " << entered
<< ": " << object_path
.value();
1164 FakeBluetoothAgentManagerClient
* fake_bluetooth_agent_manager_client
=
1165 static_cast<FakeBluetoothAgentManagerClient
*>(
1166 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
1167 FakeBluetoothAgentServiceProvider
* agent_service_provider
=
1168 fake_bluetooth_agent_manager_client
->GetAgentServiceProvider();
1170 // The agent service provider object could have been destroyed after the
1171 // pairing is canceled.
1172 if (!agent_service_provider
)
1175 agent_service_provider
->DisplayPasskey(object_path
, 123456, entered
);
1178 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1179 FROM_HERE
, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress
,
1180 base::Unretained(this), entered
+ 1, object_path
,
1181 callback
, error_callback
),
1182 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1185 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1187 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1188 base::Unretained(this), object_path
, callback
,
1190 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1194 void FakeBluetoothDeviceClient::ConnectionCallback(
1195 const dbus::ObjectPath
& object_path
,
1196 const base::Closure
& callback
,
1197 const ErrorCallback
& error_callback
,
1198 BluetoothProfileServiceProvider::Delegate::Status status
) {
1199 VLOG(1) << "ConnectionCallback: " << object_path
.value();
1201 if (status
== BluetoothProfileServiceProvider::Delegate::SUCCESS
) {
1203 } else if (status
== BluetoothProfileServiceProvider::Delegate::CANCELLED
) {
1204 // TODO(keybuk): tear down this side of the connection
1205 error_callback
.Run(bluetooth_device::kErrorFailed
, "Canceled");
1206 } else if (status
== BluetoothProfileServiceProvider::Delegate::REJECTED
) {
1207 // TODO(keybuk): tear down this side of the connection
1208 error_callback
.Run(bluetooth_device::kErrorFailed
, "Rejected");
1212 void FakeBluetoothDeviceClient::DisconnectionCallback(
1213 const dbus::ObjectPath
& object_path
,
1214 const base::Closure
& callback
,
1215 const ErrorCallback
& error_callback
,
1216 BluetoothProfileServiceProvider::Delegate::Status status
) {
1217 VLOG(1) << "DisconnectionCallback: " << object_path
.value();
1219 if (status
== BluetoothProfileServiceProvider::Delegate::SUCCESS
) {
1220 // TODO(keybuk): tear down this side of the connection
1222 } else if (status
== BluetoothProfileServiceProvider::Delegate::CANCELLED
) {
1223 error_callback
.Run(bluetooth_device::kErrorFailed
, "Canceled");
1224 } else if (status
== BluetoothProfileServiceProvider::Delegate::REJECTED
) {
1225 error_callback
.Run(bluetooth_device::kErrorFailed
, "Rejected");
1229 } // namespace chromeos