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;
48 const char kPairingMethodNone
[] = "None";
49 const char kPairingMethodPinCode
[] = "PIN Code";
50 const char kPairingMethodPassKey
[] = "PassKey";
51 const char kTestPinCode
[] = "123456";
53 // This is meant to delay the removal of a pre defined device until the
54 // developer has time to see it.
55 const int kVanishingDevicePairTimeMultiplier
= 4;
57 // Meant to delay a pair request for an observable amount of time.
58 const int kIncomingSimulationPairTimeMultiplier
= 45;
60 // Meant to delay a request that asks for pair requests for an observable
62 const int kIncomingSimulationStartPairTimeMultiplier
= 30;
64 // This allows the PIN code dialog to be shown for a long enough time to see
65 // the PIN code UI in detail.
66 const int kPinCodeDevicePairTimeMultiplier
= 7;
68 // This allows the pairing dialog to be shown for a long enough time to see
70 const int kSimulateNormalPairTimeMultiplier
= 3;
72 const int kTestPassKey
= 123456;
74 void SimulatedProfileSocket(int fd
) {
75 // Simulate a server-side socket of a profile; read data from the socket,
76 // write it back, and then close.
81 len
= read(fd
, buf
, sizeof buf
);
88 len
= write(fd
, buf
, count
);
97 void SimpleErrorCallback(const std::string
& error_name
,
98 const std::string
& error_message
) {
99 VLOG(1) << "Bluetooth Error: " << error_name
<< ": " << error_message
;
106 const char FakeBluetoothDeviceClient::kPairedDevicePath
[] =
108 const char FakeBluetoothDeviceClient::kPairedDeviceAddress
[] =
110 const char FakeBluetoothDeviceClient::kPairedDeviceName
[] =
112 const uint32
FakeBluetoothDeviceClient::kPairedDeviceClass
= 0x000104;
114 const char FakeBluetoothDeviceClient::kLegacyAutopairPath
[] =
116 const char FakeBluetoothDeviceClient::kLegacyAutopairAddress
[] =
118 const char FakeBluetoothDeviceClient::kLegacyAutopairName
[] =
119 "Bluetooth 2.0 Mouse";
120 const uint32
FakeBluetoothDeviceClient::kLegacyAutopairClass
= 0x002580;
122 const char FakeBluetoothDeviceClient::kDisplayPinCodePath
[] =
124 const char FakeBluetoothDeviceClient::kDisplayPinCodeAddress
[] =
126 const char FakeBluetoothDeviceClient::kDisplayPinCodeName
[] =
127 "Bluetooth 2.0 Keyboard";
128 const uint32
FakeBluetoothDeviceClient::kDisplayPinCodeClass
= 0x002540;
130 const char FakeBluetoothDeviceClient::kVanishingDevicePath
[] =
132 const char FakeBluetoothDeviceClient::kVanishingDeviceAddress
[] =
134 const char FakeBluetoothDeviceClient::kVanishingDeviceName
[] =
136 const uint32
FakeBluetoothDeviceClient::kVanishingDeviceClass
= 0x000104;
138 const char FakeBluetoothDeviceClient::kConnectUnpairablePath
[] =
140 const char FakeBluetoothDeviceClient::kConnectUnpairableAddress
[] =
142 const char FakeBluetoothDeviceClient::kConnectUnpairableName
[] =
144 const uint32
FakeBluetoothDeviceClient::kConnectUnpairableClass
= 0x002580;
146 const char FakeBluetoothDeviceClient::kDisplayPasskeyPath
[] =
148 const char FakeBluetoothDeviceClient::kDisplayPasskeyAddress
[] =
150 const char FakeBluetoothDeviceClient::kDisplayPasskeyName
[] =
151 "Bluetooth 2.1+ Keyboard";
152 const uint32
FakeBluetoothDeviceClient::kDisplayPasskeyClass
= 0x002540;
154 const char FakeBluetoothDeviceClient::kRequestPinCodePath
[] =
156 const char FakeBluetoothDeviceClient::kRequestPinCodeAddress
[] =
158 const char FakeBluetoothDeviceClient::kRequestPinCodeName
[] =
160 const uint32
FakeBluetoothDeviceClient::kRequestPinCodeClass
= 0x240408;
162 const char FakeBluetoothDeviceClient::kConfirmPasskeyPath
[] =
164 const char FakeBluetoothDeviceClient::kConfirmPasskeyAddress
[] =
166 const char FakeBluetoothDeviceClient::kConfirmPasskeyName
[] =
168 const uint32
FakeBluetoothDeviceClient::kConfirmPasskeyClass
= 0x7a020c;
170 const char FakeBluetoothDeviceClient::kRequestPasskeyPath
[] =
172 const char FakeBluetoothDeviceClient::kRequestPasskeyAddress
[] =
174 const char FakeBluetoothDeviceClient::kRequestPasskeyName
[] =
176 const uint32
FakeBluetoothDeviceClient::kRequestPasskeyClass
= 0x7a020c;
178 const char FakeBluetoothDeviceClient::kUnconnectableDevicePath
[] =
180 const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress
[] =
182 const char FakeBluetoothDeviceClient::kUnconnectableDeviceName
[] =
183 "Unconnectable Device";
184 const uint32
FakeBluetoothDeviceClient::kUnconnectableDeviceClass
= 0x7a020c;
186 const char FakeBluetoothDeviceClient::kUnpairableDevicePath
[] =
188 const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress
[] =
190 const char FakeBluetoothDeviceClient::kUnpairableDeviceName
[] =
192 const uint32
FakeBluetoothDeviceClient::kUnpairableDeviceClass
= 0x002540;
194 const char FakeBluetoothDeviceClient::kJustWorksPath
[] =
196 const char FakeBluetoothDeviceClient::kJustWorksAddress
[] =
198 const char FakeBluetoothDeviceClient::kJustWorksName
[] =
200 const uint32
FakeBluetoothDeviceClient::kJustWorksClass
= 0x240428;
202 const char FakeBluetoothDeviceClient::kLowEnergyPath
[] =
204 const char FakeBluetoothDeviceClient::kLowEnergyAddress
[] =
206 const char FakeBluetoothDeviceClient::kLowEnergyName
[] =
207 "Bluetooth 4.0 Heart Rate Monitor";
208 const uint32
FakeBluetoothDeviceClient::kLowEnergyClass
=
209 0x000918; // Major class "Health", Minor class "Heart/Pulse Rate Monitor."
211 const char FakeBluetoothDeviceClient::kPairedUnconnectableDevicePath
[] =
213 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress
[] =
215 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceName
[] =
216 "Paired Unconnectable Device";
217 const uint32
FakeBluetoothDeviceClient::kPairedUnconnectableDeviceClass
=
220 FakeBluetoothDeviceClient::Properties::Properties(
221 const PropertyChangedCallback
& callback
)
222 : BluetoothDeviceClient::Properties(
224 bluetooth_device::kBluetoothDeviceInterface
,
228 FakeBluetoothDeviceClient::Properties::~Properties() {
231 void FakeBluetoothDeviceClient::Properties::Get(
232 dbus::PropertyBase
* property
,
233 dbus::PropertySet::GetCallback callback
) {
234 VLOG(1) << "Get " << property
->name();
238 void FakeBluetoothDeviceClient::Properties::GetAll() {
242 void FakeBluetoothDeviceClient::Properties::Set(
243 dbus::PropertyBase
*property
,
244 dbus::PropertySet::SetCallback callback
) {
245 VLOG(1) << "Set " << property
->name();
246 if (property
->name() == trusted
.name()) {
248 property
->ReplaceValueWithSetValue();
254 FakeBluetoothDeviceClient::IncomingDeviceProperties::
255 IncomingDeviceProperties() {}
257 FakeBluetoothDeviceClient::IncomingDeviceProperties::
258 ~IncomingDeviceProperties() {}
260 FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
261 : simulation_interval_ms_(kSimulationIntervalMs
),
262 discovery_simulation_step_(0),
263 incoming_pairing_simulation_step_(0),
264 pairing_cancelled_(false),
265 connection_rssi_(kUnkownPower
),
266 transmit_power_(kUnkownPower
),
267 max_transmit_power_(kUnkownPower
) {
268 scoped_ptr
<Properties
> properties(new Properties(
269 base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged
,
270 base::Unretained(this), dbus::ObjectPath(kPairedDevicePath
))));
271 properties
->address
.ReplaceValue(kPairedDeviceAddress
);
272 properties
->bluetooth_class
.ReplaceValue(kPairedDeviceClass
);
273 properties
->name
.ReplaceValue("Fake Device (Name)");
274 properties
->alias
.ReplaceValue(kPairedDeviceName
);
275 properties
->paired
.ReplaceValue(true);
276 properties
->trusted
.ReplaceValue(true);
277 properties
->adapter
.ReplaceValue(
278 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
));
280 std::vector
<std::string
> uuids
;
281 uuids
.push_back("00001800-0000-1000-8000-00805f9b34fb");
282 uuids
.push_back("00001801-0000-1000-8000-00805f9b34fb");
283 properties
->uuids
.ReplaceValue(uuids
);
285 properties
->modalias
.ReplaceValue("usb:v05ACp030Dd0306");
287 properties_map_
.insert(dbus::ObjectPath(kPairedDevicePath
),
289 device_list_
.push_back(dbus::ObjectPath(kPairedDevicePath
));
291 properties
.reset(new Properties(base::Bind(
292 &FakeBluetoothDeviceClient::OnPropertyChanged
, base::Unretained(this),
293 dbus::ObjectPath(kPairedUnconnectableDevicePath
))));
294 properties
->address
.ReplaceValue(kPairedUnconnectableDeviceAddress
);
295 properties
->bluetooth_class
.ReplaceValue(kPairedUnconnectableDeviceClass
);
296 properties
->name
.ReplaceValue("Fake Device 2 (Unconnectable)");
297 properties
->alias
.ReplaceValue(kPairedUnconnectableDeviceName
);
298 properties
->paired
.ReplaceValue(true);
299 properties
->trusted
.ReplaceValue(true);
300 properties
->adapter
.ReplaceValue(
301 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
));
303 properties
->uuids
.ReplaceValue(uuids
);
305 properties
->modalias
.ReplaceValue("usb:v05ACp030Dd0306");
307 properties_map_
.insert(dbus::ObjectPath(kPairedUnconnectableDevicePath
),
309 device_list_
.push_back(dbus::ObjectPath(kPairedUnconnectableDevicePath
));
312 FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() {
315 void FakeBluetoothDeviceClient::Init(dbus::Bus
* bus
) {
318 void FakeBluetoothDeviceClient::AddObserver(Observer
* observer
) {
319 observers_
.AddObserver(observer
);
322 void FakeBluetoothDeviceClient::RemoveObserver(Observer
* observer
) {
323 observers_
.RemoveObserver(observer
);
326 std::vector
<dbus::ObjectPath
> FakeBluetoothDeviceClient::GetDevicesForAdapter(
327 const dbus::ObjectPath
& adapter_path
) {
329 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
))
332 return std::vector
<dbus::ObjectPath
>();
335 FakeBluetoothDeviceClient::Properties
*
336 FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath
& object_path
) {
337 PropertiesMap::const_iterator iter
= properties_map_
.find(object_path
);
338 if (iter
!= properties_map_
.end())
343 FakeBluetoothDeviceClient::SimulatedPairingOptions
*
344 FakeBluetoothDeviceClient::GetPairingOptions(
345 const dbus::ObjectPath
& object_path
) {
346 PairingOptionsMap::const_iterator iter
=
347 pairing_options_map_
.find(object_path
);
348 if (iter
!= pairing_options_map_
.end())
350 return iter
!= pairing_options_map_
.end() ? iter
->second
: nullptr;
353 void FakeBluetoothDeviceClient::Connect(
354 const dbus::ObjectPath
& object_path
,
355 const base::Closure
& callback
,
356 const ErrorCallback
& error_callback
) {
357 VLOG(1) << "Connect: " << object_path
.value();
358 Properties
* properties
= GetProperties(object_path
);
360 if (properties
->connected
.value() == true) {
361 // Already connected.
366 if (properties
->paired
.value() != true &&
367 object_path
!= dbus::ObjectPath(kConnectUnpairablePath
) &&
368 object_path
!= dbus::ObjectPath(kLowEnergyPath
)) {
370 error_callback
.Run(bluetooth_device::kErrorFailed
, "Not paired");
372 } else if (properties
->paired
.value() == true &&
373 (object_path
== dbus::ObjectPath(kUnconnectableDevicePath
) ||
375 dbus::ObjectPath(kPairedUnconnectableDevicePath
))) {
376 // Must not be paired
377 error_callback
.Run(bluetooth_device::kErrorFailed
,
378 "Connection fails while paired");
382 // The device can be connected.
383 properties
->connected
.ReplaceValue(true);
386 // Expose GATT services if connected to LE device.
387 if (object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
388 FakeBluetoothGattServiceClient
* gatt_service_client
=
389 static_cast<FakeBluetoothGattServiceClient
*>(
390 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
391 gatt_service_client
->ExposeHeartRateService(
392 dbus::ObjectPath(kLowEnergyPath
));
395 AddInputDeviceIfNeeded(object_path
, properties
);
398 void FakeBluetoothDeviceClient::Disconnect(
399 const dbus::ObjectPath
& object_path
,
400 const base::Closure
& callback
,
401 const ErrorCallback
& error_callback
) {
402 VLOG(1) << "Disconnect: " << object_path
.value();
403 Properties
* properties
= GetProperties(object_path
);
405 if (!properties
->connected
.value()) {
406 error_callback
.Run("org.bluez.Error.NotConnected", "Not Connected");
410 // Hide the Heart Rate Service if disconnected from LE device.
411 if (object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
412 FakeBluetoothGattServiceClient
* gatt_service_client
=
413 static_cast<FakeBluetoothGattServiceClient
*>(
414 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
415 gatt_service_client
->HideHeartRateService();
419 properties
->connected
.ReplaceValue(false);
422 void FakeBluetoothDeviceClient::ConnectProfile(
423 const dbus::ObjectPath
& object_path
,
424 const std::string
& uuid
,
425 const base::Closure
& callback
,
426 const ErrorCallback
& error_callback
) {
427 VLOG(1) << "ConnectProfile: " << object_path
.value() << " " << uuid
;
429 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
430 static_cast<FakeBluetoothProfileManagerClient
*>(
431 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
432 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
433 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(uuid
);
434 if (profile_service_provider
== NULL
) {
435 error_callback
.Run(kNoResponseError
, "Missing profile");
439 if (object_path
== dbus::ObjectPath(kPairedUnconnectableDevicePath
)) {
440 error_callback
.Run(bluetooth_device::kErrorFailed
, "unconnectable");
444 // Make a socket pair of a compatible type with the type used by Bluetooth;
445 // spin up a thread to simulate the server side and wrap the client side in
446 // a D-Bus file descriptor object.
447 int socket_type
= SOCK_STREAM
;
448 if (uuid
== FakeBluetoothProfileManagerClient::kL2capUuid
)
449 socket_type
= SOCK_SEQPACKET
;
452 if (socketpair(AF_UNIX
, socket_type
, 0, fds
) < 0) {
453 error_callback
.Run(kNoResponseError
, "socketpair call failed");
458 args
= fcntl(fds
[1], F_GETFL
, NULL
);
460 error_callback
.Run(kNoResponseError
, "failed to get socket flags");
465 if (fcntl(fds
[1], F_SETFL
, args
) < 0) {
466 error_callback
.Run(kNoResponseError
, "failed to set socket non-blocking");
470 base::WorkerPool::GetTaskRunner(false)->PostTask(
472 base::Bind(&SimulatedProfileSocket
,
475 scoped_ptr
<dbus::FileDescriptor
> fd(new dbus::FileDescriptor(fds
[1]));
477 // Post the new connection to the service provider.
478 BluetoothProfileServiceProvider::Delegate::Options options
;
480 profile_service_provider
->NewConnection(
484 base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback
,
485 base::Unretained(this),
491 void FakeBluetoothDeviceClient::DisconnectProfile(
492 const dbus::ObjectPath
& object_path
,
493 const std::string
& uuid
,
494 const base::Closure
& callback
,
495 const ErrorCallback
& error_callback
) {
496 VLOG(1) << "DisconnectProfile: " << object_path
.value() << " " << uuid
;
498 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
499 static_cast<FakeBluetoothProfileManagerClient
*>(
500 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
501 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
502 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(uuid
);
503 if (profile_service_provider
== NULL
) {
504 error_callback
.Run(kNoResponseError
, "Missing profile");
508 profile_service_provider
->RequestDisconnection(
510 base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback
,
511 base::Unretained(this),
517 void FakeBluetoothDeviceClient::Pair(
518 const dbus::ObjectPath
& object_path
,
519 const base::Closure
& callback
,
520 const ErrorCallback
& error_callback
) {
521 VLOG(1) << "Pair: " << object_path
.value();
522 Properties
* properties
= GetProperties(object_path
);
524 if (properties
->paired
.value() == true) {
530 SimulatePairing(object_path
, false, callback
, error_callback
);
533 void FakeBluetoothDeviceClient::CancelPairing(
534 const dbus::ObjectPath
& object_path
,
535 const base::Closure
& callback
,
536 const ErrorCallback
& error_callback
) {
537 VLOG(1) << "CancelPairing: " << object_path
.value();
538 pairing_cancelled_
= true;
542 void FakeBluetoothDeviceClient::GetConnInfo(
543 const dbus::ObjectPath
& object_path
,
544 const ConnInfoCallback
& callback
,
545 const ErrorCallback
& error_callback
) {
546 Properties
* properties
= GetProperties(object_path
);
547 if (!properties
->connected
.value()) {
548 error_callback
.Run("org.bluez.Error.NotConnected", "Not Connected");
552 callback
.Run(connection_rssi_
, transmit_power_
, max_transmit_power_
);
555 void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
556 const dbus::ObjectPath
& adapter_path
) {
557 VLOG(1) << "starting discovery simulation";
559 discovery_simulation_step_
= 1;
561 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
563 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer
,
564 base::Unretained(this)),
565 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
568 void FakeBluetoothDeviceClient::EndDiscoverySimulation(
569 const dbus::ObjectPath
& adapter_path
) {
570 VLOG(1) << "stopping discovery simulation";
571 discovery_simulation_step_
= 0;
574 void FakeBluetoothDeviceClient::BeginIncomingPairingSimulation(
575 const dbus::ObjectPath
& adapter_path
) {
576 VLOG(1) << "starting incoming pairing simulation";
578 incoming_pairing_simulation_step_
= 1;
580 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
582 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer
,
583 base::Unretained(this)),
584 base::TimeDelta::FromMilliseconds(
585 kIncomingSimulationStartPairTimeMultiplier
*
586 simulation_interval_ms_
));
589 void FakeBluetoothDeviceClient::EndIncomingPairingSimulation(
590 const dbus::ObjectPath
& adapter_path
) {
591 VLOG(1) << "stopping incoming pairing simulation";
592 incoming_pairing_simulation_step_
= 0;
595 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms
) {
596 simulation_interval_ms_
= interval_ms
;
599 void FakeBluetoothDeviceClient::CreateDevice(
600 const dbus::ObjectPath
& adapter_path
,
601 const dbus::ObjectPath
& device_path
) {
602 if (std::find(device_list_
.begin(),
603 device_list_
.end(), device_path
) != device_list_
.end())
606 scoped_ptr
<Properties
> properties(
607 new Properties(base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged
,
608 base::Unretained(this), device_path
)));
609 properties
->adapter
.ReplaceValue(adapter_path
);
611 if (device_path
== dbus::ObjectPath(kLegacyAutopairPath
)) {
612 properties
->address
.ReplaceValue(kLegacyAutopairAddress
);
613 properties
->bluetooth_class
.ReplaceValue(kLegacyAutopairClass
);
614 properties
->name
.ReplaceValue("LegacyAutopair");
615 properties
->alias
.ReplaceValue(kLegacyAutopairName
);
617 std::vector
<std::string
> uuids
;
618 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
619 properties
->uuids
.ReplaceValue(uuids
);
621 } else if (device_path
== dbus::ObjectPath(kDisplayPinCodePath
)) {
622 properties
->address
.ReplaceValue(kDisplayPinCodeAddress
);
623 properties
->bluetooth_class
.ReplaceValue(kDisplayPinCodeClass
);
624 properties
->name
.ReplaceValue("DisplayPinCode");
625 properties
->alias
.ReplaceValue(kDisplayPinCodeName
);
627 std::vector
<std::string
> uuids
;
628 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
629 properties
->uuids
.ReplaceValue(uuids
);
631 } else if (device_path
== dbus::ObjectPath(kVanishingDevicePath
)) {
632 properties
->address
.ReplaceValue(kVanishingDeviceAddress
);
633 properties
->bluetooth_class
.ReplaceValue(kVanishingDeviceClass
);
634 properties
->name
.ReplaceValue("VanishingDevice");
635 properties
->alias
.ReplaceValue(kVanishingDeviceName
);
637 } else if (device_path
== dbus::ObjectPath(kConnectUnpairablePath
)) {
638 properties
->address
.ReplaceValue(kConnectUnpairableAddress
);
639 properties
->bluetooth_class
.ReplaceValue(kConnectUnpairableClass
);
640 properties
->name
.ReplaceValue("ConnectUnpairable");
641 properties
->alias
.ReplaceValue(kConnectUnpairableName
);
643 std::vector
<std::string
> uuids
;
644 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
645 properties
->uuids
.ReplaceValue(uuids
);
647 } else if (device_path
== dbus::ObjectPath(kDisplayPasskeyPath
)) {
648 properties
->address
.ReplaceValue(kDisplayPasskeyAddress
);
649 properties
->bluetooth_class
.ReplaceValue(kDisplayPasskeyClass
);
650 properties
->name
.ReplaceValue("DisplayPasskey");
651 properties
->alias
.ReplaceValue(kDisplayPasskeyName
);
653 std::vector
<std::string
> uuids
;
654 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
655 properties
->uuids
.ReplaceValue(uuids
);
657 } else if (device_path
== dbus::ObjectPath(kRequestPinCodePath
)) {
658 properties
->address
.ReplaceValue(kRequestPinCodeAddress
);
659 properties
->bluetooth_class
.ReplaceValue(kRequestPinCodeClass
);
660 properties
->name
.ReplaceValue("RequestPinCode");
661 properties
->alias
.ReplaceValue(kRequestPinCodeName
);
663 } else if (device_path
== dbus::ObjectPath(kConfirmPasskeyPath
)) {
664 properties
->address
.ReplaceValue(kConfirmPasskeyAddress
);
665 properties
->bluetooth_class
.ReplaceValue(kConfirmPasskeyClass
);
666 properties
->name
.ReplaceValue("ConfirmPasskey");
667 properties
->alias
.ReplaceValue(kConfirmPasskeyName
);
669 } else if (device_path
== dbus::ObjectPath(kRequestPasskeyPath
)) {
670 properties
->address
.ReplaceValue(kRequestPasskeyAddress
);
671 properties
->bluetooth_class
.ReplaceValue(kRequestPasskeyClass
);
672 properties
->name
.ReplaceValue("RequestPasskey");
673 properties
->alias
.ReplaceValue(kRequestPasskeyName
);
675 } else if (device_path
== dbus::ObjectPath(kUnconnectableDevicePath
)) {
676 properties
->address
.ReplaceValue(kUnconnectableDeviceAddress
);
677 properties
->bluetooth_class
.ReplaceValue(kUnconnectableDeviceClass
);
678 properties
->name
.ReplaceValue("UnconnectableDevice");
679 properties
->alias
.ReplaceValue(kUnconnectableDeviceName
);
681 } else if (device_path
== dbus::ObjectPath(kUnpairableDevicePath
)) {
682 properties
->address
.ReplaceValue(kUnpairableDeviceAddress
);
683 properties
->bluetooth_class
.ReplaceValue(kUnpairableDeviceClass
);
684 properties
->name
.ReplaceValue("Fake Unpairable Device");
685 properties
->alias
.ReplaceValue(kUnpairableDeviceName
);
687 } else if (device_path
== dbus::ObjectPath(kJustWorksPath
)) {
688 properties
->address
.ReplaceValue(kJustWorksAddress
);
689 properties
->bluetooth_class
.ReplaceValue(kJustWorksClass
);
690 properties
->name
.ReplaceValue("JustWorks");
691 properties
->alias
.ReplaceValue(kJustWorksName
);
693 } else if (device_path
== dbus::ObjectPath(kLowEnergyPath
)) {
694 properties
->address
.ReplaceValue(kLowEnergyAddress
);
695 properties
->bluetooth_class
.ReplaceValue(kLowEnergyClass
);
696 properties
->name
.ReplaceValue("Heart Rate Monitor");
697 properties
->alias
.ReplaceValue(kLowEnergyName
);
699 std::vector
<std::string
> uuids
;
700 uuids
.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
);
701 properties
->uuids
.ReplaceValue(uuids
);
708 properties_map_
.insert(device_path
, properties
.Pass());
709 device_list_
.push_back(device_path
);
710 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
711 DeviceAdded(device_path
));
714 void FakeBluetoothDeviceClient::CreateDeviceWithProperties(
715 const dbus::ObjectPath
& adapter_path
,
716 const IncomingDeviceProperties
& props
) {
717 dbus::ObjectPath
device_path(props
.device_path
);
718 if (std::find(device_list_
.begin(), device_list_
.end(), device_path
) !=
722 scoped_ptr
<Properties
> properties(
723 new Properties(base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged
,
724 base::Unretained(this), device_path
)));
725 properties
->adapter
.ReplaceValue(adapter_path
);
726 properties
->name
.ReplaceValue(props
.device_name
);
727 properties
->alias
.ReplaceValue(props
.device_alias
);
728 properties
->address
.ReplaceValue(props
.device_address
);
729 properties
->bluetooth_class
.ReplaceValue(props
.device_class
);
730 properties
->trusted
.ReplaceValue(props
.is_trusted
);
732 if (props
.is_trusted
)
733 properties
->paired
.ReplaceValue(true);
735 scoped_ptr
<SimulatedPairingOptions
> options(new SimulatedPairingOptions
);
736 options
->pairing_method
= props
.pairing_method
;
737 options
->pairing_auth_token
= props
.pairing_auth_token
;
739 properties_map_
.insert(device_path
, properties
.Pass());
740 device_list_
.push_back(device_path
);
741 pairing_options_map_
.insert(device_path
, options
.Pass());
742 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
743 DeviceAdded(device_path
));
746 void FakeBluetoothDeviceClient::RemoveDevice(
747 const dbus::ObjectPath
& adapter_path
,
748 const dbus::ObjectPath
& device_path
) {
749 std::vector
<dbus::ObjectPath
>::iterator listiter
=
750 std::find(device_list_
.begin(), device_list_
.end(), device_path
);
751 if (listiter
== device_list_
.end())
754 PropertiesMap::const_iterator iter
= properties_map_
.find(device_path
);
755 Properties
* properties
= iter
->second
;
757 VLOG(1) << "removing device: " << properties
->alias
.value();
758 device_list_
.erase(listiter
);
760 // Remove the Input interface if it exists. This should be called before the
761 // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
762 // BluetoothDeviceChromeOS object, including the device_path referenced here.
763 FakeBluetoothInputClient
* fake_bluetooth_input_client
=
764 static_cast<FakeBluetoothInputClient
*>(
765 DBusThreadManager::Get()->GetBluetoothInputClient());
766 fake_bluetooth_input_client
->RemoveInputDevice(device_path
);
768 if (device_path
== dbus::ObjectPath(kLowEnergyPath
)) {
769 FakeBluetoothGattServiceClient
* gatt_service_client
=
770 static_cast<FakeBluetoothGattServiceClient
*>(
771 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
772 gatt_service_client
->HideHeartRateService();
775 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
776 DeviceRemoved(device_path
));
778 properties_map_
.erase(iter
);
779 PairingOptionsMap::const_iterator options_iter
=
780 pairing_options_map_
.find(device_path
);
782 if (options_iter
!= pairing_options_map_
.end()) {
783 pairing_options_map_
.erase(options_iter
);
787 void FakeBluetoothDeviceClient::OnPropertyChanged(
788 const dbus::ObjectPath
& object_path
,
789 const std::string
& property_name
) {
790 VLOG(2) << "Fake Bluetooth device property changed: " << object_path
.value()
791 << ": " << property_name
;
792 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
793 DevicePropertyChanged(object_path
, property_name
));
796 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
797 if (!discovery_simulation_step_
)
800 // Timer fires every .75s, the numbers below are arbitrary to give a feel
801 // for a discovery process.
802 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_
;
803 if (discovery_simulation_step_
== 2) {
804 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
805 dbus::ObjectPath(kLegacyAutopairPath
));
806 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
807 dbus::ObjectPath(kLowEnergyPath
));
809 } else if (discovery_simulation_step_
== 4) {
810 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
811 base::RandInt(kMinRSSI
, kMaxRSSI
));
812 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
813 dbus::ObjectPath(kDisplayPinCodePath
));
814 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
815 dbus::ObjectPath(kVanishingDevicePath
));
817 } else if (discovery_simulation_step_
== 7) {
818 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
819 dbus::ObjectPath(kConnectUnpairablePath
));
820 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
821 base::RandInt(kMinRSSI
, kMaxRSSI
));
823 } else if (discovery_simulation_step_
== 8) {
824 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
825 dbus::ObjectPath(kDisplayPasskeyPath
));
826 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
827 dbus::ObjectPath(kRequestPinCodePath
));
828 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
829 base::RandInt(kMinRSSI
, kMaxRSSI
));
831 } else if (discovery_simulation_step_
== 10) {
832 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
833 dbus::ObjectPath(kConfirmPasskeyPath
));
834 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
835 dbus::ObjectPath(kRequestPasskeyPath
));
836 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
837 dbus::ObjectPath(kUnconnectableDevicePath
));
838 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
839 dbus::ObjectPath(kUnpairableDevicePath
));
840 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
841 dbus::ObjectPath(kJustWorksPath
));
842 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
843 base::RandInt(kMinRSSI
, kMaxRSSI
));
845 } else if (discovery_simulation_step_
== 13) {
846 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
847 base::RandInt(kMinRSSI
, kMaxRSSI
));
848 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
849 dbus::ObjectPath(kVanishingDevicePath
));
850 } else if (discovery_simulation_step_
== 14) {
851 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
852 base::RandInt(kMinRSSI
, kMaxRSSI
));
857 ++discovery_simulation_step_
;
858 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
860 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer
,
861 base::Unretained(this)),
862 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
865 void FakeBluetoothDeviceClient::IncomingPairingSimulationTimer() {
866 if (!incoming_pairing_simulation_step_
)
869 VLOG(1) << "incoming pairing simulation, step "
870 << incoming_pairing_simulation_step_
;
871 switch (incoming_pairing_simulation_step_
) {
873 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
874 dbus::ObjectPath(kConfirmPasskeyPath
));
875 SimulatePairing(dbus::ObjectPath(kConfirmPasskeyPath
), true,
876 base::Bind(&base::DoNothing
),
877 base::Bind(&SimpleErrorCallback
));
880 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
881 dbus::ObjectPath(kJustWorksPath
));
882 SimulatePairing(dbus::ObjectPath(kJustWorksPath
), true,
883 base::Bind(&base::DoNothing
),
884 base::Bind(&SimpleErrorCallback
));
887 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
888 dbus::ObjectPath(kDisplayPinCodePath
));
889 SimulatePairing(dbus::ObjectPath(kDisplayPinCodePath
), true,
890 base::Bind(&base::DoNothing
),
891 base::Bind(&SimpleErrorCallback
));
894 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
895 dbus::ObjectPath(kDisplayPasskeyPath
));
896 SimulatePairing(dbus::ObjectPath(kDisplayPasskeyPath
), true,
897 base::Bind(&base::DoNothing
),
898 base::Bind(&SimpleErrorCallback
));
901 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
902 dbus::ObjectPath(kRequestPinCodePath
));
903 SimulatePairing(dbus::ObjectPath(kRequestPinCodePath
), true,
904 base::Bind(&base::DoNothing
),
905 base::Bind(&SimpleErrorCallback
));
908 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
909 dbus::ObjectPath(kRequestPasskeyPath
));
910 SimulatePairing(dbus::ObjectPath(kRequestPasskeyPath
), true,
911 base::Bind(&base::DoNothing
),
912 base::Bind(&SimpleErrorCallback
));
918 ++incoming_pairing_simulation_step_
;
919 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
921 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer
,
922 base::Unretained(this)),
923 base::TimeDelta::FromMilliseconds(kIncomingSimulationPairTimeMultiplier
*
924 simulation_interval_ms_
));
927 void FakeBluetoothDeviceClient::SimulatePairing(
928 const dbus::ObjectPath
& object_path
,
929 bool incoming_request
,
930 const base::Closure
& callback
,
931 const ErrorCallback
& error_callback
) {
932 pairing_cancelled_
= false;
934 FakeBluetoothAgentManagerClient
* fake_bluetooth_agent_manager_client
=
935 static_cast<FakeBluetoothAgentManagerClient
*>(
936 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
937 FakeBluetoothAgentServiceProvider
* agent_service_provider
=
938 fake_bluetooth_agent_manager_client
->GetAgentServiceProvider();
939 CHECK(agent_service_provider
!= NULL
);
941 // Grab the device's pairing properties.
942 PairingOptionsMap::const_iterator iter
=
943 pairing_options_map_
.find(object_path
);
945 // If the device with path |object_path| has simulated pairing properties
946 // defined, then pair it based on its |pairing_method|.
947 if (iter
!= pairing_options_map_
.end()) {
948 if (iter
->second
->pairing_method
== kPairingMethodNone
||
949 iter
->second
->pairing_method
.empty()) {
950 // Simply pair and connect the device.
951 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
953 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
954 base::Unretained(this), object_path
, callback
,
956 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier
*
957 simulation_interval_ms_
));
958 } else if (iter
->second
->pairing_method
== kPairingMethodPinCode
) {
959 // Display a Pincode, and wait before acting as if the other end accepted
961 agent_service_provider
->DisplayPinCode(object_path
,
962 iter
->second
->pairing_auth_token
);
964 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
966 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
967 base::Unretained(this), object_path
, callback
,
969 base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier
*
970 simulation_interval_ms_
));
971 } else if (iter
->second
->pairing_method
== kPairingMethodPassKey
) {
972 // Display a passkey, and each interval act as if another key was entered
974 agent_service_provider
->DisplayPasskey(
975 object_path
, std::stoi(iter
->second
->pairing_auth_token
), 0);
977 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
978 FROM_HERE
, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress
,
979 base::Unretained(this), 1, object_path
,
980 callback
, error_callback
),
981 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
984 if (object_path
== dbus::ObjectPath(kLegacyAutopairPath
) ||
985 object_path
== dbus::ObjectPath(kConnectUnpairablePath
) ||
986 object_path
== dbus::ObjectPath(kUnconnectableDevicePath
) ||
987 object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
988 // No need to call anything on the pairing delegate, just wait 3 times
989 // the interval before acting as if the other end accepted it.
990 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
992 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
993 base::Unretained(this), object_path
, callback
,
995 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier
*
996 simulation_interval_ms_
));
998 } else if (object_path
== dbus::ObjectPath(kDisplayPinCodePath
)) {
999 // Display a Pincode, and wait before acting as if the other end accepted
1001 agent_service_provider
->DisplayPinCode(object_path
, kTestPinCode
);
1003 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1005 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1006 base::Unretained(this), object_path
, callback
,
1008 base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier
*
1009 simulation_interval_ms_
));
1011 } else if (object_path
== dbus::ObjectPath(kVanishingDevicePath
)) {
1012 // The vanishing device simulates being too far away, and thus times out.
1013 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1015 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing
,
1016 base::Unretained(this), object_path
, error_callback
),
1017 base::TimeDelta::FromMilliseconds(kVanishingDevicePairTimeMultiplier
*
1018 simulation_interval_ms_
));
1020 } else if (object_path
== dbus::ObjectPath(kDisplayPasskeyPath
)) {
1021 // Display a passkey, and each interval act as if another key was entered
1023 agent_service_provider
->DisplayPasskey(object_path
, kTestPassKey
, 0);
1025 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1026 FROM_HERE
, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress
,
1027 base::Unretained(this), 1, object_path
,
1028 callback
, error_callback
),
1029 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1031 } else if (object_path
== dbus::ObjectPath(kRequestPinCodePath
)) {
1032 // Request a Pincode.
1033 agent_service_provider
->RequestPinCode(
1034 object_path
, base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback
,
1035 base::Unretained(this), object_path
, callback
,
1038 } else if (object_path
== dbus::ObjectPath(kConfirmPasskeyPath
)) {
1039 // Request confirmation of a Passkey.
1040 agent_service_provider
->RequestConfirmation(
1041 object_path
, kTestPassKey
,
1042 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback
,
1043 base::Unretained(this), object_path
, callback
,
1046 } else if (object_path
== dbus::ObjectPath(kRequestPasskeyPath
)) {
1047 // Request a Passkey from the user.
1048 agent_service_provider
->RequestPasskey(
1049 object_path
, base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback
,
1050 base::Unretained(this), object_path
, callback
,
1053 } else if (object_path
== dbus::ObjectPath(kUnpairableDevicePath
)) {
1054 // Fails the pairing with an org.bluez.Error.Failed error.
1055 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1057 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing
,
1058 base::Unretained(this), object_path
, error_callback
),
1059 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1061 } else if (object_path
== dbus::ObjectPath(kJustWorksPath
)) {
1062 if (incoming_request
) {
1063 agent_service_provider
->RequestAuthorization(
1065 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback
,
1066 base::Unretained(this), object_path
, callback
,
1070 // No need to call anything on the pairing delegate, just wait before
1071 // acting as if the other end accepted it.
1072 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1074 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1075 base::Unretained(this), object_path
, callback
,
1077 base::TimeDelta::FromMilliseconds(
1078 kSimulateNormalPairTimeMultiplier
* simulation_interval_ms_
));
1082 error_callback
.Run(kNoResponseError
, "No pairing fake");
1087 void FakeBluetoothDeviceClient::CompleteSimulatedPairing(
1088 const dbus::ObjectPath
& object_path
,
1089 const base::Closure
& callback
,
1090 const ErrorCallback
& error_callback
) {
1091 VLOG(1) << "CompleteSimulatedPairing: " << object_path
.value();
1092 if (pairing_cancelled_
) {
1093 pairing_cancelled_
= false;
1095 error_callback
.Run(bluetooth_device::kErrorAuthenticationCanceled
,
1098 Properties
* properties
= GetProperties(object_path
);
1100 properties
->paired
.ReplaceValue(true);
1103 AddInputDeviceIfNeeded(object_path
, properties
);
1107 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing(
1108 const dbus::ObjectPath
& object_path
,
1109 const ErrorCallback
& error_callback
) {
1110 VLOG(1) << "TimeoutSimulatedPairing: " << object_path
.value();
1112 error_callback
.Run(bluetooth_device::kErrorAuthenticationTimeout
,
1116 void FakeBluetoothDeviceClient::CancelSimulatedPairing(
1117 const dbus::ObjectPath
& object_path
,
1118 const ErrorCallback
& error_callback
) {
1119 VLOG(1) << "CancelSimulatedPairing: " << object_path
.value();
1121 error_callback
.Run(bluetooth_device::kErrorAuthenticationCanceled
,
1125 void FakeBluetoothDeviceClient::RejectSimulatedPairing(
1126 const dbus::ObjectPath
& object_path
,
1127 const ErrorCallback
& error_callback
) {
1128 VLOG(1) << "RejectSimulatedPairing: " << object_path
.value();
1130 error_callback
.Run(bluetooth_device::kErrorAuthenticationRejected
,
1134 void FakeBluetoothDeviceClient::FailSimulatedPairing(
1135 const dbus::ObjectPath
& object_path
,
1136 const ErrorCallback
& error_callback
) {
1137 VLOG(1) << "FailSimulatedPairing: " << object_path
.value();
1139 error_callback
.Run(bluetooth_device::kErrorFailed
, "Failed");
1142 void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded(
1143 const dbus::ObjectPath
& object_path
,
1144 Properties
* properties
) {
1145 // If the paired device is a HID device based on it's bluetooth class,
1146 // simulate the Input interface.
1147 FakeBluetoothInputClient
* fake_bluetooth_input_client
=
1148 static_cast<FakeBluetoothInputClient
*>(
1149 DBusThreadManager::Get()->GetBluetoothInputClient());
1151 if ((properties
->bluetooth_class
.value() & 0x001f03) == 0x000500)
1152 fake_bluetooth_input_client
->AddInputDevice(object_path
);
1155 void FakeBluetoothDeviceClient::UpdateDeviceRSSI(
1156 const dbus::ObjectPath
& object_path
,
1158 PropertiesMap::const_iterator iter
= properties_map_
.find(object_path
);
1159 if (iter
== properties_map_
.end()) {
1160 VLOG(2) << "Fake device does not exist: " << object_path
.value();
1163 Properties
* properties
= iter
->second
;
1165 properties
->rssi
.ReplaceValue(rssi
);
1168 void FakeBluetoothDeviceClient::UpdateConnectionInfo(
1169 uint16 connection_rssi
,
1170 uint16 transmit_power
,
1171 uint16 max_transmit_power
) {
1172 connection_rssi_
= connection_rssi
;
1173 transmit_power_
= transmit_power
;
1174 max_transmit_power_
= max_transmit_power
;
1177 void FakeBluetoothDeviceClient::PinCodeCallback(
1178 const dbus::ObjectPath
& object_path
,
1179 const base::Closure
& callback
,
1180 const ErrorCallback
& error_callback
,
1181 BluetoothAgentServiceProvider::Delegate::Status status
,
1182 const std::string
& pincode
) {
1183 VLOG(1) << "PinCodeCallback: " << object_path
.value();
1185 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1186 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1188 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1189 base::Unretained(this), object_path
, callback
,
1191 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier
*
1192 simulation_interval_ms_
));
1194 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1195 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1197 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1198 base::Unretained(this), object_path
, error_callback
),
1199 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1201 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1202 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1204 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1205 base::Unretained(this), object_path
, error_callback
),
1206 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1210 void FakeBluetoothDeviceClient::PasskeyCallback(
1211 const dbus::ObjectPath
& object_path
,
1212 const base::Closure
& callback
,
1213 const ErrorCallback
& error_callback
,
1214 BluetoothAgentServiceProvider::Delegate::Status status
,
1216 VLOG(1) << "PasskeyCallback: " << object_path
.value();
1218 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1219 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1221 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1222 base::Unretained(this), object_path
, callback
,
1224 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier
*
1225 simulation_interval_ms_
));
1227 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1228 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1230 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1231 base::Unretained(this), object_path
, error_callback
),
1232 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1234 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1235 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1237 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1238 base::Unretained(this), object_path
, error_callback
),
1239 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1243 void FakeBluetoothDeviceClient::ConfirmationCallback(
1244 const dbus::ObjectPath
& object_path
,
1245 const base::Closure
& callback
,
1246 const ErrorCallback
& error_callback
,
1247 BluetoothAgentServiceProvider::Delegate::Status status
) {
1248 VLOG(1) << "ConfirmationCallback: " << object_path
.value();
1250 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1251 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1253 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1254 base::Unretained(this), object_path
, callback
,
1256 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier
*
1257 simulation_interval_ms_
));
1259 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1260 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1262 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1263 base::Unretained(this), object_path
, error_callback
),
1264 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1266 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1267 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1269 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1270 base::Unretained(this), object_path
, error_callback
),
1271 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1275 void FakeBluetoothDeviceClient::SimulateKeypress(
1277 const dbus::ObjectPath
& object_path
,
1278 const base::Closure
& callback
,
1279 const ErrorCallback
& error_callback
) {
1280 VLOG(1) << "SimulateKeypress " << entered
<< ": " << object_path
.value();
1282 FakeBluetoothAgentManagerClient
* fake_bluetooth_agent_manager_client
=
1283 static_cast<FakeBluetoothAgentManagerClient
*>(
1284 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
1285 FakeBluetoothAgentServiceProvider
* agent_service_provider
=
1286 fake_bluetooth_agent_manager_client
->GetAgentServiceProvider();
1288 // The agent service provider object could have been destroyed after the
1289 // pairing is canceled.
1290 if (!agent_service_provider
)
1293 agent_service_provider
->DisplayPasskey(object_path
, kTestPassKey
, entered
);
1296 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1297 FROM_HERE
, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress
,
1298 base::Unretained(this), entered
+ 1, object_path
,
1299 callback
, error_callback
),
1300 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1303 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1305 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1306 base::Unretained(this), object_path
, callback
,
1308 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1312 void FakeBluetoothDeviceClient::ConnectionCallback(
1313 const dbus::ObjectPath
& object_path
,
1314 const base::Closure
& callback
,
1315 const ErrorCallback
& error_callback
,
1316 BluetoothProfileServiceProvider::Delegate::Status status
) {
1317 VLOG(1) << "ConnectionCallback: " << object_path
.value();
1319 if (status
== BluetoothProfileServiceProvider::Delegate::SUCCESS
) {
1321 } else if (status
== BluetoothProfileServiceProvider::Delegate::CANCELLED
) {
1322 // TODO(keybuk): tear down this side of the connection
1323 error_callback
.Run(bluetooth_device::kErrorFailed
, "Canceled");
1324 } else if (status
== BluetoothProfileServiceProvider::Delegate::REJECTED
) {
1325 // TODO(keybuk): tear down this side of the connection
1326 error_callback
.Run(bluetooth_device::kErrorFailed
, "Rejected");
1330 void FakeBluetoothDeviceClient::DisconnectionCallback(
1331 const dbus::ObjectPath
& object_path
,
1332 const base::Closure
& callback
,
1333 const ErrorCallback
& error_callback
,
1334 BluetoothProfileServiceProvider::Delegate::Status status
) {
1335 VLOG(1) << "DisconnectionCallback: " << object_path
.value();
1337 if (status
== BluetoothProfileServiceProvider::Delegate::SUCCESS
) {
1338 // TODO(keybuk): tear down this side of the connection
1340 } else if (status
== BluetoothProfileServiceProvider::Delegate::CANCELLED
) {
1341 error_callback
.Run(bluetooth_device::kErrorFailed
, "Canceled");
1342 } else if (status
== BluetoothProfileServiceProvider::Delegate::REJECTED
) {
1343 error_callback
.Run(bluetooth_device::kErrorFailed
, "Rejected");
1347 } // namespace chromeos