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