Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chromeos / dbus / fake_bluetooth_device_client.cc
blob8e086562a55366479c78b9449c4ed07372494d5f
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"
7 #include <fcntl.h>
8 #include <sys/socket.h>
9 #include <sys/types.h>
10 #include <unistd.h>
12 #include <algorithm>
13 #include <string>
14 #include <utility>
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"
36 namespace {
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 // This is meant to delay the removal of a pre defined device until the
49 // developer has time to see it.
50 const int kVanishingDevicePairTimeMultiplier = 4;
52 // Meant to delay a pair request for an observable amount of time.
53 const int kIncomingSimulationPairTimeMultiplier = 45;
55 // Meant to delay a request that asks for pair requests for an observable
56 // amount of time.
57 const int kIncomingSimulationStartPairTimeMultiplier = 30;
59 // This allows the PIN code dialog to be shown for a long enough time to see
60 // the PIN code UI in detail.
61 const int kPinCodeDevicePairTimeMultiplier = 7;
63 // This allows the pairing dialog to be shown for a long enough time to see
64 // its UI in detail.
65 const int kSimulateNormalPairTimeMultiplier = 3;
67 void SimulatedProfileSocket(int fd) {
68 // Simulate a server-side socket of a profile; read data from the socket,
69 // write it back, and then close.
70 char buf[1024];
71 ssize_t len;
72 ssize_t count;
74 len = read(fd, buf, sizeof buf);
75 if (len < 0) {
76 close(fd);
77 return;
80 count = len;
81 len = write(fd, buf, count);
82 if (len < 0) {
83 close(fd);
84 return;
87 close(fd);
90 void SimpleErrorCallback(const std::string& error_name,
91 const std::string& error_message) {
92 VLOG(1) << "Bluetooth Error: " << error_name << ": " << error_message;
95 } // namespace
97 namespace chromeos {
99 const char FakeBluetoothDeviceClient::kTestPinCode[] = "123456";
100 const int FakeBluetoothDeviceClient::kTestPassKey = 123456;
102 const char FakeBluetoothDeviceClient::kPairingMethodNone[] = "None";
103 const char FakeBluetoothDeviceClient::kPairingMethodPinCode[] = "PIN Code";
104 const char FakeBluetoothDeviceClient::kPairingMethodPassKey[] = "PassKey";
106 const char FakeBluetoothDeviceClient::kPairingActionConfirmation[] =
107 "Confirmation";
108 const char FakeBluetoothDeviceClient::kPairingActionDisplay[] = "Display";
109 const char FakeBluetoothDeviceClient::kPairingActionFail[] = "Fail";
110 const char FakeBluetoothDeviceClient::kPairingActionRequest[] = "Request";
112 const char FakeBluetoothDeviceClient::kPairedDevicePath[] =
113 "/fake/hci0/dev0";
114 const char FakeBluetoothDeviceClient::kPairedDeviceAddress[] =
115 "00:11:22:33:44:55";
116 const char FakeBluetoothDeviceClient::kPairedDeviceName[] =
117 "Fake Device";
118 const uint32 FakeBluetoothDeviceClient::kPairedDeviceClass = 0x000104;
120 const char FakeBluetoothDeviceClient::kLegacyAutopairPath[] =
121 "/fake/hci0/dev1";
122 const char FakeBluetoothDeviceClient::kLegacyAutopairAddress[] =
123 "28:CF:DA:00:00:00";
124 const char FakeBluetoothDeviceClient::kLegacyAutopairName[] =
125 "Bluetooth 2.0 Mouse";
126 const uint32 FakeBluetoothDeviceClient::kLegacyAutopairClass = 0x002580;
128 const char FakeBluetoothDeviceClient::kDisplayPinCodePath[] =
129 "/fake/hci0/dev2";
130 const char FakeBluetoothDeviceClient::kDisplayPinCodeAddress[] =
131 "28:37:37:00:00:00";
132 const char FakeBluetoothDeviceClient::kDisplayPinCodeName[] =
133 "Bluetooth 2.0 Keyboard";
134 const uint32 FakeBluetoothDeviceClient::kDisplayPinCodeClass = 0x002540;
136 const char FakeBluetoothDeviceClient::kVanishingDevicePath[] =
137 "/fake/hci0/dev3";
138 const char FakeBluetoothDeviceClient::kVanishingDeviceAddress[] =
139 "01:02:03:04:05:06";
140 const char FakeBluetoothDeviceClient::kVanishingDeviceName[] =
141 "Vanishing Device";
142 const uint32 FakeBluetoothDeviceClient::kVanishingDeviceClass = 0x000104;
144 const char FakeBluetoothDeviceClient::kConnectUnpairablePath[] =
145 "/fake/hci0/dev4";
146 const char FakeBluetoothDeviceClient::kConnectUnpairableAddress[] =
147 "7C:ED:8D:00:00:00";
148 const char FakeBluetoothDeviceClient::kConnectUnpairableName[] =
149 "Unpairable Device";
150 const uint32 FakeBluetoothDeviceClient::kConnectUnpairableClass = 0x002580;
152 const char FakeBluetoothDeviceClient::kDisplayPasskeyPath[] =
153 "/fake/hci0/dev5";
154 const char FakeBluetoothDeviceClient::kDisplayPasskeyAddress[] =
155 "00:0F:F6:00:00:00";
156 const char FakeBluetoothDeviceClient::kDisplayPasskeyName[] =
157 "Bluetooth 2.1+ Keyboard";
158 const uint32 FakeBluetoothDeviceClient::kDisplayPasskeyClass = 0x002540;
160 const char FakeBluetoothDeviceClient::kRequestPinCodePath[] =
161 "/fake/hci0/dev6";
162 const char FakeBluetoothDeviceClient::kRequestPinCodeAddress[] =
163 "00:24:BE:00:00:00";
164 const char FakeBluetoothDeviceClient::kRequestPinCodeName[] =
165 "PIN Device";
166 const uint32 FakeBluetoothDeviceClient::kRequestPinCodeClass = 0x240408;
168 const char FakeBluetoothDeviceClient::kConfirmPasskeyPath[] =
169 "/fake/hci0/dev7";
170 const char FakeBluetoothDeviceClient::kConfirmPasskeyAddress[] =
171 "20:7D:74:00:00:00";
172 const char FakeBluetoothDeviceClient::kConfirmPasskeyName[] =
173 "Phone";
174 const uint32 FakeBluetoothDeviceClient::kConfirmPasskeyClass = 0x7a020c;
176 const char FakeBluetoothDeviceClient::kRequestPasskeyPath[] =
177 "/fake/hci0/dev8";
178 const char FakeBluetoothDeviceClient::kRequestPasskeyAddress[] =
179 "20:7D:74:00:00:01";
180 const char FakeBluetoothDeviceClient::kRequestPasskeyName[] =
181 "Passkey Device";
182 const uint32 FakeBluetoothDeviceClient::kRequestPasskeyClass = 0x7a020c;
184 const char FakeBluetoothDeviceClient::kUnconnectableDevicePath[] =
185 "/fake/hci0/dev9";
186 const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress[] =
187 "20:7D:74:00:00:02";
188 const char FakeBluetoothDeviceClient::kUnconnectableDeviceName[] =
189 "Unconnectable Device";
190 const uint32 FakeBluetoothDeviceClient::kUnconnectableDeviceClass = 0x7a020c;
192 const char FakeBluetoothDeviceClient::kUnpairableDevicePath[] =
193 "/fake/hci0/devA";
194 const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress[] =
195 "20:7D:74:00:00:03";
196 const char FakeBluetoothDeviceClient::kUnpairableDeviceName[] =
197 "Unpairable Device";
198 const uint32 FakeBluetoothDeviceClient::kUnpairableDeviceClass = 0x002540;
200 const char FakeBluetoothDeviceClient::kJustWorksPath[] =
201 "/fake/hci0/devB";
202 const char FakeBluetoothDeviceClient::kJustWorksAddress[] =
203 "00:0C:8A:00:00:00";
204 const char FakeBluetoothDeviceClient::kJustWorksName[] =
205 "Just-Works Device";
206 const uint32 FakeBluetoothDeviceClient::kJustWorksClass = 0x240428;
208 const char FakeBluetoothDeviceClient::kLowEnergyPath[] =
209 "/fake/hci0/devC";
210 const char FakeBluetoothDeviceClient::kLowEnergyAddress[] =
211 "00:1A:11:00:15:30";
212 const char FakeBluetoothDeviceClient::kLowEnergyName[] =
213 "Bluetooth 4.0 Heart Rate Monitor";
214 const uint32 FakeBluetoothDeviceClient::kLowEnergyClass =
215 0x000918; // Major class "Health", Minor class "Heart/Pulse Rate Monitor."
217 const char FakeBluetoothDeviceClient::kPairedUnconnectableDevicePath[] =
218 "/fake/hci0/devD";
219 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress[] =
220 "20:7D:74:00:00:04";
221 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceName[] =
222 "Paired Unconnectable Device";
223 const uint32 FakeBluetoothDeviceClient::kPairedUnconnectableDeviceClass =
224 0x000104;
226 FakeBluetoothDeviceClient::Properties::Properties(
227 const PropertyChangedCallback& callback)
228 : BluetoothDeviceClient::Properties(
229 NULL,
230 bluetooth_device::kBluetoothDeviceInterface,
231 callback) {
234 FakeBluetoothDeviceClient::Properties::~Properties() {
237 void FakeBluetoothDeviceClient::Properties::Get(
238 dbus::PropertyBase* property,
239 dbus::PropertySet::GetCallback callback) {
240 VLOG(1) << "Get " << property->name();
241 callback.Run(false);
244 void FakeBluetoothDeviceClient::Properties::GetAll() {
245 VLOG(1) << "GetAll";
248 void FakeBluetoothDeviceClient::Properties::Set(
249 dbus::PropertyBase *property,
250 dbus::PropertySet::SetCallback callback) {
251 VLOG(1) << "Set " << property->name();
252 if (property->name() == trusted.name()) {
253 callback.Run(true);
254 property->ReplaceValueWithSetValue();
255 } else {
256 callback.Run(false);
260 FakeBluetoothDeviceClient::SimulatedPairingOptions::SimulatedPairingOptions() {}
262 FakeBluetoothDeviceClient::SimulatedPairingOptions::~SimulatedPairingOptions() {
265 FakeBluetoothDeviceClient::IncomingDeviceProperties::
266 IncomingDeviceProperties() {}
268 FakeBluetoothDeviceClient::IncomingDeviceProperties::
269 ~IncomingDeviceProperties() {}
271 FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
272 : simulation_interval_ms_(kSimulationIntervalMs),
273 discovery_simulation_step_(0),
274 incoming_pairing_simulation_step_(0),
275 pairing_cancelled_(false),
276 connection_rssi_(kUnkownPower),
277 transmit_power_(kUnkownPower),
278 max_transmit_power_(kUnkownPower) {
279 scoped_ptr<Properties> properties(new Properties(
280 base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged,
281 base::Unretained(this), dbus::ObjectPath(kPairedDevicePath))));
282 properties->address.ReplaceValue(kPairedDeviceAddress);
283 properties->bluetooth_class.ReplaceValue(kPairedDeviceClass);
284 properties->name.ReplaceValue("Fake Device (Name)");
285 properties->alias.ReplaceValue(kPairedDeviceName);
286 properties->paired.ReplaceValue(true);
287 properties->trusted.ReplaceValue(true);
288 properties->adapter.ReplaceValue(
289 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
291 std::vector<std::string> uuids;
292 uuids.push_back("00001800-0000-1000-8000-00805f9b34fb");
293 uuids.push_back("00001801-0000-1000-8000-00805f9b34fb");
294 properties->uuids.ReplaceValue(uuids);
296 properties->modalias.ReplaceValue("usb:v05ACp030Dd0306");
298 properties_map_.insert(dbus::ObjectPath(kPairedDevicePath),
299 properties.Pass());
300 device_list_.push_back(dbus::ObjectPath(kPairedDevicePath));
302 properties.reset(new Properties(base::Bind(
303 &FakeBluetoothDeviceClient::OnPropertyChanged, base::Unretained(this),
304 dbus::ObjectPath(kPairedUnconnectableDevicePath))));
305 properties->address.ReplaceValue(kPairedUnconnectableDeviceAddress);
306 properties->bluetooth_class.ReplaceValue(kPairedUnconnectableDeviceClass);
307 properties->name.ReplaceValue("Fake Device 2 (Unconnectable)");
308 properties->alias.ReplaceValue(kPairedUnconnectableDeviceName);
309 properties->paired.ReplaceValue(true);
310 properties->trusted.ReplaceValue(true);
311 properties->adapter.ReplaceValue(
312 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
314 properties->uuids.ReplaceValue(uuids);
316 properties->modalias.ReplaceValue("usb:v05ACp030Dd0306");
318 properties_map_.insert(dbus::ObjectPath(kPairedUnconnectableDevicePath),
319 properties.Pass());
320 device_list_.push_back(dbus::ObjectPath(kPairedUnconnectableDevicePath));
323 FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() {
326 void FakeBluetoothDeviceClient::Init(dbus::Bus* bus) {
329 void FakeBluetoothDeviceClient::AddObserver(Observer* observer) {
330 observers_.AddObserver(observer);
333 void FakeBluetoothDeviceClient::RemoveObserver(Observer* observer) {
334 observers_.RemoveObserver(observer);
337 std::vector<dbus::ObjectPath> FakeBluetoothDeviceClient::GetDevicesForAdapter(
338 const dbus::ObjectPath& adapter_path) {
339 if (adapter_path ==
340 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath))
341 return device_list_;
342 else
343 return std::vector<dbus::ObjectPath>();
346 FakeBluetoothDeviceClient::Properties*
347 FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath& object_path) {
348 PropertiesMap::const_iterator iter = properties_map_.find(object_path);
349 if (iter != properties_map_.end())
350 return iter->second;
351 return NULL;
354 FakeBluetoothDeviceClient::SimulatedPairingOptions*
355 FakeBluetoothDeviceClient::GetPairingOptions(
356 const dbus::ObjectPath& object_path) {
357 PairingOptionsMap::const_iterator iter =
358 pairing_options_map_.find(object_path);
359 if (iter != pairing_options_map_.end())
360 return iter->second;
361 return iter != pairing_options_map_.end() ? iter->second : nullptr;
364 void FakeBluetoothDeviceClient::Connect(
365 const dbus::ObjectPath& object_path,
366 const base::Closure& callback,
367 const ErrorCallback& error_callback) {
368 VLOG(1) << "Connect: " << object_path.value();
369 Properties* properties = GetProperties(object_path);
371 if (properties->connected.value() == true) {
372 // Already connected.
373 callback.Run();
374 return;
377 if (properties->paired.value() != true &&
378 object_path != dbus::ObjectPath(kConnectUnpairablePath) &&
379 object_path != dbus::ObjectPath(kLowEnergyPath)) {
380 // Must be paired.
381 error_callback.Run(bluetooth_device::kErrorFailed, "Not paired");
382 return;
383 } else if (properties->paired.value() == true &&
384 (object_path == dbus::ObjectPath(kUnconnectableDevicePath) ||
385 object_path ==
386 dbus::ObjectPath(kPairedUnconnectableDevicePath))) {
387 // Must not be paired
388 error_callback.Run(bluetooth_device::kErrorFailed,
389 "Connection fails while paired");
390 return;
393 // The device can be connected.
394 properties->connected.ReplaceValue(true);
395 callback.Run();
397 // Expose GATT services if connected to LE device.
398 if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
399 FakeBluetoothGattServiceClient* gatt_service_client =
400 static_cast<FakeBluetoothGattServiceClient*>(
401 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
402 gatt_service_client->ExposeHeartRateService(
403 dbus::ObjectPath(kLowEnergyPath));
406 AddInputDeviceIfNeeded(object_path, properties);
409 void FakeBluetoothDeviceClient::Disconnect(
410 const dbus::ObjectPath& object_path,
411 const base::Closure& callback,
412 const ErrorCallback& error_callback) {
413 VLOG(1) << "Disconnect: " << object_path.value();
414 Properties* properties = GetProperties(object_path);
416 if (!properties->connected.value()) {
417 error_callback.Run("org.bluez.Error.NotConnected", "Not Connected");
418 return;
421 // Hide the Heart Rate Service if disconnected from LE device.
422 if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
423 FakeBluetoothGattServiceClient* gatt_service_client =
424 static_cast<FakeBluetoothGattServiceClient*>(
425 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
426 gatt_service_client->HideHeartRateService();
429 callback.Run();
430 properties->connected.ReplaceValue(false);
433 void FakeBluetoothDeviceClient::ConnectProfile(
434 const dbus::ObjectPath& object_path,
435 const std::string& uuid,
436 const base::Closure& callback,
437 const ErrorCallback& error_callback) {
438 VLOG(1) << "ConnectProfile: " << object_path.value() << " " << uuid;
440 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
441 static_cast<FakeBluetoothProfileManagerClient*>(
442 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
443 FakeBluetoothProfileServiceProvider* profile_service_provider =
444 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
445 if (profile_service_provider == NULL) {
446 error_callback.Run(kNoResponseError, "Missing profile");
447 return;
450 if (object_path == dbus::ObjectPath(kPairedUnconnectableDevicePath)) {
451 error_callback.Run(bluetooth_device::kErrorFailed, "unconnectable");
452 return;
455 // Make a socket pair of a compatible type with the type used by Bluetooth;
456 // spin up a thread to simulate the server side and wrap the client side in
457 // a D-Bus file descriptor object.
458 int socket_type = SOCK_STREAM;
459 if (uuid == FakeBluetoothProfileManagerClient::kL2capUuid)
460 socket_type = SOCK_SEQPACKET;
462 int fds[2];
463 if (socketpair(AF_UNIX, socket_type, 0, fds) < 0) {
464 error_callback.Run(kNoResponseError, "socketpair call failed");
465 return;
468 int args;
469 args = fcntl(fds[1], F_GETFL, NULL);
470 if (args < 0) {
471 error_callback.Run(kNoResponseError, "failed to get socket flags");
472 return;
475 args |= O_NONBLOCK;
476 if (fcntl(fds[1], F_SETFL, args) < 0) {
477 error_callback.Run(kNoResponseError, "failed to set socket non-blocking");
478 return;
481 base::WorkerPool::GetTaskRunner(false)->PostTask(
482 FROM_HERE,
483 base::Bind(&SimulatedProfileSocket,
484 fds[0]));
486 scoped_ptr<dbus::FileDescriptor> fd(new dbus::FileDescriptor(fds[1]));
488 // Post the new connection to the service provider.
489 BluetoothProfileServiceProvider::Delegate::Options options;
491 profile_service_provider->NewConnection(
492 object_path,
493 fd.Pass(),
494 options,
495 base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback,
496 base::Unretained(this),
497 object_path,
498 callback,
499 error_callback));
502 void FakeBluetoothDeviceClient::DisconnectProfile(
503 const dbus::ObjectPath& object_path,
504 const std::string& uuid,
505 const base::Closure& callback,
506 const ErrorCallback& error_callback) {
507 VLOG(1) << "DisconnectProfile: " << object_path.value() << " " << uuid;
509 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
510 static_cast<FakeBluetoothProfileManagerClient*>(
511 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
512 FakeBluetoothProfileServiceProvider* profile_service_provider =
513 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
514 if (profile_service_provider == NULL) {
515 error_callback.Run(kNoResponseError, "Missing profile");
516 return;
519 profile_service_provider->RequestDisconnection(
520 object_path,
521 base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback,
522 base::Unretained(this),
523 object_path,
524 callback,
525 error_callback));
528 void FakeBluetoothDeviceClient::Pair(
529 const dbus::ObjectPath& object_path,
530 const base::Closure& callback,
531 const ErrorCallback& error_callback) {
532 VLOG(1) << "Pair: " << object_path.value();
533 Properties* properties = GetProperties(object_path);
535 if (properties->paired.value() == true) {
536 // Already paired.
537 callback.Run();
538 return;
541 SimulatePairing(object_path, false, callback, error_callback);
544 void FakeBluetoothDeviceClient::CancelPairing(
545 const dbus::ObjectPath& object_path,
546 const base::Closure& callback,
547 const ErrorCallback& error_callback) {
548 VLOG(1) << "CancelPairing: " << object_path.value();
549 pairing_cancelled_ = true;
550 callback.Run();
553 void FakeBluetoothDeviceClient::GetConnInfo(
554 const dbus::ObjectPath& object_path,
555 const ConnInfoCallback& callback,
556 const ErrorCallback& error_callback) {
557 Properties* properties = GetProperties(object_path);
558 if (!properties->connected.value()) {
559 error_callback.Run("org.bluez.Error.NotConnected", "Not Connected");
560 return;
563 callback.Run(connection_rssi_, transmit_power_, max_transmit_power_);
566 void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
567 const dbus::ObjectPath& adapter_path) {
568 VLOG(1) << "starting discovery simulation";
570 discovery_simulation_step_ = 1;
572 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
573 FROM_HERE,
574 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
575 base::Unretained(this)),
576 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
579 void FakeBluetoothDeviceClient::EndDiscoverySimulation(
580 const dbus::ObjectPath& adapter_path) {
581 VLOG(1) << "stopping discovery simulation";
582 discovery_simulation_step_ = 0;
585 void FakeBluetoothDeviceClient::BeginIncomingPairingSimulation(
586 const dbus::ObjectPath& adapter_path) {
587 VLOG(1) << "starting incoming pairing simulation";
589 incoming_pairing_simulation_step_ = 1;
591 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
592 FROM_HERE,
593 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
594 base::Unretained(this)),
595 base::TimeDelta::FromMilliseconds(
596 kIncomingSimulationStartPairTimeMultiplier *
597 simulation_interval_ms_));
600 void FakeBluetoothDeviceClient::EndIncomingPairingSimulation(
601 const dbus::ObjectPath& adapter_path) {
602 VLOG(1) << "stopping incoming pairing simulation";
603 incoming_pairing_simulation_step_ = 0;
606 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms) {
607 simulation_interval_ms_ = interval_ms;
610 void FakeBluetoothDeviceClient::CreateDevice(
611 const dbus::ObjectPath& adapter_path,
612 const dbus::ObjectPath& device_path) {
613 if (std::find(device_list_.begin(),
614 device_list_.end(), device_path) != device_list_.end())
615 return;
617 scoped_ptr<Properties> properties(
618 new Properties(base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged,
619 base::Unretained(this), device_path)));
620 properties->adapter.ReplaceValue(adapter_path);
622 if (device_path == dbus::ObjectPath(kLegacyAutopairPath)) {
623 properties->address.ReplaceValue(kLegacyAutopairAddress);
624 properties->bluetooth_class.ReplaceValue(kLegacyAutopairClass);
625 properties->name.ReplaceValue("LegacyAutopair");
626 properties->alias.ReplaceValue(kLegacyAutopairName);
628 std::vector<std::string> uuids;
629 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
630 properties->uuids.ReplaceValue(uuids);
632 } else if (device_path == dbus::ObjectPath(kDisplayPinCodePath)) {
633 properties->address.ReplaceValue(kDisplayPinCodeAddress);
634 properties->bluetooth_class.ReplaceValue(kDisplayPinCodeClass);
635 properties->name.ReplaceValue("DisplayPinCode");
636 properties->alias.ReplaceValue(kDisplayPinCodeName);
638 std::vector<std::string> uuids;
639 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
640 properties->uuids.ReplaceValue(uuids);
642 } else if (device_path == dbus::ObjectPath(kVanishingDevicePath)) {
643 properties->address.ReplaceValue(kVanishingDeviceAddress);
644 properties->bluetooth_class.ReplaceValue(kVanishingDeviceClass);
645 properties->name.ReplaceValue("VanishingDevice");
646 properties->alias.ReplaceValue(kVanishingDeviceName);
648 } else if (device_path == dbus::ObjectPath(kConnectUnpairablePath)) {
649 properties->address.ReplaceValue(kConnectUnpairableAddress);
650 properties->bluetooth_class.ReplaceValue(kConnectUnpairableClass);
651 properties->name.ReplaceValue("ConnectUnpairable");
652 properties->alias.ReplaceValue(kConnectUnpairableName);
654 std::vector<std::string> uuids;
655 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
656 properties->uuids.ReplaceValue(uuids);
658 } else if (device_path == dbus::ObjectPath(kDisplayPasskeyPath)) {
659 properties->address.ReplaceValue(kDisplayPasskeyAddress);
660 properties->bluetooth_class.ReplaceValue(kDisplayPasskeyClass);
661 properties->name.ReplaceValue("DisplayPasskey");
662 properties->alias.ReplaceValue(kDisplayPasskeyName);
664 std::vector<std::string> uuids;
665 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
666 properties->uuids.ReplaceValue(uuids);
668 } else if (device_path == dbus::ObjectPath(kRequestPinCodePath)) {
669 properties->address.ReplaceValue(kRequestPinCodeAddress);
670 properties->bluetooth_class.ReplaceValue(kRequestPinCodeClass);
671 properties->name.ReplaceValue("RequestPinCode");
672 properties->alias.ReplaceValue(kRequestPinCodeName);
674 } else if (device_path == dbus::ObjectPath(kConfirmPasskeyPath)) {
675 properties->address.ReplaceValue(kConfirmPasskeyAddress);
676 properties->bluetooth_class.ReplaceValue(kConfirmPasskeyClass);
677 properties->name.ReplaceValue("ConfirmPasskey");
678 properties->alias.ReplaceValue(kConfirmPasskeyName);
680 } else if (device_path == dbus::ObjectPath(kRequestPasskeyPath)) {
681 properties->address.ReplaceValue(kRequestPasskeyAddress);
682 properties->bluetooth_class.ReplaceValue(kRequestPasskeyClass);
683 properties->name.ReplaceValue("RequestPasskey");
684 properties->alias.ReplaceValue(kRequestPasskeyName);
686 } else if (device_path == dbus::ObjectPath(kUnconnectableDevicePath)) {
687 properties->address.ReplaceValue(kUnconnectableDeviceAddress);
688 properties->bluetooth_class.ReplaceValue(kUnconnectableDeviceClass);
689 properties->name.ReplaceValue("UnconnectableDevice");
690 properties->alias.ReplaceValue(kUnconnectableDeviceName);
692 } else if (device_path == dbus::ObjectPath(kUnpairableDevicePath)) {
693 properties->address.ReplaceValue(kUnpairableDeviceAddress);
694 properties->bluetooth_class.ReplaceValue(kUnpairableDeviceClass);
695 properties->name.ReplaceValue("Fake Unpairable Device");
696 properties->alias.ReplaceValue(kUnpairableDeviceName);
698 } else if (device_path == dbus::ObjectPath(kJustWorksPath)) {
699 properties->address.ReplaceValue(kJustWorksAddress);
700 properties->bluetooth_class.ReplaceValue(kJustWorksClass);
701 properties->name.ReplaceValue("JustWorks");
702 properties->alias.ReplaceValue(kJustWorksName);
704 } else if (device_path == dbus::ObjectPath(kLowEnergyPath)) {
705 properties->address.ReplaceValue(kLowEnergyAddress);
706 properties->bluetooth_class.ReplaceValue(kLowEnergyClass);
707 properties->name.ReplaceValue("Heart Rate Monitor");
708 properties->alias.ReplaceValue(kLowEnergyName);
710 std::vector<std::string> uuids;
711 uuids.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID);
712 properties->uuids.ReplaceValue(uuids);
714 } else {
715 NOTREACHED();
719 properties_map_.insert(device_path, properties.Pass());
720 device_list_.push_back(device_path);
721 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
722 DeviceAdded(device_path));
725 void FakeBluetoothDeviceClient::CreateDeviceWithProperties(
726 const dbus::ObjectPath& adapter_path,
727 const IncomingDeviceProperties& props) {
728 dbus::ObjectPath device_path(props.device_path);
729 if (std::find(device_list_.begin(), device_list_.end(), device_path) !=
730 device_list_.end())
731 return;
733 scoped_ptr<Properties> properties(
734 new Properties(base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged,
735 base::Unretained(this), device_path)));
736 properties->adapter.ReplaceValue(adapter_path);
737 properties->name.ReplaceValue(props.device_name);
738 properties->alias.ReplaceValue(props.device_alias);
739 properties->address.ReplaceValue(props.device_address);
740 properties->bluetooth_class.ReplaceValue(props.device_class);
741 properties->trusted.ReplaceValue(props.is_trusted);
743 if (props.is_trusted)
744 properties->paired.ReplaceValue(true);
746 scoped_ptr<SimulatedPairingOptions> options(new SimulatedPairingOptions);
747 options->pairing_method = props.pairing_method;
748 options->pairing_auth_token = props.pairing_auth_token;
749 options->pairing_action = props.pairing_action;
750 options->incoming = props.incoming;
752 properties_map_.insert(device_path, properties.Pass());
753 device_list_.push_back(device_path);
754 pairing_options_map_.insert(device_path, options.Pass());
755 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
756 DeviceAdded(device_path));
759 scoped_ptr<base::ListValue>
760 FakeBluetoothDeviceClient::GetBluetoothDevicesAsDictionaries() const {
761 scoped_ptr<base::ListValue> predefined_devices(new base::ListValue);
762 scoped_ptr<base::DictionaryValue> pairedDevice(new base::DictionaryValue);
763 pairedDevice->SetString("path", kPairedDevicePath);
764 pairedDevice->SetString("address", kPairedDeviceAddress);
765 pairedDevice->SetString("name", kPairedDeviceName);
766 pairedDevice->SetString("alias", kPairedDeviceName);
767 pairedDevice->SetString("pairingMethod", "");
768 pairedDevice->SetString("pairingAuthToken", "");
769 pairedDevice->SetString("pairingAction", "");
770 pairedDevice->SetInteger("classValue", kPairedDeviceClass);
771 pairedDevice->SetBoolean("discoverable", true);
772 pairedDevice->SetBoolean("isTrusted", true);
773 pairedDevice->SetBoolean("paired", true);
774 pairedDevice->SetBoolean("incoming", false);
775 predefined_devices->Append(pairedDevice.Pass());
777 scoped_ptr<base::DictionaryValue> legacyDevice(new base::DictionaryValue);
778 legacyDevice->SetString("path", kLegacyAutopairPath);
779 legacyDevice->SetString("address", kLegacyAutopairAddress);
780 legacyDevice->SetString("name", kLegacyAutopairName);
781 legacyDevice->SetString("alias", kLegacyAutopairName);
782 legacyDevice->SetString("pairingMethod", "");
783 legacyDevice->SetString("pairingAuthToken", "");
784 legacyDevice->SetString("pairingAction", "");
785 legacyDevice->SetInteger("classValue", kLegacyAutopairClass);
786 legacyDevice->SetBoolean("isTrusted", true);
787 legacyDevice->SetBoolean("discoverable", false);
788 legacyDevice->SetBoolean("paired", false);
789 legacyDevice->SetBoolean("incoming", false);
790 predefined_devices->Append(legacyDevice.Pass());
792 scoped_ptr<base::DictionaryValue> pin(new base::DictionaryValue);
793 pin->SetString("path", kDisplayPinCodePath);
794 pin->SetString("address", kDisplayPinCodeAddress);
795 pin->SetString("name", kDisplayPinCodeName);
796 pin->SetString("alias", kDisplayPinCodeName);
797 pin->SetString("pairingMethod", kPairingMethodPinCode);
798 pin->SetString("pairingAuthToken", kTestPinCode);
799 pin->SetString("pairingAction", kPairingActionDisplay);
800 pin->SetInteger("classValue", kDisplayPinCodeClass);
801 pin->SetBoolean("isTrusted", false);
802 pin->SetBoolean("discoverable", false);
803 pin->SetBoolean("paired", false);
804 pin->SetBoolean("incoming", false);
805 predefined_devices->Append(pin.Pass());
807 scoped_ptr<base::DictionaryValue> vanishing(new base::DictionaryValue);
808 vanishing->SetString("path", kVanishingDevicePath);
809 vanishing->SetString("address", kVanishingDeviceAddress);
810 vanishing->SetString("name", kVanishingDeviceName);
811 vanishing->SetString("alias", kVanishingDeviceName);
812 vanishing->SetString("pairingMethod", "");
813 vanishing->SetString("pairingAuthToken", "");
814 vanishing->SetString("pairingAction", "");
815 vanishing->SetInteger("classValue", kVanishingDeviceClass);
816 vanishing->SetBoolean("isTrusted", false);
817 vanishing->SetBoolean("discoverable", false);
818 vanishing->SetBoolean("paired", false);
819 vanishing->SetBoolean("incoming", false);
820 predefined_devices->Append(vanishing.Pass());
822 scoped_ptr<base::DictionaryValue> connect_unpairable(
823 new base::DictionaryValue);
824 connect_unpairable->SetString("path", kConnectUnpairablePath);
825 connect_unpairable->SetString("address", kConnectUnpairableAddress);
826 connect_unpairable->SetString("name", kConnectUnpairableName);
827 connect_unpairable->SetString("pairingMethod", "");
828 connect_unpairable->SetString("pairingAuthToken", "");
829 connect_unpairable->SetString("pairingAction", "");
830 connect_unpairable->SetString("alias", kConnectUnpairableName);
831 connect_unpairable->SetInteger("classValue", kConnectUnpairableClass);
832 connect_unpairable->SetBoolean("isTrusted", false);
833 connect_unpairable->SetBoolean("discoverable", false);
834 connect_unpairable->SetBoolean("paired", false);
835 connect_unpairable->SetBoolean("incoming", false);
836 predefined_devices->Append(connect_unpairable.Pass());
838 scoped_ptr<base::DictionaryValue> passkey(new base::DictionaryValue);
839 passkey->SetString("path", kDisplayPasskeyPath);
840 passkey->SetString("address", kDisplayPasskeyAddress);
841 passkey->SetString("name", kDisplayPasskeyName);
842 passkey->SetString("alias", kDisplayPasskeyName);
843 passkey->SetString("pairingMethod", kPairingMethodPassKey);
844 passkey->SetInteger("pairingAuthToken", kTestPassKey);
845 passkey->SetString("pairingAction", kPairingActionDisplay);
846 passkey->SetInteger("classValue", kDisplayPasskeyClass);
847 passkey->SetBoolean("isTrusted", false);
848 passkey->SetBoolean("discoverable", false);
849 passkey->SetBoolean("paired", false);
850 passkey->SetBoolean("incoming", false);
851 predefined_devices->Append(passkey.Pass());
853 scoped_ptr<base::DictionaryValue> request_pin(new base::DictionaryValue);
854 request_pin->SetString("path", kRequestPinCodePath);
855 request_pin->SetString("address", kRequestPinCodeAddress);
856 request_pin->SetString("name", kRequestPinCodeName);
857 request_pin->SetString("alias", kRequestPinCodeName);
858 request_pin->SetString("pairingMethod", "");
859 request_pin->SetString("pairingAuthToken", "");
860 request_pin->SetString("pairingAction", kPairingActionRequest);
861 request_pin->SetInteger("classValue", kRequestPinCodeClass);
862 request_pin->SetBoolean("isTrusted", false);
863 request_pin->SetBoolean("discoverable", false);
864 request_pin->SetBoolean("paired", false);
865 request_pin->SetBoolean("incoming", false);
866 predefined_devices->Append(request_pin.Pass());
868 scoped_ptr<base::DictionaryValue> confirm(new base::DictionaryValue);
869 confirm->SetString("path", kConfirmPasskeyPath);
870 confirm->SetString("address", kConfirmPasskeyAddress);
871 confirm->SetString("name", kConfirmPasskeyName);
872 confirm->SetString("alias", kConfirmPasskeyName);
873 confirm->SetString("pairingMethod", "");
874 confirm->SetInteger("pairingAuthToken", kTestPassKey);
875 confirm->SetString("pairingAction", kPairingActionConfirmation);
876 confirm->SetInteger("classValue", kConfirmPasskeyClass);
877 confirm->SetBoolean("isTrusted", false);
878 confirm->SetBoolean("discoverable", false);
879 confirm->SetBoolean("paired", false);
880 confirm->SetBoolean("incoming", false);
881 predefined_devices->Append(confirm.Pass());
883 scoped_ptr<base::DictionaryValue> request_passkey(new base::DictionaryValue);
884 request_passkey->SetString("path", kRequestPasskeyPath);
885 request_passkey->SetString("address", kRequestPasskeyAddress);
886 request_passkey->SetString("name", kRequestPasskeyName);
887 request_passkey->SetString("alias", kRequestPasskeyName);
888 request_passkey->SetString("pairingMethod", kPairingMethodPassKey);
889 request_passkey->SetString("pairingAction", kPairingActionRequest);
890 request_passkey->SetInteger("pairingAuthToken", kTestPassKey);
891 request_passkey->SetInteger("classValue", kRequestPasskeyClass);
892 request_passkey->SetBoolean("isTrusted", false);
893 request_passkey->SetBoolean("discoverable", false);
894 request_passkey->SetBoolean("paired", false);
895 request_passkey->SetBoolean("incoming", false);
896 predefined_devices->Append(request_passkey.Pass());
898 scoped_ptr<base::DictionaryValue> unconnectable(new base::DictionaryValue);
899 unconnectable->SetString("path", kUnconnectableDevicePath);
900 unconnectable->SetString("address", kUnconnectableDeviceAddress);
901 unconnectable->SetString("name", kUnconnectableDeviceName);
902 unconnectable->SetString("alias", kUnconnectableDeviceName);
903 unconnectable->SetString("pairingMethod", "");
904 unconnectable->SetString("pairingAuthToken", "");
905 unconnectable->SetString("pairingAction", "");
906 unconnectable->SetInteger("classValue", kUnconnectableDeviceClass);
907 unconnectable->SetBoolean("isTrusted", true);
908 unconnectable->SetBoolean("discoverable", false);
909 unconnectable->SetBoolean("paired", false);
910 unconnectable->SetBoolean("incoming", false);
911 predefined_devices->Append(unconnectable.Pass());
913 scoped_ptr<base::DictionaryValue> unpairable(new base::DictionaryValue);
914 unpairable->SetString("path", kUnpairableDevicePath);
915 unpairable->SetString("address", kUnpairableDeviceAddress);
916 unpairable->SetString("name", kUnpairableDeviceName);
917 unpairable->SetString("alias", kUnpairableDeviceName);
918 unpairable->SetString("pairingMethod", "");
919 unpairable->SetString("pairingAuthToken", "");
920 unpairable->SetString("pairingAction", kPairingActionFail);
921 unpairable->SetInteger("classValue", kUnpairableDeviceClass);
922 unpairable->SetBoolean("isTrusted", false);
923 unpairable->SetBoolean("discoverable", false);
924 unpairable->SetBoolean("paired", false);
925 unpairable->SetBoolean("incoming", false);
926 predefined_devices->Append(unpairable.Pass());
928 scoped_ptr<base::DictionaryValue> just_works(new base::DictionaryValue);
929 just_works->SetString("path", kJustWorksPath);
930 just_works->SetString("address", kJustWorksAddress);
931 just_works->SetString("name", kJustWorksName);
932 just_works->SetString("alias", kJustWorksName);
933 just_works->SetString("pairingMethod", "");
934 just_works->SetString("pairingAuthToken", "");
935 just_works->SetString("pairingAction", "");
936 just_works->SetInteger("classValue", kJustWorksClass);
937 just_works->SetBoolean("isTrusted", false);
938 just_works->SetBoolean("discoverable", false);
939 just_works->SetBoolean("paired", false);
940 just_works->SetBoolean("incoming", false);
941 predefined_devices->Append(just_works.Pass());
943 scoped_ptr<base::DictionaryValue> low_energy(new base::DictionaryValue);
944 low_energy->SetString("path", kLowEnergyPath);
945 low_energy->SetString("address", kLowEnergyAddress);
946 low_energy->SetString("name", kLowEnergyName);
947 low_energy->SetString("alias", kLowEnergyName);
948 low_energy->SetString("pairingMethod", "");
949 low_energy->SetString("pairingAuthToken", "");
950 low_energy->SetString("pairingAction", "");
951 low_energy->SetInteger("classValue", kLowEnergyClass);
952 low_energy->SetBoolean("isTrusted", false);
953 low_energy->SetBoolean("discoverable", false);
954 low_energy->SetBoolean("paireed", false);
955 low_energy->SetBoolean("incoming", false);
956 predefined_devices->Append(low_energy.Pass());
958 scoped_ptr<base::DictionaryValue> paired_unconnectable(
959 new base::DictionaryValue);
960 paired_unconnectable->SetString("path", kPairedUnconnectableDevicePath);
961 paired_unconnectable->SetString("address", kPairedUnconnectableDeviceAddress);
962 paired_unconnectable->SetString("name", kPairedUnconnectableDeviceName);
963 paired_unconnectable->SetString("pairingMethod", "");
964 paired_unconnectable->SetString("pairingAuthToken", "");
965 paired_unconnectable->SetString("pairingAction", "");
966 paired_unconnectable->SetString("alias", kPairedUnconnectableDeviceName);
967 paired_unconnectable->SetInteger("classValue",
968 kPairedUnconnectableDeviceClass);
969 paired_unconnectable->SetBoolean("isTrusted", false);
970 paired_unconnectable->SetBoolean("discoverable", true);
971 paired_unconnectable->SetBoolean("paired", true);
972 paired_unconnectable->SetBoolean("incoming", false);
973 predefined_devices->Append(paired_unconnectable.Pass());
975 return predefined_devices.Pass();
978 void FakeBluetoothDeviceClient::RemoveDevice(
979 const dbus::ObjectPath& adapter_path,
980 const dbus::ObjectPath& device_path) {
981 std::vector<dbus::ObjectPath>::iterator listiter =
982 std::find(device_list_.begin(), device_list_.end(), device_path);
983 if (listiter == device_list_.end())
984 return;
986 PropertiesMap::const_iterator iter = properties_map_.find(device_path);
987 Properties* properties = iter->second;
989 VLOG(1) << "removing device: " << properties->alias.value();
990 device_list_.erase(listiter);
992 // Remove the Input interface if it exists. This should be called before the
993 // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
994 // BluetoothDeviceChromeOS object, including the device_path referenced here.
995 FakeBluetoothInputClient* fake_bluetooth_input_client =
996 static_cast<FakeBluetoothInputClient*>(
997 DBusThreadManager::Get()->GetBluetoothInputClient());
998 fake_bluetooth_input_client->RemoveInputDevice(device_path);
1000 if (device_path == dbus::ObjectPath(kLowEnergyPath)) {
1001 FakeBluetoothGattServiceClient* gatt_service_client =
1002 static_cast<FakeBluetoothGattServiceClient*>(
1003 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
1004 gatt_service_client->HideHeartRateService();
1007 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
1008 DeviceRemoved(device_path));
1010 properties_map_.erase(iter);
1011 PairingOptionsMap::const_iterator options_iter =
1012 pairing_options_map_.find(device_path);
1014 if (options_iter != pairing_options_map_.end()) {
1015 pairing_options_map_.erase(options_iter);
1019 void FakeBluetoothDeviceClient::OnPropertyChanged(
1020 const dbus::ObjectPath& object_path,
1021 const std::string& property_name) {
1022 VLOG(2) << "Fake Bluetooth device property changed: " << object_path.value()
1023 << ": " << property_name;
1024 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
1025 DevicePropertyChanged(object_path, property_name));
1028 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
1029 if (!discovery_simulation_step_)
1030 return;
1032 // Timer fires every .75s, the numbers below are arbitrary to give a feel
1033 // for a discovery process.
1034 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_;
1035 if (discovery_simulation_step_ == 2) {
1036 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1037 dbus::ObjectPath(kLegacyAutopairPath));
1038 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1039 dbus::ObjectPath(kLowEnergyPath));
1041 } else if (discovery_simulation_step_ == 4) {
1042 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
1043 base::RandInt(kMinRSSI, kMaxRSSI));
1044 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1045 dbus::ObjectPath(kDisplayPinCodePath));
1046 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1047 dbus::ObjectPath(kVanishingDevicePath));
1049 } else if (discovery_simulation_step_ == 7) {
1050 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1051 dbus::ObjectPath(kConnectUnpairablePath));
1052 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
1053 base::RandInt(kMinRSSI, kMaxRSSI));
1055 } else if (discovery_simulation_step_ == 8) {
1056 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1057 dbus::ObjectPath(kDisplayPasskeyPath));
1058 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1059 dbus::ObjectPath(kRequestPinCodePath));
1060 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
1061 base::RandInt(kMinRSSI, kMaxRSSI));
1063 } else if (discovery_simulation_step_ == 10) {
1064 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1065 dbus::ObjectPath(kConfirmPasskeyPath));
1066 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1067 dbus::ObjectPath(kRequestPasskeyPath));
1068 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1069 dbus::ObjectPath(kUnconnectableDevicePath));
1070 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1071 dbus::ObjectPath(kUnpairableDevicePath));
1072 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1073 dbus::ObjectPath(kJustWorksPath));
1074 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
1075 base::RandInt(kMinRSSI, kMaxRSSI));
1077 } else if (discovery_simulation_step_ == 13) {
1078 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
1079 base::RandInt(kMinRSSI, kMaxRSSI));
1080 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1081 dbus::ObjectPath(kVanishingDevicePath));
1082 } else if (discovery_simulation_step_ == 14) {
1083 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
1084 base::RandInt(kMinRSSI, kMaxRSSI));
1085 return;
1089 ++discovery_simulation_step_;
1090 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1091 FROM_HERE,
1092 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
1093 base::Unretained(this)),
1094 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1097 void FakeBluetoothDeviceClient::IncomingPairingSimulationTimer() {
1098 if (!incoming_pairing_simulation_step_)
1099 return;
1101 VLOG(1) << "incoming pairing simulation, step "
1102 << incoming_pairing_simulation_step_;
1103 switch (incoming_pairing_simulation_step_) {
1104 case 1:
1105 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1106 dbus::ObjectPath(kConfirmPasskeyPath));
1107 SimulatePairing(dbus::ObjectPath(kConfirmPasskeyPath), true,
1108 base::Bind(&base::DoNothing),
1109 base::Bind(&SimpleErrorCallback));
1110 break;
1111 case 2:
1112 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1113 dbus::ObjectPath(kJustWorksPath));
1114 SimulatePairing(dbus::ObjectPath(kJustWorksPath), true,
1115 base::Bind(&base::DoNothing),
1116 base::Bind(&SimpleErrorCallback));
1117 break;
1118 case 3:
1119 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1120 dbus::ObjectPath(kDisplayPinCodePath));
1121 SimulatePairing(dbus::ObjectPath(kDisplayPinCodePath), true,
1122 base::Bind(&base::DoNothing),
1123 base::Bind(&SimpleErrorCallback));
1124 break;
1125 case 4:
1126 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1127 dbus::ObjectPath(kDisplayPasskeyPath));
1128 SimulatePairing(dbus::ObjectPath(kDisplayPasskeyPath), true,
1129 base::Bind(&base::DoNothing),
1130 base::Bind(&SimpleErrorCallback));
1131 break;
1132 case 5:
1133 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1134 dbus::ObjectPath(kRequestPinCodePath));
1135 SimulatePairing(dbus::ObjectPath(kRequestPinCodePath), true,
1136 base::Bind(&base::DoNothing),
1137 base::Bind(&SimpleErrorCallback));
1138 break;
1139 case 6:
1140 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1141 dbus::ObjectPath(kRequestPasskeyPath));
1142 SimulatePairing(dbus::ObjectPath(kRequestPasskeyPath), true,
1143 base::Bind(&base::DoNothing),
1144 base::Bind(&SimpleErrorCallback));
1145 break;
1146 default:
1147 return;
1150 ++incoming_pairing_simulation_step_;
1151 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1152 FROM_HERE,
1153 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
1154 base::Unretained(this)),
1155 base::TimeDelta::FromMilliseconds(kIncomingSimulationPairTimeMultiplier *
1156 simulation_interval_ms_));
1159 void FakeBluetoothDeviceClient::SimulatePairing(
1160 const dbus::ObjectPath& object_path,
1161 bool incoming_request,
1162 const base::Closure& callback,
1163 const ErrorCallback& error_callback) {
1164 pairing_cancelled_ = false;
1166 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
1167 static_cast<FakeBluetoothAgentManagerClient*>(
1168 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
1169 FakeBluetoothAgentServiceProvider* agent_service_provider =
1170 fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
1171 CHECK(agent_service_provider != NULL);
1173 // Grab the device's pairing properties.
1174 PairingOptionsMap::const_iterator iter =
1175 pairing_options_map_.find(object_path);
1177 // If the device with path |object_path| has simulated pairing properties
1178 // defined, then pair it based on its |pairing_method|.
1179 if (iter != pairing_options_map_.end()) {
1180 if (iter->second->pairing_action == kPairingActionFail) {
1181 // Fails the pairing with an org.bluez.Error.Failed error.
1182 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1183 FROM_HERE,
1184 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing,
1185 base::Unretained(this), object_path, error_callback),
1186 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1187 } else if (iter->second->pairing_method == kPairingMethodNone ||
1188 iter->second->pairing_method.empty()) {
1189 if (!iter->second->incoming) {
1190 // Simply pair and connect the device.
1191 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1192 FROM_HERE,
1193 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1194 base::Unretained(this), object_path, callback,
1195 error_callback),
1196 base::TimeDelta::FromMilliseconds(
1197 kSimulateNormalPairTimeMultiplier * simulation_interval_ms_));
1198 } else {
1199 agent_service_provider->RequestAuthorization(
1200 object_path,
1201 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
1202 base::Unretained(this), object_path, callback,
1203 error_callback));
1205 } else if (iter->second->pairing_method == kPairingMethodPinCode) {
1206 if (iter->second->pairing_action == kPairingActionDisplay) {
1207 // Display a Pincode, and wait before acting as if the other end
1208 // accepted it.
1209 agent_service_provider->DisplayPinCode(
1210 object_path, iter->second->pairing_auth_token);
1212 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1213 FROM_HERE,
1214 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1215 base::Unretained(this), object_path, callback,
1216 error_callback),
1217 base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier *
1218 simulation_interval_ms_));
1219 } else if (iter->second->pairing_action == kPairingActionRequest) {
1220 // Request a pin code.
1221 agent_service_provider->RequestPinCode(
1222 object_path, base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback,
1223 base::Unretained(this), object_path,
1224 callback, error_callback));
1225 } else if (iter->second->pairing_action == kPairingActionConfirmation) {
1226 error_callback.Run(kNoResponseError, "No confirm for pincode pairing.");
1228 } else if (iter->second->pairing_method == kPairingMethodPassKey) {
1229 // Display a passkey, and each interval act as if another key was entered
1230 // for it.
1231 if (iter->second->pairing_action == kPairingActionDisplay) {
1232 agent_service_provider->DisplayPasskey(
1233 object_path, std::stoi(iter->second->pairing_auth_token), 0);
1235 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1236 FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
1237 base::Unretained(this), 1, object_path,
1238 callback, error_callback),
1239 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1240 } else if (iter->second->pairing_action == kPairingActionRequest) {
1241 agent_service_provider->RequestPasskey(
1242 object_path, base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback,
1243 base::Unretained(this), object_path,
1244 callback, error_callback));
1245 } else if (iter->second->pairing_action == kPairingActionConfirmation) {
1246 agent_service_provider->RequestConfirmation(
1247 object_path, std::stoi(iter->second->pairing_auth_token),
1248 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
1249 base::Unretained(this), object_path, callback,
1250 error_callback));
1253 } else {
1254 if (object_path == dbus::ObjectPath(kLegacyAutopairPath) ||
1255 object_path == dbus::ObjectPath(kConnectUnpairablePath) ||
1256 object_path == dbus::ObjectPath(kUnconnectableDevicePath) ||
1257 object_path == dbus::ObjectPath(kLowEnergyPath)) {
1258 // No need to call anything on the pairing delegate, just wait 3 times
1259 // the interval before acting as if the other end accepted it.
1260 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1261 FROM_HERE,
1262 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1263 base::Unretained(this), object_path, callback,
1264 error_callback),
1265 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
1266 simulation_interval_ms_));
1268 } else if (object_path == dbus::ObjectPath(kDisplayPinCodePath)) {
1269 // Display a Pincode, and wait before acting as if the other end accepted
1270 // it.
1271 agent_service_provider->DisplayPinCode(object_path, kTestPinCode);
1273 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1274 FROM_HERE,
1275 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1276 base::Unretained(this), object_path, callback,
1277 error_callback),
1278 base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier *
1279 simulation_interval_ms_));
1281 } else if (object_path == dbus::ObjectPath(kVanishingDevicePath)) {
1282 // The vanishing device simulates being too far away, and thus times out.
1283 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1284 FROM_HERE,
1285 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing,
1286 base::Unretained(this), object_path, error_callback),
1287 base::TimeDelta::FromMilliseconds(kVanishingDevicePairTimeMultiplier *
1288 simulation_interval_ms_));
1290 } else if (object_path == dbus::ObjectPath(kDisplayPasskeyPath)) {
1291 // Display a passkey, and each interval act as if another key was entered
1292 // for it.
1293 agent_service_provider->DisplayPasskey(object_path, kTestPassKey, 0);
1295 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1296 FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
1297 base::Unretained(this), 1, object_path,
1298 callback, error_callback),
1299 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1301 } else if (object_path == dbus::ObjectPath(kRequestPinCodePath)) {
1302 // Request a Pincode.
1303 agent_service_provider->RequestPinCode(
1304 object_path, base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback,
1305 base::Unretained(this), object_path, callback,
1306 error_callback));
1308 } else if (object_path == dbus::ObjectPath(kConfirmPasskeyPath)) {
1309 // Request confirmation of a Passkey.
1310 agent_service_provider->RequestConfirmation(
1311 object_path, kTestPassKey,
1312 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
1313 base::Unretained(this), object_path, callback,
1314 error_callback));
1316 } else if (object_path == dbus::ObjectPath(kRequestPasskeyPath)) {
1317 // Request a Passkey from the user.
1318 agent_service_provider->RequestPasskey(
1319 object_path, base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback,
1320 base::Unretained(this), object_path, callback,
1321 error_callback));
1323 } else if (object_path == dbus::ObjectPath(kUnpairableDevicePath)) {
1324 // Fails the pairing with an org.bluez.Error.Failed error.
1325 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1326 FROM_HERE,
1327 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing,
1328 base::Unretained(this), object_path, error_callback),
1329 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1331 } else if (object_path == dbus::ObjectPath(kJustWorksPath)) {
1332 if (incoming_request) {
1333 agent_service_provider->RequestAuthorization(
1334 object_path,
1335 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
1336 base::Unretained(this), object_path, callback,
1337 error_callback));
1339 } else {
1340 // No need to call anything on the pairing delegate, just wait before
1341 // acting as if the other end accepted it.
1342 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1343 FROM_HERE,
1344 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1345 base::Unretained(this), object_path, callback,
1346 error_callback),
1347 base::TimeDelta::FromMilliseconds(
1348 kSimulateNormalPairTimeMultiplier * simulation_interval_ms_));
1351 } else {
1352 error_callback.Run(kNoResponseError, "No pairing fake");
1357 void FakeBluetoothDeviceClient::CompleteSimulatedPairing(
1358 const dbus::ObjectPath& object_path,
1359 const base::Closure& callback,
1360 const ErrorCallback& error_callback) {
1361 VLOG(1) << "CompleteSimulatedPairing: " << object_path.value();
1362 if (pairing_cancelled_) {
1363 pairing_cancelled_ = false;
1365 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
1366 "Cancelled");
1367 } else {
1368 Properties* properties = GetProperties(object_path);
1370 properties->paired.ReplaceValue(true);
1371 callback.Run();
1373 AddInputDeviceIfNeeded(object_path, properties);
1377 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing(
1378 const dbus::ObjectPath& object_path,
1379 const ErrorCallback& error_callback) {
1380 VLOG(1) << "TimeoutSimulatedPairing: " << object_path.value();
1382 error_callback.Run(bluetooth_device::kErrorAuthenticationTimeout,
1383 "Timed out");
1386 void FakeBluetoothDeviceClient::CancelSimulatedPairing(
1387 const dbus::ObjectPath& object_path,
1388 const ErrorCallback& error_callback) {
1389 VLOG(1) << "CancelSimulatedPairing: " << object_path.value();
1391 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
1392 "Canceled");
1395 void FakeBluetoothDeviceClient::RejectSimulatedPairing(
1396 const dbus::ObjectPath& object_path,
1397 const ErrorCallback& error_callback) {
1398 VLOG(1) << "RejectSimulatedPairing: " << object_path.value();
1400 error_callback.Run(bluetooth_device::kErrorAuthenticationRejected,
1401 "Rejected");
1404 void FakeBluetoothDeviceClient::FailSimulatedPairing(
1405 const dbus::ObjectPath& object_path,
1406 const ErrorCallback& error_callback) {
1407 VLOG(1) << "FailSimulatedPairing: " << object_path.value();
1409 error_callback.Run(bluetooth_device::kErrorFailed, "Failed");
1412 void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded(
1413 const dbus::ObjectPath& object_path,
1414 Properties* properties) {
1415 // If the paired device is a HID device based on it's bluetooth class,
1416 // simulate the Input interface.
1417 FakeBluetoothInputClient* fake_bluetooth_input_client =
1418 static_cast<FakeBluetoothInputClient*>(
1419 DBusThreadManager::Get()->GetBluetoothInputClient());
1421 if ((properties->bluetooth_class.value() & 0x001f03) == 0x000500)
1422 fake_bluetooth_input_client->AddInputDevice(object_path);
1425 void FakeBluetoothDeviceClient::UpdateDeviceRSSI(
1426 const dbus::ObjectPath& object_path,
1427 int16 rssi) {
1428 PropertiesMap::const_iterator iter = properties_map_.find(object_path);
1429 if (iter == properties_map_.end()) {
1430 VLOG(2) << "Fake device does not exist: " << object_path.value();
1431 return;
1433 Properties* properties = iter->second;
1434 DCHECK(properties);
1435 properties->rssi.ReplaceValue(rssi);
1438 void FakeBluetoothDeviceClient::UpdateConnectionInfo(
1439 uint16 connection_rssi,
1440 uint16 transmit_power,
1441 uint16 max_transmit_power) {
1442 connection_rssi_ = connection_rssi;
1443 transmit_power_ = transmit_power;
1444 max_transmit_power_ = max_transmit_power;
1447 void FakeBluetoothDeviceClient::PinCodeCallback(
1448 const dbus::ObjectPath& object_path,
1449 const base::Closure& callback,
1450 const ErrorCallback& error_callback,
1451 BluetoothAgentServiceProvider::Delegate::Status status,
1452 const std::string& pincode) {
1453 VLOG(1) << "PinCodeCallback: " << object_path.value();
1455 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1456 PairingOptionsMap::const_iterator iter =
1457 pairing_options_map_.find(object_path);
1459 bool success = true;
1461 // If the device has pairing options defined
1462 if (iter != pairing_options_map_.end()) {
1463 success = iter->second->pairing_auth_token == pincode;
1466 if (success) {
1467 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1468 FROM_HERE,
1469 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1470 base::Unretained(this), object_path, callback,
1471 error_callback),
1472 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
1473 simulation_interval_ms_));
1474 } else {
1475 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1476 FROM_HERE,
1477 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1478 base::Unretained(this), object_path, error_callback),
1479 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1482 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1483 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1484 FROM_HERE,
1485 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1486 base::Unretained(this), object_path, error_callback),
1487 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1489 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1490 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1491 FROM_HERE,
1492 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1493 base::Unretained(this), object_path, error_callback),
1494 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1498 void FakeBluetoothDeviceClient::PasskeyCallback(
1499 const dbus::ObjectPath& object_path,
1500 const base::Closure& callback,
1501 const ErrorCallback& error_callback,
1502 BluetoothAgentServiceProvider::Delegate::Status status,
1503 uint32 passkey) {
1504 VLOG(1) << "PasskeyCallback: " << object_path.value();
1506 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1507 PairingOptionsMap::const_iterator iter =
1508 pairing_options_map_.find(object_path);
1509 bool success = true;
1511 if (iter != pairing_options_map_.end()) {
1512 success = static_cast<uint32>(
1513 std::stoi(iter->second->pairing_auth_token)) == passkey;
1516 if (success) {
1517 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1518 FROM_HERE,
1519 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1520 base::Unretained(this), object_path, callback,
1521 error_callback),
1522 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
1523 simulation_interval_ms_));
1524 } else {
1525 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1526 FROM_HERE,
1527 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1528 base::Unretained(this), object_path, error_callback),
1529 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1532 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1533 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1534 FROM_HERE,
1535 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1536 base::Unretained(this), object_path, error_callback),
1537 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1539 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1540 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1541 FROM_HERE,
1542 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1543 base::Unretained(this), object_path, error_callback),
1544 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1548 void FakeBluetoothDeviceClient::ConfirmationCallback(
1549 const dbus::ObjectPath& object_path,
1550 const base::Closure& callback,
1551 const ErrorCallback& error_callback,
1552 BluetoothAgentServiceProvider::Delegate::Status status) {
1553 VLOG(1) << "ConfirmationCallback: " << object_path.value();
1555 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1556 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1557 FROM_HERE,
1558 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1559 base::Unretained(this), object_path, callback,
1560 error_callback),
1561 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
1562 simulation_interval_ms_));
1564 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1565 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1566 FROM_HERE,
1567 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1568 base::Unretained(this), object_path, error_callback),
1569 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1571 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1572 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1573 FROM_HERE,
1574 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1575 base::Unretained(this), object_path, error_callback),
1576 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1580 void FakeBluetoothDeviceClient::SimulateKeypress(
1581 uint16 entered,
1582 const dbus::ObjectPath& object_path,
1583 const base::Closure& callback,
1584 const ErrorCallback& error_callback) {
1585 VLOG(1) << "SimulateKeypress " << entered << ": " << object_path.value();
1587 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
1588 static_cast<FakeBluetoothAgentManagerClient*>(
1589 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
1590 FakeBluetoothAgentServiceProvider* agent_service_provider =
1591 fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
1593 // The agent service provider object could have been destroyed after the
1594 // pairing is canceled.
1595 if (!agent_service_provider)
1596 return;
1598 agent_service_provider->DisplayPasskey(object_path, kTestPassKey, entered);
1600 if (entered < 7) {
1601 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1602 FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
1603 base::Unretained(this), entered + 1, object_path,
1604 callback, error_callback),
1605 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1607 } else {
1608 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1609 FROM_HERE,
1610 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1611 base::Unretained(this), object_path, callback,
1612 error_callback),
1613 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1617 void FakeBluetoothDeviceClient::ConnectionCallback(
1618 const dbus::ObjectPath& object_path,
1619 const base::Closure& callback,
1620 const ErrorCallback& error_callback,
1621 BluetoothProfileServiceProvider::Delegate::Status status) {
1622 VLOG(1) << "ConnectionCallback: " << object_path.value();
1624 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
1625 callback.Run();
1626 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
1627 // TODO(keybuk): tear down this side of the connection
1628 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
1629 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
1630 // TODO(keybuk): tear down this side of the connection
1631 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
1635 void FakeBluetoothDeviceClient::DisconnectionCallback(
1636 const dbus::ObjectPath& object_path,
1637 const base::Closure& callback,
1638 const ErrorCallback& error_callback,
1639 BluetoothProfileServiceProvider::Delegate::Status status) {
1640 VLOG(1) << "DisconnectionCallback: " << object_path.value();
1642 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
1643 // TODO(keybuk): tear down this side of the connection
1644 callback.Run();
1645 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
1646 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
1647 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
1648 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
1652 } // namespace chromeos