Use PlaybackToMemory for BitmapRasterWorkerPool playback
[chromium-blink-merge.git] / chromeos / dbus / fake_bluetooth_device_client.cc
blob87b6591d9315fdfbf17977704b8ef125e4414c1b
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 <unistd.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
12 #include <algorithm>
13 #include <map>
14 #include <string>
15 #include <utility>
16 #include <vector>
18 #include "base/bind.h"
19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/message_loop/message_loop.h"
22 #include "base/rand_util.h"
23 #include "base/stl_util.h"
24 #include "base/threading/worker_pool.h"
25 #include "base/time/time.h"
26 #include "chromeos/dbus/dbus_thread_manager.h"
27 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
28 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
29 #include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
30 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
31 #include "chromeos/dbus/fake_bluetooth_input_client.h"
32 #include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
33 #include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
34 #include "dbus/file_descriptor.h"
35 #include "dbus/object_path.h"
36 #include "third_party/cros_system_api/dbus/service_constants.h"
38 namespace {
40 // Default interval between simulated events.
41 const int kSimulationIntervalMs = 750;
43 // Minimum and maximum bounds for randomly generated RSSI values.
44 const int kMinRSSI = -90;
45 const int kMaxRSSI = -30;
48 void SimulatedProfileSocket(int fd) {
49 // Simulate a server-side socket of a profile; read data from the socket,
50 // write it back, and then close.
51 char buf[1024];
52 ssize_t len;
53 ssize_t count;
55 len = read(fd, buf, sizeof buf);
56 if (len < 0) {
57 close(fd);
58 return;
61 count = len;
62 len = write(fd, buf, count);
63 if (len < 0) {
64 close(fd);
65 return;
68 close(fd);
71 void SimpleErrorCallback(const std::string& error_name,
72 const std::string& error_message) {
73 VLOG(1) << "Bluetooth Error: " << error_name << ": " << error_message;
76 } // namespace
78 namespace chromeos {
80 const char FakeBluetoothDeviceClient::kPairedDevicePath[] =
81 "/fake/hci0/dev0";
82 const char FakeBluetoothDeviceClient::kPairedDeviceAddress[] =
83 "00:11:22:33:44:55";
84 const char FakeBluetoothDeviceClient::kPairedDeviceName[] =
85 "Fake Device";
86 const uint32 FakeBluetoothDeviceClient::kPairedDeviceClass = 0x000104;
88 const char FakeBluetoothDeviceClient::kLegacyAutopairPath[] =
89 "/fake/hci0/dev1";
90 const char FakeBluetoothDeviceClient::kLegacyAutopairAddress[] =
91 "28:CF:DA:00:00:00";
92 const char FakeBluetoothDeviceClient::kLegacyAutopairName[] =
93 "Bluetooth 2.0 Mouse";
94 const uint32 FakeBluetoothDeviceClient::kLegacyAutopairClass = 0x002580;
96 const char FakeBluetoothDeviceClient::kDisplayPinCodePath[] =
97 "/fake/hci0/dev2";
98 const char FakeBluetoothDeviceClient::kDisplayPinCodeAddress[] =
99 "28:37:37:00:00:00";
100 const char FakeBluetoothDeviceClient::kDisplayPinCodeName[] =
101 "Bluetooth 2.0 Keyboard";
102 const uint32 FakeBluetoothDeviceClient::kDisplayPinCodeClass = 0x002540;
104 const char FakeBluetoothDeviceClient::kVanishingDevicePath[] =
105 "/fake/hci0/dev3";
106 const char FakeBluetoothDeviceClient::kVanishingDeviceAddress[] =
107 "01:02:03:04:05:06";
108 const char FakeBluetoothDeviceClient::kVanishingDeviceName[] =
109 "Vanishing Device";
110 const uint32 FakeBluetoothDeviceClient::kVanishingDeviceClass = 0x000104;
112 const char FakeBluetoothDeviceClient::kConnectUnpairablePath[] =
113 "/fake/hci0/dev4";
114 const char FakeBluetoothDeviceClient::kConnectUnpairableAddress[] =
115 "7C:ED:8D:00:00:00";
116 const char FakeBluetoothDeviceClient::kConnectUnpairableName[] =
117 "Unpairable Device";
118 const uint32 FakeBluetoothDeviceClient::kConnectUnpairableClass = 0x002580;
120 const char FakeBluetoothDeviceClient::kDisplayPasskeyPath[] =
121 "/fake/hci0/dev5";
122 const char FakeBluetoothDeviceClient::kDisplayPasskeyAddress[] =
123 "00:0F:F6:00:00:00";
124 const char FakeBluetoothDeviceClient::kDisplayPasskeyName[] =
125 "Bluetooth 2.1+ Keyboard";
126 const uint32 FakeBluetoothDeviceClient::kDisplayPasskeyClass = 0x002540;
128 const char FakeBluetoothDeviceClient::kRequestPinCodePath[] =
129 "/fake/hci0/dev6";
130 const char FakeBluetoothDeviceClient::kRequestPinCodeAddress[] =
131 "00:24:BE:00:00:00";
132 const char FakeBluetoothDeviceClient::kRequestPinCodeName[] =
133 "PIN Device";
134 const uint32 FakeBluetoothDeviceClient::kRequestPinCodeClass = 0x240408;
136 const char FakeBluetoothDeviceClient::kConfirmPasskeyPath[] =
137 "/fake/hci0/dev7";
138 const char FakeBluetoothDeviceClient::kConfirmPasskeyAddress[] =
139 "20:7D:74:00:00:00";
140 const char FakeBluetoothDeviceClient::kConfirmPasskeyName[] =
141 "Phone";
142 const uint32 FakeBluetoothDeviceClient::kConfirmPasskeyClass = 0x7a020c;
144 const char FakeBluetoothDeviceClient::kRequestPasskeyPath[] =
145 "/fake/hci0/dev8";
146 const char FakeBluetoothDeviceClient::kRequestPasskeyAddress[] =
147 "20:7D:74:00:00:01";
148 const char FakeBluetoothDeviceClient::kRequestPasskeyName[] =
149 "Passkey Device";
150 const uint32 FakeBluetoothDeviceClient::kRequestPasskeyClass = 0x7a020c;
152 const char FakeBluetoothDeviceClient::kUnconnectableDevicePath[] =
153 "/fake/hci0/dev9";
154 const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress[] =
155 "20:7D:74:00:00:02";
156 const char FakeBluetoothDeviceClient::kUnconnectableDeviceName[] =
157 "Unconnectable Device";
158 const uint32 FakeBluetoothDeviceClient::kUnconnectableDeviceClass = 0x7a020c;
160 const char FakeBluetoothDeviceClient::kUnpairableDevicePath[] =
161 "/fake/hci0/devA";
162 const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress[] =
163 "20:7D:74:00:00:03";
164 const char FakeBluetoothDeviceClient::kUnpairableDeviceName[] =
165 "Unpairable Device";
166 const uint32 FakeBluetoothDeviceClient::kUnpairableDeviceClass = 0x002540;
168 const char FakeBluetoothDeviceClient::kJustWorksPath[] =
169 "/fake/hci0/devB";
170 const char FakeBluetoothDeviceClient::kJustWorksAddress[] =
171 "00:0C:8A:00:00:00";
172 const char FakeBluetoothDeviceClient::kJustWorksName[] =
173 "Just-Works Device";
174 const uint32 FakeBluetoothDeviceClient::kJustWorksClass = 0x240428;
176 const char FakeBluetoothDeviceClient::kLowEnergyPath[] =
177 "/fake/hci0/devC";
178 const char FakeBluetoothDeviceClient::kLowEnergyAddress[] =
179 "00:1A:11:00:15:30";
180 const char FakeBluetoothDeviceClient::kLowEnergyName[] =
181 "Bluetooth 4.0 Heart Rate Monitor";
182 const uint32 FakeBluetoothDeviceClient::kLowEnergyClass =
183 0x000918; // Major class "Health", Minor class "Heart/Pulse Rate Monitor."
185 FakeBluetoothDeviceClient::Properties::Properties(
186 const PropertyChangedCallback& callback)
187 : BluetoothDeviceClient::Properties(
188 NULL,
189 bluetooth_device::kBluetoothDeviceInterface,
190 callback) {
193 FakeBluetoothDeviceClient::Properties::~Properties() {
196 void FakeBluetoothDeviceClient::Properties::Get(
197 dbus::PropertyBase* property,
198 dbus::PropertySet::GetCallback callback) {
199 VLOG(1) << "Get " << property->name();
200 callback.Run(false);
203 void FakeBluetoothDeviceClient::Properties::GetAll() {
204 VLOG(1) << "GetAll";
207 void FakeBluetoothDeviceClient::Properties::Set(
208 dbus::PropertyBase *property,
209 dbus::PropertySet::SetCallback callback) {
210 VLOG(1) << "Set " << property->name();
211 if (property->name() == trusted.name()) {
212 callback.Run(true);
213 property->ReplaceValueWithSetValue();
214 } else {
215 callback.Run(false);
219 FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
220 : simulation_interval_ms_(kSimulationIntervalMs),
221 discovery_simulation_step_(0),
222 incoming_pairing_simulation_step_(0),
223 pairing_cancelled_(false),
224 connection_monitor_started_(false) {
225 Properties* properties = new Properties(base::Bind(
226 &FakeBluetoothDeviceClient::OnPropertyChanged,
227 base::Unretained(this),
228 dbus::ObjectPath(kPairedDevicePath)));
229 properties->address.ReplaceValue(kPairedDeviceAddress);
230 properties->bluetooth_class.ReplaceValue(kPairedDeviceClass);
231 properties->name.ReplaceValue("Fake Device (Name)");
232 properties->alias.ReplaceValue(kPairedDeviceName);
233 properties->paired.ReplaceValue(true);
234 properties->trusted.ReplaceValue(true);
235 properties->adapter.ReplaceValue(
236 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
238 std::vector<std::string> uuids;
239 uuids.push_back("00001800-0000-1000-8000-00805f9b34fb");
240 uuids.push_back("00001801-0000-1000-8000-00805f9b34fb");
241 properties->uuids.ReplaceValue(uuids);
243 properties->modalias.ReplaceValue("usb:v05ACp030Dd0306");
245 properties_map_[dbus::ObjectPath(kPairedDevicePath)] = properties;
246 device_list_.push_back(dbus::ObjectPath(kPairedDevicePath));
249 FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() {
250 // Clean up Properties structures
251 STLDeleteValues(&properties_map_);
254 void FakeBluetoothDeviceClient::Init(dbus::Bus* bus) {
257 void FakeBluetoothDeviceClient::AddObserver(Observer* observer) {
258 observers_.AddObserver(observer);
261 void FakeBluetoothDeviceClient::RemoveObserver(Observer* observer) {
262 observers_.RemoveObserver(observer);
265 std::vector<dbus::ObjectPath> FakeBluetoothDeviceClient::GetDevicesForAdapter(
266 const dbus::ObjectPath& adapter_path) {
267 if (adapter_path ==
268 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath))
269 return device_list_;
270 else
271 return std::vector<dbus::ObjectPath>();
274 FakeBluetoothDeviceClient::Properties*
275 FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath& object_path) {
276 PropertiesMap::iterator iter = properties_map_.find(object_path);
277 if (iter != properties_map_.end())
278 return iter->second;
279 return NULL;
282 void FakeBluetoothDeviceClient::Connect(
283 const dbus::ObjectPath& object_path,
284 const base::Closure& callback,
285 const ErrorCallback& error_callback) {
286 VLOG(1) << "Connect: " << object_path.value();
287 Properties* properties = GetProperties(object_path);
289 if (properties->connected.value() == true) {
290 // Already connected.
291 callback.Run();
292 return;
295 if (properties->paired.value() != true &&
296 object_path != dbus::ObjectPath(kConnectUnpairablePath) &&
297 object_path != dbus::ObjectPath(kLowEnergyPath)) {
298 // Must be paired.
299 error_callback.Run(bluetooth_device::kErrorFailed, "Not paired");
300 return;
301 } else if (properties->paired.value() == true &&
302 object_path == dbus::ObjectPath(kUnconnectableDevicePath)) {
303 // Must not be paired
304 error_callback.Run(bluetooth_device::kErrorFailed,
305 "Connection fails while paired");
306 return;
309 // The device can be connected.
310 properties->connected.ReplaceValue(true);
311 callback.Run();
313 // Expose GATT services if connected to LE device.
314 if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
315 FakeBluetoothGattServiceClient* gatt_service_client =
316 static_cast<FakeBluetoothGattServiceClient*>(
317 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
318 gatt_service_client->ExposeHeartRateService(
319 dbus::ObjectPath(kLowEnergyPath));
322 AddInputDeviceIfNeeded(object_path, properties);
325 void FakeBluetoothDeviceClient::Disconnect(
326 const dbus::ObjectPath& object_path,
327 const base::Closure& callback,
328 const ErrorCallback& error_callback) {
329 VLOG(1) << "Disconnect: " << object_path.value();
330 Properties* properties = GetProperties(object_path);
332 if (!properties->connected.value()) {
333 error_callback.Run("org.bluez.Error.NotConnected", "Not Connected");
334 return;
337 // Hide the Heart Rate Service if disconnected from LE device.
338 if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
339 FakeBluetoothGattServiceClient* gatt_service_client =
340 static_cast<FakeBluetoothGattServiceClient*>(
341 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
342 gatt_service_client->HideHeartRateService();
345 callback.Run();
346 properties->connected.ReplaceValue(false);
349 void FakeBluetoothDeviceClient::ConnectProfile(
350 const dbus::ObjectPath& object_path,
351 const std::string& uuid,
352 const base::Closure& callback,
353 const ErrorCallback& error_callback) {
354 VLOG(1) << "ConnectProfile: " << object_path.value() << " " << uuid;
356 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
357 static_cast<FakeBluetoothProfileManagerClient*>(
358 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
359 FakeBluetoothProfileServiceProvider* profile_service_provider =
360 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
361 if (profile_service_provider == NULL) {
362 error_callback.Run(kNoResponseError, "Missing profile");
363 return;
366 // Make a socket pair of a compatible type with the type used by Bluetooth;
367 // spin up a thread to simulate the server side and wrap the client side in
368 // a D-Bus file descriptor object.
369 int socket_type = SOCK_STREAM;
370 if (uuid == FakeBluetoothProfileManagerClient::kL2capUuid)
371 socket_type = SOCK_SEQPACKET;
373 int fds[2];
374 if (socketpair(AF_UNIX, socket_type, 0, fds) < 0) {
375 error_callback.Run(kNoResponseError, "socketpair call failed");
376 return;
379 int args;
380 args = fcntl(fds[1], F_GETFL, NULL);
381 if (args < 0) {
382 error_callback.Run(kNoResponseError, "failed to get socket flags");
383 return;
386 args |= O_NONBLOCK;
387 if (fcntl(fds[1], F_SETFL, args) < 0) {
388 error_callback.Run(kNoResponseError, "failed to set socket non-blocking");
389 return;
392 base::WorkerPool::GetTaskRunner(false)->PostTask(
393 FROM_HERE,
394 base::Bind(&SimulatedProfileSocket,
395 fds[0]));
397 scoped_ptr<dbus::FileDescriptor> fd(new dbus::FileDescriptor(fds[1]));
399 // Post the new connection to the service provider.
400 BluetoothProfileServiceProvider::Delegate::Options options;
402 profile_service_provider->NewConnection(
403 object_path,
404 fd.Pass(),
405 options,
406 base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback,
407 base::Unretained(this),
408 object_path,
409 callback,
410 error_callback));
413 void FakeBluetoothDeviceClient::DisconnectProfile(
414 const dbus::ObjectPath& object_path,
415 const std::string& uuid,
416 const base::Closure& callback,
417 const ErrorCallback& error_callback) {
418 VLOG(1) << "DisconnectProfile: " << object_path.value() << " " << uuid;
420 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
421 static_cast<FakeBluetoothProfileManagerClient*>(
422 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
423 FakeBluetoothProfileServiceProvider* profile_service_provider =
424 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
425 if (profile_service_provider == NULL) {
426 error_callback.Run(kNoResponseError, "Missing profile");
427 return;
430 profile_service_provider->RequestDisconnection(
431 object_path,
432 base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback,
433 base::Unretained(this),
434 object_path,
435 callback,
436 error_callback));
439 void FakeBluetoothDeviceClient::Pair(
440 const dbus::ObjectPath& object_path,
441 const base::Closure& callback,
442 const ErrorCallback& error_callback) {
443 VLOG(1) << "Pair: " << object_path.value();
444 Properties* properties = GetProperties(object_path);
446 if (properties->paired.value() == true) {
447 // Already paired.
448 callback.Run();
449 return;
452 SimulatePairing(object_path, false, callback, error_callback);
455 void FakeBluetoothDeviceClient::CancelPairing(
456 const dbus::ObjectPath& object_path,
457 const base::Closure& callback,
458 const ErrorCallback& error_callback) {
459 VLOG(1) << "CancelPairing: " << object_path.value();
460 pairing_cancelled_ = true;
461 callback.Run();
464 void FakeBluetoothDeviceClient::StartConnectionMonitor(
465 const dbus::ObjectPath& object_path,
466 const base::Closure& callback,
467 const ErrorCallback& error_callback) {
468 VLOG(1) << "StartConnectionMonitor: " << object_path.value();
469 connection_monitor_started_ = true;
470 callback.Run();
473 void FakeBluetoothDeviceClient::StopConnectionMonitor(
474 const dbus::ObjectPath& object_path,
475 const base::Closure& callback,
476 const ErrorCallback& error_callback) {
477 connection_monitor_started_ = false;
478 callback.Run();
481 void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
482 const dbus::ObjectPath& adapter_path) {
483 VLOG(1) << "starting discovery simulation";
485 discovery_simulation_step_ = 1;
487 base::MessageLoop::current()->PostDelayedTask(
488 FROM_HERE,
489 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
490 base::Unretained(this)),
491 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
494 void FakeBluetoothDeviceClient::EndDiscoverySimulation(
495 const dbus::ObjectPath& adapter_path) {
496 VLOG(1) << "stopping discovery simulation";
497 discovery_simulation_step_ = 0;
500 void FakeBluetoothDeviceClient::BeginIncomingPairingSimulation(
501 const dbus::ObjectPath& adapter_path) {
502 VLOG(1) << "starting incoming pairing simulation";
504 incoming_pairing_simulation_step_ = 1;
506 base::MessageLoop::current()->PostDelayedTask(
507 FROM_HERE,
508 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
509 base::Unretained(this)),
510 base::TimeDelta::FromMilliseconds(30 * simulation_interval_ms_));
513 void FakeBluetoothDeviceClient::EndIncomingPairingSimulation(
514 const dbus::ObjectPath& adapter_path) {
515 VLOG(1) << "stopping incoming pairing simulation";
516 incoming_pairing_simulation_step_ = 0;
519 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms) {
520 simulation_interval_ms_ = interval_ms;
523 void FakeBluetoothDeviceClient::CreateDevice(
524 const dbus::ObjectPath& adapter_path,
525 const dbus::ObjectPath& device_path) {
526 if (std::find(device_list_.begin(),
527 device_list_.end(), device_path) != device_list_.end())
528 return;
530 Properties* properties = new Properties(base::Bind(
531 &FakeBluetoothDeviceClient::OnPropertyChanged,
532 base::Unretained(this),
533 device_path));
534 properties->adapter.ReplaceValue(adapter_path);
536 if (device_path == dbus::ObjectPath(kLegacyAutopairPath)) {
537 properties->address.ReplaceValue(kLegacyAutopairAddress);
538 properties->bluetooth_class.ReplaceValue(kLegacyAutopairClass);
539 properties->name.ReplaceValue("LegacyAutopair");
540 properties->alias.ReplaceValue(kLegacyAutopairName);
542 std::vector<std::string> uuids;
543 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
544 properties->uuids.ReplaceValue(uuids);
546 } else if (device_path == dbus::ObjectPath(kDisplayPinCodePath)) {
547 properties->address.ReplaceValue(kDisplayPinCodeAddress);
548 properties->bluetooth_class.ReplaceValue(kDisplayPinCodeClass);
549 properties->name.ReplaceValue("DisplayPinCode");
550 properties->alias.ReplaceValue(kDisplayPinCodeName);
552 std::vector<std::string> uuids;
553 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
554 properties->uuids.ReplaceValue(uuids);
556 } else if (device_path == dbus::ObjectPath(kVanishingDevicePath)) {
557 properties->address.ReplaceValue(kVanishingDeviceAddress);
558 properties->bluetooth_class.ReplaceValue(kVanishingDeviceClass);
559 properties->name.ReplaceValue("VanishingDevice");
560 properties->alias.ReplaceValue(kVanishingDeviceName);
562 } else if (device_path == dbus::ObjectPath(kConnectUnpairablePath)) {
563 properties->address.ReplaceValue(kConnectUnpairableAddress);
564 properties->bluetooth_class.ReplaceValue(kConnectUnpairableClass);
565 properties->name.ReplaceValue("ConnectUnpairable");
566 properties->alias.ReplaceValue(kConnectUnpairableName);
568 std::vector<std::string> uuids;
569 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
570 properties->uuids.ReplaceValue(uuids);
572 } else if (device_path == dbus::ObjectPath(kDisplayPasskeyPath)) {
573 properties->address.ReplaceValue(kDisplayPasskeyAddress);
574 properties->bluetooth_class.ReplaceValue(kDisplayPasskeyClass);
575 properties->name.ReplaceValue("DisplayPasskey");
576 properties->alias.ReplaceValue(kDisplayPasskeyName);
578 std::vector<std::string> uuids;
579 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
580 properties->uuids.ReplaceValue(uuids);
582 } else if (device_path == dbus::ObjectPath(kRequestPinCodePath)) {
583 properties->address.ReplaceValue(kRequestPinCodeAddress);
584 properties->bluetooth_class.ReplaceValue(kRequestPinCodeClass);
585 properties->name.ReplaceValue("RequestPinCode");
586 properties->alias.ReplaceValue(kRequestPinCodeName);
588 } else if (device_path == dbus::ObjectPath(kConfirmPasskeyPath)) {
589 properties->address.ReplaceValue(kConfirmPasskeyAddress);
590 properties->bluetooth_class.ReplaceValue(kConfirmPasskeyClass);
591 properties->name.ReplaceValue("ConfirmPasskey");
592 properties->alias.ReplaceValue(kConfirmPasskeyName);
594 } else if (device_path == dbus::ObjectPath(kRequestPasskeyPath)) {
595 properties->address.ReplaceValue(kRequestPasskeyAddress);
596 properties->bluetooth_class.ReplaceValue(kRequestPasskeyClass);
597 properties->name.ReplaceValue("RequestPasskey");
598 properties->alias.ReplaceValue(kRequestPasskeyName);
600 } else if (device_path == dbus::ObjectPath(kUnconnectableDevicePath)) {
601 properties->address.ReplaceValue(kUnconnectableDeviceAddress);
602 properties->bluetooth_class.ReplaceValue(kUnconnectableDeviceClass);
603 properties->name.ReplaceValue("UnconnectableDevice");
604 properties->alias.ReplaceValue(kUnconnectableDeviceName);
606 } else if (device_path == dbus::ObjectPath(kUnpairableDevicePath)) {
607 properties->address.ReplaceValue(kUnpairableDeviceAddress);
608 properties->bluetooth_class.ReplaceValue(kUnpairableDeviceClass);
609 properties->name.ReplaceValue("Fake Unpairable Device");
610 properties->alias.ReplaceValue(kUnpairableDeviceName);
612 } else if (device_path == dbus::ObjectPath(kJustWorksPath)) {
613 properties->address.ReplaceValue(kJustWorksAddress);
614 properties->bluetooth_class.ReplaceValue(kJustWorksClass);
615 properties->name.ReplaceValue("JustWorks");
616 properties->alias.ReplaceValue(kJustWorksName);
618 } else if (device_path == dbus::ObjectPath(kLowEnergyPath)) {
619 properties->address.ReplaceValue(kLowEnergyAddress);
620 properties->bluetooth_class.ReplaceValue(kLowEnergyClass);
621 properties->name.ReplaceValue("Heart Rate Monitor");
622 properties->alias.ReplaceValue(kLowEnergyName);
624 std::vector<std::string> uuids;
625 uuids.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID);
626 properties->uuids.ReplaceValue(uuids);
628 } else {
629 NOTREACHED();
633 properties_map_[device_path] = properties;
634 device_list_.push_back(device_path);
635 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
636 DeviceAdded(device_path));
639 void FakeBluetoothDeviceClient::RemoveDevice(
640 const dbus::ObjectPath& adapter_path,
641 const dbus::ObjectPath& device_path) {
642 std::vector<dbus::ObjectPath>::iterator listiter =
643 std::find(device_list_.begin(), device_list_.end(), device_path);
644 if (listiter == device_list_.end())
645 return;
647 PropertiesMap::iterator iter = properties_map_.find(device_path);
648 Properties* properties = iter->second;
650 VLOG(1) << "removing device: " << properties->alias.value();
651 device_list_.erase(listiter);
653 // Remove the Input interface if it exists. This should be called before the
654 // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
655 // BluetoothDeviceChromeOS object, including the device_path referenced here.
656 FakeBluetoothInputClient* fake_bluetooth_input_client =
657 static_cast<FakeBluetoothInputClient*>(
658 DBusThreadManager::Get()->GetBluetoothInputClient());
659 fake_bluetooth_input_client->RemoveInputDevice(device_path);
661 if (device_path == dbus::ObjectPath(kLowEnergyPath)) {
662 FakeBluetoothGattServiceClient* gatt_service_client =
663 static_cast<FakeBluetoothGattServiceClient*>(
664 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
665 gatt_service_client->HideHeartRateService();
668 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
669 DeviceRemoved(device_path));
671 delete properties;
672 properties_map_.erase(iter);
675 void FakeBluetoothDeviceClient::OnPropertyChanged(
676 const dbus::ObjectPath& object_path,
677 const std::string& property_name) {
678 VLOG(2) << "Fake Bluetooth device property changed: " << object_path.value()
679 << ": " << property_name;
680 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
681 DevicePropertyChanged(object_path, property_name));
684 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
685 if (!discovery_simulation_step_)
686 return;
688 // Timer fires every .75s, the numbers below are arbitrary to give a feel
689 // for a discovery process.
690 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_;
691 if (discovery_simulation_step_ == 2) {
692 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
693 dbus::ObjectPath(kLegacyAutopairPath));
694 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
695 dbus::ObjectPath(kLowEnergyPath));
697 } else if (discovery_simulation_step_ == 4) {
698 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
699 base::RandInt(kMinRSSI, kMaxRSSI));
700 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
701 dbus::ObjectPath(kDisplayPinCodePath));
702 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
703 dbus::ObjectPath(kVanishingDevicePath));
705 } else if (discovery_simulation_step_ == 7) {
706 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
707 dbus::ObjectPath(kConnectUnpairablePath));
708 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
709 base::RandInt(kMinRSSI, kMaxRSSI));
711 } else if (discovery_simulation_step_ == 8) {
712 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
713 dbus::ObjectPath(kDisplayPasskeyPath));
714 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
715 dbus::ObjectPath(kRequestPinCodePath));
716 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
717 base::RandInt(kMinRSSI, kMaxRSSI));
719 } else if (discovery_simulation_step_ == 10) {
720 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
721 dbus::ObjectPath(kConfirmPasskeyPath));
722 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
723 dbus::ObjectPath(kRequestPasskeyPath));
724 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
725 dbus::ObjectPath(kUnconnectableDevicePath));
726 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
727 dbus::ObjectPath(kUnpairableDevicePath));
728 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
729 dbus::ObjectPath(kJustWorksPath));
730 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
731 base::RandInt(kMinRSSI, kMaxRSSI));
733 } else if (discovery_simulation_step_ == 13) {
734 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
735 base::RandInt(kMinRSSI, kMaxRSSI));
736 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
737 dbus::ObjectPath(kVanishingDevicePath));
739 } else if (discovery_simulation_step_ == 14) {
740 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
741 base::RandInt(kMinRSSI, kMaxRSSI));
742 return;
746 ++discovery_simulation_step_;
747 base::MessageLoop::current()->PostDelayedTask(
748 FROM_HERE,
749 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
750 base::Unretained(this)),
751 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
754 void FakeBluetoothDeviceClient::IncomingPairingSimulationTimer() {
755 if (!incoming_pairing_simulation_step_)
756 return;
758 VLOG(1) << "incoming pairing simulation, step "
759 << incoming_pairing_simulation_step_;
760 switch (incoming_pairing_simulation_step_) {
761 case 1:
762 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
763 dbus::ObjectPath(kConfirmPasskeyPath));
764 SimulatePairing(dbus::ObjectPath(kConfirmPasskeyPath), true,
765 base::Bind(&base::DoNothing),
766 base::Bind(&SimpleErrorCallback));
767 break;
768 case 2:
769 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
770 dbus::ObjectPath(kJustWorksPath));
771 SimulatePairing(dbus::ObjectPath(kJustWorksPath), true,
772 base::Bind(&base::DoNothing),
773 base::Bind(&SimpleErrorCallback));
774 break;
775 case 3:
776 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
777 dbus::ObjectPath(kDisplayPinCodePath));
778 SimulatePairing(dbus::ObjectPath(kDisplayPinCodePath), true,
779 base::Bind(&base::DoNothing),
780 base::Bind(&SimpleErrorCallback));
781 break;
782 case 4:
783 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
784 dbus::ObjectPath(kDisplayPasskeyPath));
785 SimulatePairing(dbus::ObjectPath(kDisplayPasskeyPath), true,
786 base::Bind(&base::DoNothing),
787 base::Bind(&SimpleErrorCallback));
788 break;
789 case 5:
790 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
791 dbus::ObjectPath(kRequestPinCodePath));
792 SimulatePairing(dbus::ObjectPath(kRequestPinCodePath), true,
793 base::Bind(&base::DoNothing),
794 base::Bind(&SimpleErrorCallback));
795 break;
796 case 6:
797 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
798 dbus::ObjectPath(kRequestPasskeyPath));
799 SimulatePairing(dbus::ObjectPath(kRequestPasskeyPath), true,
800 base::Bind(&base::DoNothing),
801 base::Bind(&SimpleErrorCallback));
802 break;
803 default:
804 return;
807 ++incoming_pairing_simulation_step_;
808 base::MessageLoop::current()->PostDelayedTask(
809 FROM_HERE,
810 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
811 base::Unretained(this)),
812 base::TimeDelta::FromMilliseconds(45 * simulation_interval_ms_));
815 void FakeBluetoothDeviceClient::SimulatePairing(
816 const dbus::ObjectPath& object_path,
817 bool incoming_request,
818 const base::Closure& callback,
819 const ErrorCallback& error_callback) {
820 pairing_cancelled_ = false;
822 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
823 static_cast<FakeBluetoothAgentManagerClient*>(
824 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
825 FakeBluetoothAgentServiceProvider* agent_service_provider =
826 fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
827 CHECK(agent_service_provider != NULL);
829 if (object_path == dbus::ObjectPath(kLegacyAutopairPath) ||
830 object_path == dbus::ObjectPath(kConnectUnpairablePath) ||
831 object_path == dbus::ObjectPath(kUnconnectableDevicePath) ||
832 object_path == dbus::ObjectPath(kLowEnergyPath)) {
833 // No need to call anything on the pairing delegate, just wait 3 times
834 // the interval before acting as if the other end accepted it.
835 base::MessageLoop::current()->PostDelayedTask(
836 FROM_HERE,
837 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
838 base::Unretained(this),
839 object_path, callback, error_callback),
840 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
842 } else if (object_path == dbus::ObjectPath(kDisplayPinCodePath)) {
843 // Display a Pincode, and wait 7 times the interval before acting as
844 // if the other end accepted it.
845 agent_service_provider->DisplayPinCode(object_path, "123456");
847 base::MessageLoop::current()->PostDelayedTask(
848 FROM_HERE,
849 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
850 base::Unretained(this),
851 object_path, callback, error_callback),
852 base::TimeDelta::FromMilliseconds(7 * simulation_interval_ms_));
854 } else if (object_path == dbus::ObjectPath(kVanishingDevicePath)) {
855 // The vanishing device simulates being too far away, and thus times out.
856 base::MessageLoop::current()->PostDelayedTask(
857 FROM_HERE,
858 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing,
859 base::Unretained(this),
860 object_path, error_callback),
861 base::TimeDelta::FromMilliseconds(4 * simulation_interval_ms_));
863 } else if (object_path == dbus::ObjectPath(kDisplayPasskeyPath)) {
864 // Display a passkey, and each interval act as if another key was entered
865 // for it.
866 agent_service_provider->DisplayPasskey(object_path, 123456, 0);
868 base::MessageLoop::current()->PostDelayedTask(
869 FROM_HERE,
870 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
871 base::Unretained(this),
872 1, object_path, callback, error_callback),
873 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
875 } else if (object_path == dbus::ObjectPath(kRequestPinCodePath)) {
876 // Request a Pincode.
877 agent_service_provider->RequestPinCode(
878 object_path,
879 base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback,
880 base::Unretained(this),
881 object_path,
882 callback,
883 error_callback));
885 } else if (object_path == dbus::ObjectPath(kConfirmPasskeyPath)) {
886 // Request confirmation of a Passkey.
887 agent_service_provider->RequestConfirmation(
888 object_path, 123456,
889 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
890 base::Unretained(this),
891 object_path,
892 callback,
893 error_callback));
895 } else if (object_path == dbus::ObjectPath(kRequestPasskeyPath)) {
896 // Request a Passkey from the user.
897 agent_service_provider->RequestPasskey(
898 object_path,
899 base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback,
900 base::Unretained(this),
901 object_path,
902 callback,
903 error_callback));
905 } else if (object_path == dbus::ObjectPath(kUnpairableDevicePath)) {
906 // Fails the pairing with an org.bluez.Error.Failed error.
907 base::MessageLoop::current()->PostDelayedTask(
908 FROM_HERE,
909 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing,
910 base::Unretained(this),
911 object_path, error_callback),
912 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
914 } else if (object_path == dbus::ObjectPath(kJustWorksPath)) {
915 if (incoming_request) {
916 agent_service_provider->RequestAuthorization(
917 object_path,
918 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
919 base::Unretained(this),
920 object_path,
921 callback,
922 error_callback));
924 } else {
925 // No need to call anything on the pairing delegate, just wait 3 times
926 // the interval before acting as if the other end accepted it.
927 base::MessageLoop::current()->PostDelayedTask(
928 FROM_HERE,
929 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
930 base::Unretained(this),
931 object_path, callback, error_callback),
932 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
936 } else {
937 error_callback.Run(kNoResponseError, "No pairing fake");
941 void FakeBluetoothDeviceClient::CompleteSimulatedPairing(
942 const dbus::ObjectPath& object_path,
943 const base::Closure& callback,
944 const ErrorCallback& error_callback) {
945 VLOG(1) << "CompleteSimulatedPairing: " << object_path.value();
946 if (pairing_cancelled_) {
947 pairing_cancelled_ = false;
949 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
950 "Cancelled");
951 } else {
952 Properties* properties = GetProperties(object_path);
954 properties->paired.ReplaceValue(true);
955 callback.Run();
957 AddInputDeviceIfNeeded(object_path, properties);
961 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing(
962 const dbus::ObjectPath& object_path,
963 const ErrorCallback& error_callback) {
964 VLOG(1) << "TimeoutSimulatedPairing: " << object_path.value();
966 error_callback.Run(bluetooth_device::kErrorAuthenticationTimeout,
967 "Timed out");
970 void FakeBluetoothDeviceClient::CancelSimulatedPairing(
971 const dbus::ObjectPath& object_path,
972 const ErrorCallback& error_callback) {
973 VLOG(1) << "CancelSimulatedPairing: " << object_path.value();
975 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
976 "Canceled");
979 void FakeBluetoothDeviceClient::RejectSimulatedPairing(
980 const dbus::ObjectPath& object_path,
981 const ErrorCallback& error_callback) {
982 VLOG(1) << "RejectSimulatedPairing: " << object_path.value();
984 error_callback.Run(bluetooth_device::kErrorAuthenticationRejected,
985 "Rejected");
988 void FakeBluetoothDeviceClient::FailSimulatedPairing(
989 const dbus::ObjectPath& object_path,
990 const ErrorCallback& error_callback) {
991 VLOG(1) << "FailSimulatedPairing: " << object_path.value();
993 error_callback.Run(bluetooth_device::kErrorFailed, "Failed");
996 void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded(
997 const dbus::ObjectPath& object_path,
998 Properties* properties) {
999 // If the paired device is a HID device based on it's bluetooth class,
1000 // simulate the Input interface.
1001 FakeBluetoothInputClient* fake_bluetooth_input_client =
1002 static_cast<FakeBluetoothInputClient*>(
1003 DBusThreadManager::Get()->GetBluetoothInputClient());
1005 if ((properties->bluetooth_class.value() & 0x001f03) == 0x000500)
1006 fake_bluetooth_input_client->AddInputDevice(object_path);
1009 void FakeBluetoothDeviceClient::UpdateDeviceRSSI(
1010 const dbus::ObjectPath& object_path,
1011 int16 rssi) {
1012 PropertiesMap::iterator iter = properties_map_.find(object_path);
1013 if (iter == properties_map_.end()) {
1014 VLOG(2) << "Fake device does not exist: " << object_path.value();
1015 return;
1017 Properties* properties = iter->second;
1018 DCHECK(properties);
1019 properties->rssi.ReplaceValue(rssi);
1022 void FakeBluetoothDeviceClient::PinCodeCallback(
1023 const dbus::ObjectPath& object_path,
1024 const base::Closure& callback,
1025 const ErrorCallback& error_callback,
1026 BluetoothAgentServiceProvider::Delegate::Status status,
1027 const std::string& pincode) {
1028 VLOG(1) << "PinCodeCallback: " << object_path.value();
1030 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1031 base::MessageLoop::current()->PostDelayedTask(
1032 FROM_HERE,
1033 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1034 base::Unretained(this),
1035 object_path, callback, error_callback),
1036 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
1038 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1039 base::MessageLoop::current()->PostDelayedTask(
1040 FROM_HERE,
1041 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1042 base::Unretained(this),
1043 object_path, error_callback),
1044 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1046 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1047 base::MessageLoop::current()->PostDelayedTask(
1048 FROM_HERE,
1049 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1050 base::Unretained(this),
1051 object_path, error_callback),
1052 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1057 void FakeBluetoothDeviceClient::PasskeyCallback(
1058 const dbus::ObjectPath& object_path,
1059 const base::Closure& callback,
1060 const ErrorCallback& error_callback,
1061 BluetoothAgentServiceProvider::Delegate::Status status,
1062 uint32 passkey) {
1063 VLOG(1) << "PasskeyCallback: " << object_path.value();
1065 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1066 base::MessageLoop::current()->PostDelayedTask(
1067 FROM_HERE,
1068 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1069 base::Unretained(this),
1070 object_path, callback, error_callback),
1071 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
1073 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1074 base::MessageLoop::current()->PostDelayedTask(
1075 FROM_HERE,
1076 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1077 base::Unretained(this),
1078 object_path, error_callback),
1079 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1081 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1082 base::MessageLoop::current()->PostDelayedTask(
1083 FROM_HERE,
1084 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1085 base::Unretained(this),
1086 object_path, error_callback),
1087 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1092 void FakeBluetoothDeviceClient::ConfirmationCallback(
1093 const dbus::ObjectPath& object_path,
1094 const base::Closure& callback,
1095 const ErrorCallback& error_callback,
1096 BluetoothAgentServiceProvider::Delegate::Status status) {
1097 VLOG(1) << "ConfirmationCallback: " << object_path.value();
1099 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1100 base::MessageLoop::current()->PostDelayedTask(
1101 FROM_HERE,
1102 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1103 base::Unretained(this),
1104 object_path, callback, error_callback),
1105 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
1107 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1108 base::MessageLoop::current()->PostDelayedTask(
1109 FROM_HERE,
1110 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1111 base::Unretained(this),
1112 object_path, error_callback),
1113 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1115 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1116 base::MessageLoop::current()->PostDelayedTask(
1117 FROM_HERE,
1118 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1119 base::Unretained(this),
1120 object_path, error_callback),
1121 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1126 void FakeBluetoothDeviceClient::SimulateKeypress(
1127 uint16 entered,
1128 const dbus::ObjectPath& object_path,
1129 const base::Closure& callback,
1130 const ErrorCallback& error_callback) {
1131 VLOG(1) << "SimulateKeypress " << entered << ": " << object_path.value();
1133 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
1134 static_cast<FakeBluetoothAgentManagerClient*>(
1135 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
1136 FakeBluetoothAgentServiceProvider* agent_service_provider =
1137 fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
1139 // The agent service provider object could have been destroyed after the
1140 // pairing is canceled.
1141 if (!agent_service_provider)
1142 return;
1144 agent_service_provider->DisplayPasskey(object_path, 123456, entered);
1146 if (entered < 7) {
1147 base::MessageLoop::current()->PostDelayedTask(
1148 FROM_HERE,
1149 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
1150 base::Unretained(this),
1151 entered + 1, object_path, callback, error_callback),
1152 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1154 } else {
1155 base::MessageLoop::current()->PostDelayedTask(
1156 FROM_HERE,
1157 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1158 base::Unretained(this),
1159 object_path, callback, error_callback),
1160 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1165 void FakeBluetoothDeviceClient::ConnectionCallback(
1166 const dbus::ObjectPath& object_path,
1167 const base::Closure& callback,
1168 const ErrorCallback& error_callback,
1169 BluetoothProfileServiceProvider::Delegate::Status status) {
1170 VLOG(1) << "ConnectionCallback: " << object_path.value();
1172 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
1173 callback.Run();
1174 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
1175 // TODO(keybuk): tear down this side of the connection
1176 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
1177 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
1178 // TODO(keybuk): tear down this side of the connection
1179 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
1183 void FakeBluetoothDeviceClient::DisconnectionCallback(
1184 const dbus::ObjectPath& object_path,
1185 const base::Closure& callback,
1186 const ErrorCallback& error_callback,
1187 BluetoothProfileServiceProvider::Delegate::Status status) {
1188 VLOG(1) << "DisconnectionCallback: " << object_path.value();
1190 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
1191 // TODO(keybuk): tear down this side of the connection
1192 callback.Run();
1193 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
1194 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
1195 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
1196 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
1200 } // namespace chromeos