1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/dbus/fake_bluetooth_device_client.h"
10 #include <sys/socket.h>
16 #include "base/logging.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/rand_util.h"
20 #include "base/stl_util.h"
21 #include "base/threading/worker_pool.h"
22 #include "base/time/time.h"
23 #include "chromeos/dbus/dbus_thread_manager.h"
24 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
25 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
26 #include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
27 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
28 #include "chromeos/dbus/fake_bluetooth_input_client.h"
29 #include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
30 #include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
31 #include "dbus/file_descriptor.h"
32 #include "third_party/cros_system_api/dbus/service_constants.h"
36 // Default interval between simulated events.
37 const int kSimulationIntervalMs
= 750;
39 // Minimum and maximum bounds for randomly generated RSSI values.
40 const int kMinRSSI
= -90;
41 const int kMaxRSSI
= -30;
43 // The default value of connection info properties from GetConnInfo().
44 const int kUnkownPower
= 127;
47 void SimulatedProfileSocket(int fd
) {
48 // Simulate a server-side socket of a profile; read data from the socket,
49 // write it back, and then close.
54 len
= read(fd
, buf
, sizeof buf
);
61 len
= write(fd
, buf
, count
);
70 void SimpleErrorCallback(const std::string
& error_name
,
71 const std::string
& error_message
) {
72 VLOG(1) << "Bluetooth Error: " << error_name
<< ": " << error_message
;
79 const char FakeBluetoothDeviceClient::kPairedDevicePath
[] =
81 const char FakeBluetoothDeviceClient::kPairedDeviceAddress
[] =
83 const char FakeBluetoothDeviceClient::kPairedDeviceName
[] =
85 const uint32
FakeBluetoothDeviceClient::kPairedDeviceClass
= 0x000104;
87 const char FakeBluetoothDeviceClient::kLegacyAutopairPath
[] =
89 const char FakeBluetoothDeviceClient::kLegacyAutopairAddress
[] =
91 const char FakeBluetoothDeviceClient::kLegacyAutopairName
[] =
92 "Bluetooth 2.0 Mouse";
93 const uint32
FakeBluetoothDeviceClient::kLegacyAutopairClass
= 0x002580;
95 const char FakeBluetoothDeviceClient::kDisplayPinCodePath
[] =
97 const char FakeBluetoothDeviceClient::kDisplayPinCodeAddress
[] =
99 const char FakeBluetoothDeviceClient::kDisplayPinCodeName
[] =
100 "Bluetooth 2.0 Keyboard";
101 const uint32
FakeBluetoothDeviceClient::kDisplayPinCodeClass
= 0x002540;
103 const char FakeBluetoothDeviceClient::kVanishingDevicePath
[] =
105 const char FakeBluetoothDeviceClient::kVanishingDeviceAddress
[] =
107 const char FakeBluetoothDeviceClient::kVanishingDeviceName
[] =
109 const uint32
FakeBluetoothDeviceClient::kVanishingDeviceClass
= 0x000104;
111 const char FakeBluetoothDeviceClient::kConnectUnpairablePath
[] =
113 const char FakeBluetoothDeviceClient::kConnectUnpairableAddress
[] =
115 const char FakeBluetoothDeviceClient::kConnectUnpairableName
[] =
117 const uint32
FakeBluetoothDeviceClient::kConnectUnpairableClass
= 0x002580;
119 const char FakeBluetoothDeviceClient::kDisplayPasskeyPath
[] =
121 const char FakeBluetoothDeviceClient::kDisplayPasskeyAddress
[] =
123 const char FakeBluetoothDeviceClient::kDisplayPasskeyName
[] =
124 "Bluetooth 2.1+ Keyboard";
125 const uint32
FakeBluetoothDeviceClient::kDisplayPasskeyClass
= 0x002540;
127 const char FakeBluetoothDeviceClient::kRequestPinCodePath
[] =
129 const char FakeBluetoothDeviceClient::kRequestPinCodeAddress
[] =
131 const char FakeBluetoothDeviceClient::kRequestPinCodeName
[] =
133 const uint32
FakeBluetoothDeviceClient::kRequestPinCodeClass
= 0x240408;
135 const char FakeBluetoothDeviceClient::kConfirmPasskeyPath
[] =
137 const char FakeBluetoothDeviceClient::kConfirmPasskeyAddress
[] =
139 const char FakeBluetoothDeviceClient::kConfirmPasskeyName
[] =
141 const uint32
FakeBluetoothDeviceClient::kConfirmPasskeyClass
= 0x7a020c;
143 const char FakeBluetoothDeviceClient::kRequestPasskeyPath
[] =
145 const char FakeBluetoothDeviceClient::kRequestPasskeyAddress
[] =
147 const char FakeBluetoothDeviceClient::kRequestPasskeyName
[] =
149 const uint32
FakeBluetoothDeviceClient::kRequestPasskeyClass
= 0x7a020c;
151 const char FakeBluetoothDeviceClient::kUnconnectableDevicePath
[] =
153 const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress
[] =
155 const char FakeBluetoothDeviceClient::kUnconnectableDeviceName
[] =
156 "Unconnectable Device";
157 const uint32
FakeBluetoothDeviceClient::kUnconnectableDeviceClass
= 0x7a020c;
159 const char FakeBluetoothDeviceClient::kUnpairableDevicePath
[] =
161 const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress
[] =
163 const char FakeBluetoothDeviceClient::kUnpairableDeviceName
[] =
165 const uint32
FakeBluetoothDeviceClient::kUnpairableDeviceClass
= 0x002540;
167 const char FakeBluetoothDeviceClient::kJustWorksPath
[] =
169 const char FakeBluetoothDeviceClient::kJustWorksAddress
[] =
171 const char FakeBluetoothDeviceClient::kJustWorksName
[] =
173 const uint32
FakeBluetoothDeviceClient::kJustWorksClass
= 0x240428;
175 const char FakeBluetoothDeviceClient::kLowEnergyPath
[] =
177 const char FakeBluetoothDeviceClient::kLowEnergyAddress
[] =
179 const char FakeBluetoothDeviceClient::kLowEnergyName
[] =
180 "Bluetooth 4.0 Heart Rate Monitor";
181 const uint32
FakeBluetoothDeviceClient::kLowEnergyClass
=
182 0x000918; // Major class "Health", Minor class "Heart/Pulse Rate Monitor."
184 const char FakeBluetoothDeviceClient::kPairedUnconnectableDevicePath
[] =
186 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress
[] =
188 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceName
[] =
189 "Paired Unconnectable Device";
190 const uint32
FakeBluetoothDeviceClient::kPairedUnconnectableDeviceClass
=
193 FakeBluetoothDeviceClient::Properties::Properties(
194 const PropertyChangedCallback
& callback
)
195 : BluetoothDeviceClient::Properties(
197 bluetooth_device::kBluetoothDeviceInterface
,
201 FakeBluetoothDeviceClient::Properties::~Properties() {
204 void FakeBluetoothDeviceClient::Properties::Get(
205 dbus::PropertyBase
* property
,
206 dbus::PropertySet::GetCallback callback
) {
207 VLOG(1) << "Get " << property
->name();
211 void FakeBluetoothDeviceClient::Properties::GetAll() {
215 void FakeBluetoothDeviceClient::Properties::Set(
216 dbus::PropertyBase
*property
,
217 dbus::PropertySet::SetCallback callback
) {
218 VLOG(1) << "Set " << property
->name();
219 if (property
->name() == trusted
.name()) {
221 property
->ReplaceValueWithSetValue();
227 FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
228 : simulation_interval_ms_(kSimulationIntervalMs
),
229 discovery_simulation_step_(0),
230 incoming_pairing_simulation_step_(0),
231 pairing_cancelled_(false),
232 connection_rssi_(kUnkownPower
),
233 transmit_power_(kUnkownPower
),
234 max_transmit_power_(kUnkownPower
) {
235 Properties
* properties
= new Properties(base::Bind(
236 &FakeBluetoothDeviceClient::OnPropertyChanged
,
237 base::Unretained(this),
238 dbus::ObjectPath(kPairedDevicePath
)));
239 properties
->address
.ReplaceValue(kPairedDeviceAddress
);
240 properties
->bluetooth_class
.ReplaceValue(kPairedDeviceClass
);
241 properties
->name
.ReplaceValue("Fake Device (Name)");
242 properties
->alias
.ReplaceValue(kPairedDeviceName
);
243 properties
->paired
.ReplaceValue(true);
244 properties
->trusted
.ReplaceValue(true);
245 properties
->adapter
.ReplaceValue(
246 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
));
248 std::vector
<std::string
> uuids
;
249 uuids
.push_back("00001800-0000-1000-8000-00805f9b34fb");
250 uuids
.push_back("00001801-0000-1000-8000-00805f9b34fb");
251 properties
->uuids
.ReplaceValue(uuids
);
253 properties
->modalias
.ReplaceValue("usb:v05ACp030Dd0306");
255 properties_map_
[dbus::ObjectPath(kPairedDevicePath
)] = properties
;
256 device_list_
.push_back(dbus::ObjectPath(kPairedDevicePath
));
258 properties
= new Properties(base::Bind(
259 &FakeBluetoothDeviceClient::OnPropertyChanged
, base::Unretained(this),
260 dbus::ObjectPath(kPairedUnconnectableDevicePath
)));
261 properties
->address
.ReplaceValue(kPairedUnconnectableDeviceAddress
);
262 properties
->bluetooth_class
.ReplaceValue(kPairedUnconnectableDeviceClass
);
263 properties
->name
.ReplaceValue("Fake Device 2 (Unconnectable)");
264 properties
->alias
.ReplaceValue(kPairedUnconnectableDeviceName
);
265 properties
->paired
.ReplaceValue(true);
266 properties
->trusted
.ReplaceValue(true);
267 properties
->adapter
.ReplaceValue(
268 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
));
270 properties
->uuids
.ReplaceValue(uuids
);
272 properties
->modalias
.ReplaceValue("usb:v05ACp030Dd0306");
274 properties_map_
[dbus::ObjectPath(kPairedUnconnectableDevicePath
)] =
276 device_list_
.push_back(dbus::ObjectPath(kPairedUnconnectableDevicePath
));
279 FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() {
280 // Clean up Properties structures
281 STLDeleteValues(&properties_map_
);
284 void FakeBluetoothDeviceClient::Init(dbus::Bus
* bus
) {
287 void FakeBluetoothDeviceClient::AddObserver(Observer
* observer
) {
288 observers_
.AddObserver(observer
);
291 void FakeBluetoothDeviceClient::RemoveObserver(Observer
* observer
) {
292 observers_
.RemoveObserver(observer
);
295 std::vector
<dbus::ObjectPath
> FakeBluetoothDeviceClient::GetDevicesForAdapter(
296 const dbus::ObjectPath
& adapter_path
) {
298 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
))
301 return std::vector
<dbus::ObjectPath
>();
304 FakeBluetoothDeviceClient::Properties
*
305 FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath
& object_path
) {
306 PropertiesMap::iterator iter
= properties_map_
.find(object_path
);
307 if (iter
!= properties_map_
.end())
312 void FakeBluetoothDeviceClient::Connect(
313 const dbus::ObjectPath
& object_path
,
314 const base::Closure
& callback
,
315 const ErrorCallback
& error_callback
) {
316 VLOG(1) << "Connect: " << object_path
.value();
317 Properties
* properties
= GetProperties(object_path
);
319 if (properties
->connected
.value() == true) {
320 // Already connected.
325 if (properties
->paired
.value() != true &&
326 object_path
!= dbus::ObjectPath(kConnectUnpairablePath
) &&
327 object_path
!= dbus::ObjectPath(kLowEnergyPath
)) {
329 error_callback
.Run(bluetooth_device::kErrorFailed
, "Not paired");
331 } else if (properties
->paired
.value() == true &&
332 (object_path
== dbus::ObjectPath(kUnconnectableDevicePath
) ||
334 dbus::ObjectPath(kPairedUnconnectableDevicePath
))) {
335 // Must not be paired
336 error_callback
.Run(bluetooth_device::kErrorFailed
,
337 "Connection fails while paired");
341 // The device can be connected.
342 properties
->connected
.ReplaceValue(true);
345 // Expose GATT services if connected to LE device.
346 if (object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
347 FakeBluetoothGattServiceClient
* gatt_service_client
=
348 static_cast<FakeBluetoothGattServiceClient
*>(
349 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
350 gatt_service_client
->ExposeHeartRateService(
351 dbus::ObjectPath(kLowEnergyPath
));
354 AddInputDeviceIfNeeded(object_path
, properties
);
357 void FakeBluetoothDeviceClient::Disconnect(
358 const dbus::ObjectPath
& object_path
,
359 const base::Closure
& callback
,
360 const ErrorCallback
& error_callback
) {
361 VLOG(1) << "Disconnect: " << object_path
.value();
362 Properties
* properties
= GetProperties(object_path
);
364 if (!properties
->connected
.value()) {
365 error_callback
.Run("org.bluez.Error.NotConnected", "Not Connected");
369 // Hide the Heart Rate Service if disconnected from LE device.
370 if (object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
371 FakeBluetoothGattServiceClient
* gatt_service_client
=
372 static_cast<FakeBluetoothGattServiceClient
*>(
373 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
374 gatt_service_client
->HideHeartRateService();
378 properties
->connected
.ReplaceValue(false);
381 void FakeBluetoothDeviceClient::ConnectProfile(
382 const dbus::ObjectPath
& object_path
,
383 const std::string
& uuid
,
384 const base::Closure
& callback
,
385 const ErrorCallback
& error_callback
) {
386 VLOG(1) << "ConnectProfile: " << object_path
.value() << " " << uuid
;
388 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
389 static_cast<FakeBluetoothProfileManagerClient
*>(
390 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
391 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
392 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(uuid
);
393 if (profile_service_provider
== NULL
) {
394 error_callback
.Run(kNoResponseError
, "Missing profile");
398 if (object_path
== dbus::ObjectPath(kPairedUnconnectableDevicePath
)) {
399 error_callback
.Run(bluetooth_device::kErrorFailed
, "unconnectable");
403 // Make a socket pair of a compatible type with the type used by Bluetooth;
404 // spin up a thread to simulate the server side and wrap the client side in
405 // a D-Bus file descriptor object.
406 int socket_type
= SOCK_STREAM
;
407 if (uuid
== FakeBluetoothProfileManagerClient::kL2capUuid
)
408 socket_type
= SOCK_SEQPACKET
;
411 if (socketpair(AF_UNIX
, socket_type
, 0, fds
) < 0) {
412 error_callback
.Run(kNoResponseError
, "socketpair call failed");
417 args
= fcntl(fds
[1], F_GETFL
, NULL
);
419 error_callback
.Run(kNoResponseError
, "failed to get socket flags");
424 if (fcntl(fds
[1], F_SETFL
, args
) < 0) {
425 error_callback
.Run(kNoResponseError
, "failed to set socket non-blocking");
429 base::WorkerPool::GetTaskRunner(false)->PostTask(
431 base::Bind(&SimulatedProfileSocket
,
434 scoped_ptr
<dbus::FileDescriptor
> fd(new dbus::FileDescriptor(fds
[1]));
436 // Post the new connection to the service provider.
437 BluetoothProfileServiceProvider::Delegate::Options options
;
439 profile_service_provider
->NewConnection(
443 base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback
,
444 base::Unretained(this),
450 void FakeBluetoothDeviceClient::DisconnectProfile(
451 const dbus::ObjectPath
& object_path
,
452 const std::string
& uuid
,
453 const base::Closure
& callback
,
454 const ErrorCallback
& error_callback
) {
455 VLOG(1) << "DisconnectProfile: " << object_path
.value() << " " << uuid
;
457 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
458 static_cast<FakeBluetoothProfileManagerClient
*>(
459 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
460 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
461 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(uuid
);
462 if (profile_service_provider
== NULL
) {
463 error_callback
.Run(kNoResponseError
, "Missing profile");
467 profile_service_provider
->RequestDisconnection(
469 base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback
,
470 base::Unretained(this),
476 void FakeBluetoothDeviceClient::Pair(
477 const dbus::ObjectPath
& object_path
,
478 const base::Closure
& callback
,
479 const ErrorCallback
& error_callback
) {
480 VLOG(1) << "Pair: " << object_path
.value();
481 Properties
* properties
= GetProperties(object_path
);
483 if (properties
->paired
.value() == true) {
489 SimulatePairing(object_path
, false, callback
, error_callback
);
492 void FakeBluetoothDeviceClient::CancelPairing(
493 const dbus::ObjectPath
& object_path
,
494 const base::Closure
& callback
,
495 const ErrorCallback
& error_callback
) {
496 VLOG(1) << "CancelPairing: " << object_path
.value();
497 pairing_cancelled_
= true;
501 void FakeBluetoothDeviceClient::GetConnInfo(
502 const dbus::ObjectPath
& object_path
,
503 const ConnInfoCallback
& callback
,
504 const ErrorCallback
& error_callback
) {
505 Properties
* properties
= GetProperties(object_path
);
506 if (!properties
->connected
.value()) {
507 error_callback
.Run("org.bluez.Error.NotConnected", "Not Connected");
511 callback
.Run(connection_rssi_
, transmit_power_
, max_transmit_power_
);
514 void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
515 const dbus::ObjectPath
& adapter_path
) {
516 VLOG(1) << "starting discovery simulation";
518 discovery_simulation_step_
= 1;
520 base::MessageLoop::current()->PostDelayedTask(
522 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer
,
523 base::Unretained(this)),
524 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
527 void FakeBluetoothDeviceClient::EndDiscoverySimulation(
528 const dbus::ObjectPath
& adapter_path
) {
529 VLOG(1) << "stopping discovery simulation";
530 discovery_simulation_step_
= 0;
533 void FakeBluetoothDeviceClient::BeginIncomingPairingSimulation(
534 const dbus::ObjectPath
& adapter_path
) {
535 VLOG(1) << "starting incoming pairing simulation";
537 incoming_pairing_simulation_step_
= 1;
539 base::MessageLoop::current()->PostDelayedTask(
541 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer
,
542 base::Unretained(this)),
543 base::TimeDelta::FromMilliseconds(30 * simulation_interval_ms_
));
546 void FakeBluetoothDeviceClient::EndIncomingPairingSimulation(
547 const dbus::ObjectPath
& adapter_path
) {
548 VLOG(1) << "stopping incoming pairing simulation";
549 incoming_pairing_simulation_step_
= 0;
552 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms
) {
553 simulation_interval_ms_
= interval_ms
;
556 void FakeBluetoothDeviceClient::CreateDevice(
557 const dbus::ObjectPath
& adapter_path
,
558 const dbus::ObjectPath
& device_path
) {
559 if (std::find(device_list_
.begin(),
560 device_list_
.end(), device_path
) != device_list_
.end())
563 Properties
* properties
= new Properties(base::Bind(
564 &FakeBluetoothDeviceClient::OnPropertyChanged
,
565 base::Unretained(this),
567 properties
->adapter
.ReplaceValue(adapter_path
);
569 if (device_path
== dbus::ObjectPath(kLegacyAutopairPath
)) {
570 properties
->address
.ReplaceValue(kLegacyAutopairAddress
);
571 properties
->bluetooth_class
.ReplaceValue(kLegacyAutopairClass
);
572 properties
->name
.ReplaceValue("LegacyAutopair");
573 properties
->alias
.ReplaceValue(kLegacyAutopairName
);
575 std::vector
<std::string
> uuids
;
576 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
577 properties
->uuids
.ReplaceValue(uuids
);
579 } else if (device_path
== dbus::ObjectPath(kDisplayPinCodePath
)) {
580 properties
->address
.ReplaceValue(kDisplayPinCodeAddress
);
581 properties
->bluetooth_class
.ReplaceValue(kDisplayPinCodeClass
);
582 properties
->name
.ReplaceValue("DisplayPinCode");
583 properties
->alias
.ReplaceValue(kDisplayPinCodeName
);
585 std::vector
<std::string
> uuids
;
586 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
587 properties
->uuids
.ReplaceValue(uuids
);
589 } else if (device_path
== dbus::ObjectPath(kVanishingDevicePath
)) {
590 properties
->address
.ReplaceValue(kVanishingDeviceAddress
);
591 properties
->bluetooth_class
.ReplaceValue(kVanishingDeviceClass
);
592 properties
->name
.ReplaceValue("VanishingDevice");
593 properties
->alias
.ReplaceValue(kVanishingDeviceName
);
595 } else if (device_path
== dbus::ObjectPath(kConnectUnpairablePath
)) {
596 properties
->address
.ReplaceValue(kConnectUnpairableAddress
);
597 properties
->bluetooth_class
.ReplaceValue(kConnectUnpairableClass
);
598 properties
->name
.ReplaceValue("ConnectUnpairable");
599 properties
->alias
.ReplaceValue(kConnectUnpairableName
);
601 std::vector
<std::string
> uuids
;
602 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
603 properties
->uuids
.ReplaceValue(uuids
);
605 } else if (device_path
== dbus::ObjectPath(kDisplayPasskeyPath
)) {
606 properties
->address
.ReplaceValue(kDisplayPasskeyAddress
);
607 properties
->bluetooth_class
.ReplaceValue(kDisplayPasskeyClass
);
608 properties
->name
.ReplaceValue("DisplayPasskey");
609 properties
->alias
.ReplaceValue(kDisplayPasskeyName
);
611 std::vector
<std::string
> uuids
;
612 uuids
.push_back("00001124-0000-1000-8000-00805f9b34fb");
613 properties
->uuids
.ReplaceValue(uuids
);
615 } else if (device_path
== dbus::ObjectPath(kRequestPinCodePath
)) {
616 properties
->address
.ReplaceValue(kRequestPinCodeAddress
);
617 properties
->bluetooth_class
.ReplaceValue(kRequestPinCodeClass
);
618 properties
->name
.ReplaceValue("RequestPinCode");
619 properties
->alias
.ReplaceValue(kRequestPinCodeName
);
621 } else if (device_path
== dbus::ObjectPath(kConfirmPasskeyPath
)) {
622 properties
->address
.ReplaceValue(kConfirmPasskeyAddress
);
623 properties
->bluetooth_class
.ReplaceValue(kConfirmPasskeyClass
);
624 properties
->name
.ReplaceValue("ConfirmPasskey");
625 properties
->alias
.ReplaceValue(kConfirmPasskeyName
);
627 } else if (device_path
== dbus::ObjectPath(kRequestPasskeyPath
)) {
628 properties
->address
.ReplaceValue(kRequestPasskeyAddress
);
629 properties
->bluetooth_class
.ReplaceValue(kRequestPasskeyClass
);
630 properties
->name
.ReplaceValue("RequestPasskey");
631 properties
->alias
.ReplaceValue(kRequestPasskeyName
);
633 } else if (device_path
== dbus::ObjectPath(kUnconnectableDevicePath
)) {
634 properties
->address
.ReplaceValue(kUnconnectableDeviceAddress
);
635 properties
->bluetooth_class
.ReplaceValue(kUnconnectableDeviceClass
);
636 properties
->name
.ReplaceValue("UnconnectableDevice");
637 properties
->alias
.ReplaceValue(kUnconnectableDeviceName
);
639 } else if (device_path
== dbus::ObjectPath(kUnpairableDevicePath
)) {
640 properties
->address
.ReplaceValue(kUnpairableDeviceAddress
);
641 properties
->bluetooth_class
.ReplaceValue(kUnpairableDeviceClass
);
642 properties
->name
.ReplaceValue("Fake Unpairable Device");
643 properties
->alias
.ReplaceValue(kUnpairableDeviceName
);
645 } else if (device_path
== dbus::ObjectPath(kJustWorksPath
)) {
646 properties
->address
.ReplaceValue(kJustWorksAddress
);
647 properties
->bluetooth_class
.ReplaceValue(kJustWorksClass
);
648 properties
->name
.ReplaceValue("JustWorks");
649 properties
->alias
.ReplaceValue(kJustWorksName
);
651 } else if (device_path
== dbus::ObjectPath(kLowEnergyPath
)) {
652 properties
->address
.ReplaceValue(kLowEnergyAddress
);
653 properties
->bluetooth_class
.ReplaceValue(kLowEnergyClass
);
654 properties
->name
.ReplaceValue("Heart Rate Monitor");
655 properties
->alias
.ReplaceValue(kLowEnergyName
);
657 std::vector
<std::string
> uuids
;
658 uuids
.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
);
659 properties
->uuids
.ReplaceValue(uuids
);
666 properties_map_
[device_path
] = properties
;
667 device_list_
.push_back(device_path
);
668 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
669 DeviceAdded(device_path
));
672 void FakeBluetoothDeviceClient::RemoveDevice(
673 const dbus::ObjectPath
& adapter_path
,
674 const dbus::ObjectPath
& device_path
) {
675 std::vector
<dbus::ObjectPath
>::iterator listiter
=
676 std::find(device_list_
.begin(), device_list_
.end(), device_path
);
677 if (listiter
== device_list_
.end())
680 PropertiesMap::iterator iter
= properties_map_
.find(device_path
);
681 Properties
* properties
= iter
->second
;
683 VLOG(1) << "removing device: " << properties
->alias
.value();
684 device_list_
.erase(listiter
);
686 // Remove the Input interface if it exists. This should be called before the
687 // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
688 // BluetoothDeviceChromeOS object, including the device_path referenced here.
689 FakeBluetoothInputClient
* fake_bluetooth_input_client
=
690 static_cast<FakeBluetoothInputClient
*>(
691 DBusThreadManager::Get()->GetBluetoothInputClient());
692 fake_bluetooth_input_client
->RemoveInputDevice(device_path
);
694 if (device_path
== dbus::ObjectPath(kLowEnergyPath
)) {
695 FakeBluetoothGattServiceClient
* gatt_service_client
=
696 static_cast<FakeBluetoothGattServiceClient
*>(
697 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
698 gatt_service_client
->HideHeartRateService();
701 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
702 DeviceRemoved(device_path
));
705 properties_map_
.erase(iter
);
708 void FakeBluetoothDeviceClient::OnPropertyChanged(
709 const dbus::ObjectPath
& object_path
,
710 const std::string
& property_name
) {
711 VLOG(2) << "Fake Bluetooth device property changed: " << object_path
.value()
712 << ": " << property_name
;
713 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
714 DevicePropertyChanged(object_path
, property_name
));
717 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
718 if (!discovery_simulation_step_
)
721 // Timer fires every .75s, the numbers below are arbitrary to give a feel
722 // for a discovery process.
723 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_
;
724 if (discovery_simulation_step_
== 2) {
725 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
726 dbus::ObjectPath(kLegacyAutopairPath
));
727 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
728 dbus::ObjectPath(kLowEnergyPath
));
730 } else if (discovery_simulation_step_
== 4) {
731 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
732 base::RandInt(kMinRSSI
, kMaxRSSI
));
733 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
734 dbus::ObjectPath(kDisplayPinCodePath
));
735 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
736 dbus::ObjectPath(kVanishingDevicePath
));
738 } else if (discovery_simulation_step_
== 7) {
739 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
740 dbus::ObjectPath(kConnectUnpairablePath
));
741 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
742 base::RandInt(kMinRSSI
, kMaxRSSI
));
744 } else if (discovery_simulation_step_
== 8) {
745 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
746 dbus::ObjectPath(kDisplayPasskeyPath
));
747 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
748 dbus::ObjectPath(kRequestPinCodePath
));
749 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
750 base::RandInt(kMinRSSI
, kMaxRSSI
));
752 } else if (discovery_simulation_step_
== 10) {
753 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
754 dbus::ObjectPath(kConfirmPasskeyPath
));
755 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
756 dbus::ObjectPath(kRequestPasskeyPath
));
757 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
758 dbus::ObjectPath(kUnconnectableDevicePath
));
759 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
760 dbus::ObjectPath(kUnpairableDevicePath
));
761 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
762 dbus::ObjectPath(kJustWorksPath
));
763 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
764 base::RandInt(kMinRSSI
, kMaxRSSI
));
766 } else if (discovery_simulation_step_
== 13) {
767 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
768 base::RandInt(kMinRSSI
, kMaxRSSI
));
769 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
770 dbus::ObjectPath(kVanishingDevicePath
));
772 } else if (discovery_simulation_step_
== 14) {
773 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath
),
774 base::RandInt(kMinRSSI
, kMaxRSSI
));
779 ++discovery_simulation_step_
;
780 base::MessageLoop::current()->PostDelayedTask(
782 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer
,
783 base::Unretained(this)),
784 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
787 void FakeBluetoothDeviceClient::IncomingPairingSimulationTimer() {
788 if (!incoming_pairing_simulation_step_
)
791 VLOG(1) << "incoming pairing simulation, step "
792 << incoming_pairing_simulation_step_
;
793 switch (incoming_pairing_simulation_step_
) {
795 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
796 dbus::ObjectPath(kConfirmPasskeyPath
));
797 SimulatePairing(dbus::ObjectPath(kConfirmPasskeyPath
), true,
798 base::Bind(&base::DoNothing
),
799 base::Bind(&SimpleErrorCallback
));
802 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
803 dbus::ObjectPath(kJustWorksPath
));
804 SimulatePairing(dbus::ObjectPath(kJustWorksPath
), true,
805 base::Bind(&base::DoNothing
),
806 base::Bind(&SimpleErrorCallback
));
809 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
810 dbus::ObjectPath(kDisplayPinCodePath
));
811 SimulatePairing(dbus::ObjectPath(kDisplayPinCodePath
), true,
812 base::Bind(&base::DoNothing
),
813 base::Bind(&SimpleErrorCallback
));
816 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
817 dbus::ObjectPath(kDisplayPasskeyPath
));
818 SimulatePairing(dbus::ObjectPath(kDisplayPasskeyPath
), true,
819 base::Bind(&base::DoNothing
),
820 base::Bind(&SimpleErrorCallback
));
823 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
824 dbus::ObjectPath(kRequestPinCodePath
));
825 SimulatePairing(dbus::ObjectPath(kRequestPinCodePath
), true,
826 base::Bind(&base::DoNothing
),
827 base::Bind(&SimpleErrorCallback
));
830 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
831 dbus::ObjectPath(kRequestPasskeyPath
));
832 SimulatePairing(dbus::ObjectPath(kRequestPasskeyPath
), true,
833 base::Bind(&base::DoNothing
),
834 base::Bind(&SimpleErrorCallback
));
840 ++incoming_pairing_simulation_step_
;
841 base::MessageLoop::current()->PostDelayedTask(
843 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer
,
844 base::Unretained(this)),
845 base::TimeDelta::FromMilliseconds(45 * simulation_interval_ms_
));
848 void FakeBluetoothDeviceClient::SimulatePairing(
849 const dbus::ObjectPath
& object_path
,
850 bool incoming_request
,
851 const base::Closure
& callback
,
852 const ErrorCallback
& error_callback
) {
853 pairing_cancelled_
= false;
855 FakeBluetoothAgentManagerClient
* fake_bluetooth_agent_manager_client
=
856 static_cast<FakeBluetoothAgentManagerClient
*>(
857 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
858 FakeBluetoothAgentServiceProvider
* agent_service_provider
=
859 fake_bluetooth_agent_manager_client
->GetAgentServiceProvider();
860 CHECK(agent_service_provider
!= NULL
);
862 if (object_path
== dbus::ObjectPath(kLegacyAutopairPath
) ||
863 object_path
== dbus::ObjectPath(kConnectUnpairablePath
) ||
864 object_path
== dbus::ObjectPath(kUnconnectableDevicePath
) ||
865 object_path
== dbus::ObjectPath(kLowEnergyPath
)) {
866 // No need to call anything on the pairing delegate, just wait 3 times
867 // the interval before acting as if the other end accepted it.
868 base::MessageLoop::current()->PostDelayedTask(
870 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
871 base::Unretained(this),
872 object_path
, callback
, error_callback
),
873 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
875 } else if (object_path
== dbus::ObjectPath(kDisplayPinCodePath
)) {
876 // Display a Pincode, and wait 7 times the interval before acting as
877 // if the other end accepted it.
878 agent_service_provider
->DisplayPinCode(object_path
, "123456");
880 base::MessageLoop::current()->PostDelayedTask(
882 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
883 base::Unretained(this),
884 object_path
, callback
, error_callback
),
885 base::TimeDelta::FromMilliseconds(7 * simulation_interval_ms_
));
887 } else if (object_path
== dbus::ObjectPath(kVanishingDevicePath
)) {
888 // The vanishing device simulates being too far away, and thus times out.
889 base::MessageLoop::current()->PostDelayedTask(
891 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing
,
892 base::Unretained(this),
893 object_path
, error_callback
),
894 base::TimeDelta::FromMilliseconds(4 * simulation_interval_ms_
));
896 } else if (object_path
== dbus::ObjectPath(kDisplayPasskeyPath
)) {
897 // Display a passkey, and each interval act as if another key was entered
899 agent_service_provider
->DisplayPasskey(object_path
, 123456, 0);
901 base::MessageLoop::current()->PostDelayedTask(
903 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress
,
904 base::Unretained(this),
905 1, object_path
, callback
, error_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::MessageLoop::current()->PostDelayedTask(
942 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing
,
943 base::Unretained(this),
944 object_path
, error_callback
),
945 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
947 } else if (object_path
== dbus::ObjectPath(kJustWorksPath
)) {
948 if (incoming_request
) {
949 agent_service_provider
->RequestAuthorization(
951 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback
,
952 base::Unretained(this),
958 // No need to call anything on the pairing delegate, just wait 3 times
959 // the interval before acting as if the other end accepted it.
960 base::MessageLoop::current()->PostDelayedTask(
962 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
963 base::Unretained(this),
964 object_path
, callback
, error_callback
),
965 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
970 error_callback
.Run(kNoResponseError
, "No pairing fake");
974 void FakeBluetoothDeviceClient::CompleteSimulatedPairing(
975 const dbus::ObjectPath
& object_path
,
976 const base::Closure
& callback
,
977 const ErrorCallback
& error_callback
) {
978 VLOG(1) << "CompleteSimulatedPairing: " << object_path
.value();
979 if (pairing_cancelled_
) {
980 pairing_cancelled_
= false;
982 error_callback
.Run(bluetooth_device::kErrorAuthenticationCanceled
,
985 Properties
* properties
= GetProperties(object_path
);
987 properties
->paired
.ReplaceValue(true);
990 AddInputDeviceIfNeeded(object_path
, properties
);
994 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing(
995 const dbus::ObjectPath
& object_path
,
996 const ErrorCallback
& error_callback
) {
997 VLOG(1) << "TimeoutSimulatedPairing: " << object_path
.value();
999 error_callback
.Run(bluetooth_device::kErrorAuthenticationTimeout
,
1003 void FakeBluetoothDeviceClient::CancelSimulatedPairing(
1004 const dbus::ObjectPath
& object_path
,
1005 const ErrorCallback
& error_callback
) {
1006 VLOG(1) << "CancelSimulatedPairing: " << object_path
.value();
1008 error_callback
.Run(bluetooth_device::kErrorAuthenticationCanceled
,
1012 void FakeBluetoothDeviceClient::RejectSimulatedPairing(
1013 const dbus::ObjectPath
& object_path
,
1014 const ErrorCallback
& error_callback
) {
1015 VLOG(1) << "RejectSimulatedPairing: " << object_path
.value();
1017 error_callback
.Run(bluetooth_device::kErrorAuthenticationRejected
,
1021 void FakeBluetoothDeviceClient::FailSimulatedPairing(
1022 const dbus::ObjectPath
& object_path
,
1023 const ErrorCallback
& error_callback
) {
1024 VLOG(1) << "FailSimulatedPairing: " << object_path
.value();
1026 error_callback
.Run(bluetooth_device::kErrorFailed
, "Failed");
1029 void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded(
1030 const dbus::ObjectPath
& object_path
,
1031 Properties
* properties
) {
1032 // If the paired device is a HID device based on it's bluetooth class,
1033 // simulate the Input interface.
1034 FakeBluetoothInputClient
* fake_bluetooth_input_client
=
1035 static_cast<FakeBluetoothInputClient
*>(
1036 DBusThreadManager::Get()->GetBluetoothInputClient());
1038 if ((properties
->bluetooth_class
.value() & 0x001f03) == 0x000500)
1039 fake_bluetooth_input_client
->AddInputDevice(object_path
);
1042 void FakeBluetoothDeviceClient::UpdateDeviceRSSI(
1043 const dbus::ObjectPath
& object_path
,
1045 PropertiesMap::iterator iter
= properties_map_
.find(object_path
);
1046 if (iter
== properties_map_
.end()) {
1047 VLOG(2) << "Fake device does not exist: " << object_path
.value();
1050 Properties
* properties
= iter
->second
;
1052 properties
->rssi
.ReplaceValue(rssi
);
1055 void FakeBluetoothDeviceClient::UpdateConnectionInfo(
1056 uint16 connection_rssi
,
1057 uint16 transmit_power
,
1058 uint16 max_transmit_power
) {
1059 connection_rssi_
= connection_rssi
;
1060 transmit_power_
= transmit_power
;
1061 max_transmit_power_
= max_transmit_power
;
1064 void FakeBluetoothDeviceClient::PinCodeCallback(
1065 const dbus::ObjectPath
& object_path
,
1066 const base::Closure
& callback
,
1067 const ErrorCallback
& error_callback
,
1068 BluetoothAgentServiceProvider::Delegate::Status status
,
1069 const std::string
& pincode
) {
1070 VLOG(1) << "PinCodeCallback: " << object_path
.value();
1072 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1073 base::MessageLoop::current()->PostDelayedTask(
1075 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1076 base::Unretained(this),
1077 object_path
, callback
, error_callback
),
1078 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
1080 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1081 base::MessageLoop::current()->PostDelayedTask(
1083 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1084 base::Unretained(this),
1085 object_path
, error_callback
),
1086 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1088 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1089 base::MessageLoop::current()->PostDelayedTask(
1091 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1092 base::Unretained(this),
1093 object_path
, error_callback
),
1094 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1099 void FakeBluetoothDeviceClient::PasskeyCallback(
1100 const dbus::ObjectPath
& object_path
,
1101 const base::Closure
& callback
,
1102 const ErrorCallback
& error_callback
,
1103 BluetoothAgentServiceProvider::Delegate::Status status
,
1105 VLOG(1) << "PasskeyCallback: " << object_path
.value();
1107 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1108 base::MessageLoop::current()->PostDelayedTask(
1110 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1111 base::Unretained(this),
1112 object_path
, callback
, error_callback
),
1113 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
1115 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1116 base::MessageLoop::current()->PostDelayedTask(
1118 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1119 base::Unretained(this),
1120 object_path
, error_callback
),
1121 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1123 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1124 base::MessageLoop::current()->PostDelayedTask(
1126 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1127 base::Unretained(this),
1128 object_path
, error_callback
),
1129 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1134 void FakeBluetoothDeviceClient::ConfirmationCallback(
1135 const dbus::ObjectPath
& object_path
,
1136 const base::Closure
& callback
,
1137 const ErrorCallback
& error_callback
,
1138 BluetoothAgentServiceProvider::Delegate::Status status
) {
1139 VLOG(1) << "ConfirmationCallback: " << object_path
.value();
1141 if (status
== BluetoothAgentServiceProvider::Delegate::SUCCESS
) {
1142 base::MessageLoop::current()->PostDelayedTask(
1144 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1145 base::Unretained(this),
1146 object_path
, callback
, error_callback
),
1147 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_
));
1149 } else if (status
== BluetoothAgentServiceProvider::Delegate::CANCELLED
) {
1150 base::MessageLoop::current()->PostDelayedTask(
1152 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing
,
1153 base::Unretained(this),
1154 object_path
, error_callback
),
1155 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1157 } else if (status
== BluetoothAgentServiceProvider::Delegate::REJECTED
) {
1158 base::MessageLoop::current()->PostDelayedTask(
1160 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing
,
1161 base::Unretained(this),
1162 object_path
, error_callback
),
1163 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1168 void FakeBluetoothDeviceClient::SimulateKeypress(
1170 const dbus::ObjectPath
& object_path
,
1171 const base::Closure
& callback
,
1172 const ErrorCallback
& error_callback
) {
1173 VLOG(1) << "SimulateKeypress " << entered
<< ": " << object_path
.value();
1175 FakeBluetoothAgentManagerClient
* fake_bluetooth_agent_manager_client
=
1176 static_cast<FakeBluetoothAgentManagerClient
*>(
1177 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
1178 FakeBluetoothAgentServiceProvider
* agent_service_provider
=
1179 fake_bluetooth_agent_manager_client
->GetAgentServiceProvider();
1181 // The agent service provider object could have been destroyed after the
1182 // pairing is canceled.
1183 if (!agent_service_provider
)
1186 agent_service_provider
->DisplayPasskey(object_path
, 123456, entered
);
1189 base::MessageLoop::current()->PostDelayedTask(
1191 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress
,
1192 base::Unretained(this),
1193 entered
+ 1, object_path
, callback
, error_callback
),
1194 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1197 base::MessageLoop::current()->PostDelayedTask(
1199 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing
,
1200 base::Unretained(this),
1201 object_path
, callback
, error_callback
),
1202 base::TimeDelta::FromMilliseconds(simulation_interval_ms_
));
1207 void FakeBluetoothDeviceClient::ConnectionCallback(
1208 const dbus::ObjectPath
& object_path
,
1209 const base::Closure
& callback
,
1210 const ErrorCallback
& error_callback
,
1211 BluetoothProfileServiceProvider::Delegate::Status status
) {
1212 VLOG(1) << "ConnectionCallback: " << object_path
.value();
1214 if (status
== BluetoothProfileServiceProvider::Delegate::SUCCESS
) {
1216 } else if (status
== BluetoothProfileServiceProvider::Delegate::CANCELLED
) {
1217 // TODO(keybuk): tear down this side of the connection
1218 error_callback
.Run(bluetooth_device::kErrorFailed
, "Canceled");
1219 } else if (status
== BluetoothProfileServiceProvider::Delegate::REJECTED
) {
1220 // TODO(keybuk): tear down this side of the connection
1221 error_callback
.Run(bluetooth_device::kErrorFailed
, "Rejected");
1225 void FakeBluetoothDeviceClient::DisconnectionCallback(
1226 const dbus::ObjectPath
& object_path
,
1227 const base::Closure
& callback
,
1228 const ErrorCallback
& error_callback
,
1229 BluetoothProfileServiceProvider::Delegate::Status status
) {
1230 VLOG(1) << "DisconnectionCallback: " << object_path
.value();
1232 if (status
== BluetoothProfileServiceProvider::Delegate::SUCCESS
) {
1233 // TODO(keybuk): tear down this side of the connection
1235 } else if (status
== BluetoothProfileServiceProvider::Delegate::CANCELLED
) {
1236 error_callback
.Run(bluetooth_device::kErrorFailed
, "Canceled");
1237 } else if (status
== BluetoothProfileServiceProvider::Delegate::REJECTED
) {
1238 error_callback
.Run(bluetooth_device::kErrorFailed
, "Rejected");
1242 } // namespace chromeos