Add a comment to the Browser Blacklist List
[chromium-blink-merge.git] / chromeos / dbus / fake_bluetooth_device_client.cc
blob2dd5aaea70e64f4f77cf7c374829b0e723dc14bf
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 // Must be paired.
298 error_callback.Run(bluetooth_device::kErrorFailed, "Not paired");
299 return;
300 } else if (properties->paired.value() == true &&
301 object_path == dbus::ObjectPath(kUnconnectableDevicePath)) {
302 // Must not be paired
303 error_callback.Run(bluetooth_device::kErrorFailed,
304 "Connection fails while paired");
305 return;
308 // The device can be connected.
309 properties->connected.ReplaceValue(true);
310 callback.Run();
312 // Expose GATT services if connected to LE device.
313 if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
314 FakeBluetoothGattServiceClient* gatt_service_client =
315 static_cast<FakeBluetoothGattServiceClient*>(
316 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
317 gatt_service_client->ExposeHeartRateService(
318 dbus::ObjectPath(kLowEnergyPath));
321 AddInputDeviceIfNeeded(object_path, properties);
324 void FakeBluetoothDeviceClient::Disconnect(
325 const dbus::ObjectPath& object_path,
326 const base::Closure& callback,
327 const ErrorCallback& error_callback) {
328 VLOG(1) << "Disconnect: " << object_path.value();
329 Properties* properties = GetProperties(object_path);
331 if (!properties->connected.value()) {
332 error_callback.Run("org.bluez.Error.NotConnected", "Not Connected");
333 return;
336 // Hide the Heart Rate Service if disconnected from LE device.
337 if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
338 FakeBluetoothGattServiceClient* gatt_service_client =
339 static_cast<FakeBluetoothGattServiceClient*>(
340 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
341 gatt_service_client->HideHeartRateService();
344 callback.Run();
345 properties->connected.ReplaceValue(false);
348 void FakeBluetoothDeviceClient::ConnectProfile(
349 const dbus::ObjectPath& object_path,
350 const std::string& uuid,
351 const base::Closure& callback,
352 const ErrorCallback& error_callback) {
353 VLOG(1) << "ConnectProfile: " << object_path.value() << " " << uuid;
355 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
356 static_cast<FakeBluetoothProfileManagerClient*>(
357 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
358 FakeBluetoothProfileServiceProvider* profile_service_provider =
359 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
360 if (profile_service_provider == NULL) {
361 error_callback.Run(kNoResponseError, "Missing profile");
362 return;
365 // Make a socket pair of a compatible type with the type used by Bluetooth;
366 // spin up a thread to simulate the server side and wrap the client side in
367 // a D-Bus file descriptor object.
368 int socket_type = SOCK_STREAM;
369 if (uuid == FakeBluetoothProfileManagerClient::kL2capUuid)
370 socket_type = SOCK_SEQPACKET;
372 int fds[2];
373 if (socketpair(AF_UNIX, socket_type, 0, fds) < 0) {
374 error_callback.Run(kNoResponseError, "socketpair call failed");
375 return;
378 int args;
379 args = fcntl(fds[1], F_GETFL, NULL);
380 if (args < 0) {
381 error_callback.Run(kNoResponseError, "failed to get socket flags");
382 return;
385 args |= O_NONBLOCK;
386 if (fcntl(fds[1], F_SETFL, args) < 0) {
387 error_callback.Run(kNoResponseError, "failed to set socket non-blocking");
388 return;
391 base::WorkerPool::GetTaskRunner(false)->PostTask(
392 FROM_HERE,
393 base::Bind(&SimulatedProfileSocket,
394 fds[0]));
396 scoped_ptr<dbus::FileDescriptor> fd(new dbus::FileDescriptor(fds[1]));
398 // Post the new connection to the service provider.
399 BluetoothProfileServiceProvider::Delegate::Options options;
401 profile_service_provider->NewConnection(
402 object_path,
403 fd.Pass(),
404 options,
405 base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback,
406 base::Unretained(this),
407 object_path,
408 callback,
409 error_callback));
412 void FakeBluetoothDeviceClient::DisconnectProfile(
413 const dbus::ObjectPath& object_path,
414 const std::string& uuid,
415 const base::Closure& callback,
416 const ErrorCallback& error_callback) {
417 VLOG(1) << "DisconnectProfile: " << object_path.value() << " " << uuid;
419 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
420 static_cast<FakeBluetoothProfileManagerClient*>(
421 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
422 FakeBluetoothProfileServiceProvider* profile_service_provider =
423 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
424 if (profile_service_provider == NULL) {
425 error_callback.Run(kNoResponseError, "Missing profile");
426 return;
429 profile_service_provider->RequestDisconnection(
430 object_path,
431 base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback,
432 base::Unretained(this),
433 object_path,
434 callback,
435 error_callback));
438 void FakeBluetoothDeviceClient::Pair(
439 const dbus::ObjectPath& object_path,
440 const base::Closure& callback,
441 const ErrorCallback& error_callback) {
442 VLOG(1) << "Pair: " << object_path.value();
443 Properties* properties = GetProperties(object_path);
445 if (properties->paired.value() == true) {
446 // Already paired.
447 callback.Run();
448 return;
451 SimulatePairing(object_path, false, callback, error_callback);
454 void FakeBluetoothDeviceClient::CancelPairing(
455 const dbus::ObjectPath& object_path,
456 const base::Closure& callback,
457 const ErrorCallback& error_callback) {
458 VLOG(1) << "CancelPairing: " << object_path.value();
459 pairing_cancelled_ = true;
460 callback.Run();
463 void FakeBluetoothDeviceClient::StartConnectionMonitor(
464 const dbus::ObjectPath& object_path,
465 const base::Closure& callback,
466 const ErrorCallback& error_callback) {
467 VLOG(1) << "StartConnectionMonitor: " << object_path.value();
468 connection_monitor_started_ = true;
469 callback.Run();
472 void FakeBluetoothDeviceClient::StopConnectionMonitor(
473 const dbus::ObjectPath& object_path,
474 const base::Closure& callback,
475 const ErrorCallback& error_callback) {
476 connection_monitor_started_ = false;
477 callback.Run();
480 void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
481 const dbus::ObjectPath& adapter_path) {
482 VLOG(1) << "starting discovery simulation";
484 discovery_simulation_step_ = 1;
486 base::MessageLoop::current()->PostDelayedTask(
487 FROM_HERE,
488 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
489 base::Unretained(this)),
490 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
493 void FakeBluetoothDeviceClient::EndDiscoverySimulation(
494 const dbus::ObjectPath& adapter_path) {
495 VLOG(1) << "stopping discovery simulation";
496 discovery_simulation_step_ = 0;
499 void FakeBluetoothDeviceClient::BeginIncomingPairingSimulation(
500 const dbus::ObjectPath& adapter_path) {
501 VLOG(1) << "starting incoming pairing simulation";
503 incoming_pairing_simulation_step_ = 1;
505 base::MessageLoop::current()->PostDelayedTask(
506 FROM_HERE,
507 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
508 base::Unretained(this)),
509 base::TimeDelta::FromMilliseconds(30 * simulation_interval_ms_));
512 void FakeBluetoothDeviceClient::EndIncomingPairingSimulation(
513 const dbus::ObjectPath& adapter_path) {
514 VLOG(1) << "stopping incoming pairing simulation";
515 incoming_pairing_simulation_step_ = 0;
518 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms) {
519 simulation_interval_ms_ = interval_ms;
522 void FakeBluetoothDeviceClient::CreateDevice(
523 const dbus::ObjectPath& adapter_path,
524 const dbus::ObjectPath& device_path) {
525 if (std::find(device_list_.begin(),
526 device_list_.end(), device_path) != device_list_.end())
527 return;
529 Properties* properties = new Properties(base::Bind(
530 &FakeBluetoothDeviceClient::OnPropertyChanged,
531 base::Unretained(this),
532 device_path));
533 properties->adapter.ReplaceValue(adapter_path);
535 if (device_path == dbus::ObjectPath(kLegacyAutopairPath)) {
536 properties->address.ReplaceValue(kLegacyAutopairAddress);
537 properties->bluetooth_class.ReplaceValue(kLegacyAutopairClass);
538 properties->name.ReplaceValue("LegacyAutopair");
539 properties->alias.ReplaceValue(kLegacyAutopairName);
541 std::vector<std::string> uuids;
542 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
543 properties->uuids.ReplaceValue(uuids);
545 } else if (device_path == dbus::ObjectPath(kDisplayPinCodePath)) {
546 properties->address.ReplaceValue(kDisplayPinCodeAddress);
547 properties->bluetooth_class.ReplaceValue(kDisplayPinCodeClass);
548 properties->name.ReplaceValue("DisplayPinCode");
549 properties->alias.ReplaceValue(kDisplayPinCodeName);
551 std::vector<std::string> uuids;
552 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
553 properties->uuids.ReplaceValue(uuids);
555 } else if (device_path == dbus::ObjectPath(kVanishingDevicePath)) {
556 properties->address.ReplaceValue(kVanishingDeviceAddress);
557 properties->bluetooth_class.ReplaceValue(kVanishingDeviceClass);
558 properties->name.ReplaceValue("VanishingDevice");
559 properties->alias.ReplaceValue(kVanishingDeviceName);
561 } else if (device_path == dbus::ObjectPath(kConnectUnpairablePath)) {
562 properties->address.ReplaceValue(kConnectUnpairableAddress);
563 properties->bluetooth_class.ReplaceValue(kConnectUnpairableClass);
564 properties->name.ReplaceValue("ConnectUnpairable");
565 properties->alias.ReplaceValue(kConnectUnpairableName);
567 std::vector<std::string> uuids;
568 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
569 properties->uuids.ReplaceValue(uuids);
571 } else if (device_path == dbus::ObjectPath(kDisplayPasskeyPath)) {
572 properties->address.ReplaceValue(kDisplayPasskeyAddress);
573 properties->bluetooth_class.ReplaceValue(kDisplayPasskeyClass);
574 properties->name.ReplaceValue("DisplayPasskey");
575 properties->alias.ReplaceValue(kDisplayPasskeyName);
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(kRequestPinCodePath)) {
582 properties->address.ReplaceValue(kRequestPinCodeAddress);
583 properties->bluetooth_class.ReplaceValue(kRequestPinCodeClass);
584 properties->name.ReplaceValue("RequestPinCode");
585 properties->alias.ReplaceValue(kRequestPinCodeName);
587 } else if (device_path == dbus::ObjectPath(kConfirmPasskeyPath)) {
588 properties->address.ReplaceValue(kConfirmPasskeyAddress);
589 properties->bluetooth_class.ReplaceValue(kConfirmPasskeyClass);
590 properties->name.ReplaceValue("ConfirmPasskey");
591 properties->alias.ReplaceValue(kConfirmPasskeyName);
593 } else if (device_path == dbus::ObjectPath(kRequestPasskeyPath)) {
594 properties->address.ReplaceValue(kRequestPasskeyAddress);
595 properties->bluetooth_class.ReplaceValue(kRequestPasskeyClass);
596 properties->name.ReplaceValue("RequestPasskey");
597 properties->alias.ReplaceValue(kRequestPasskeyName);
599 } else if (device_path == dbus::ObjectPath(kUnconnectableDevicePath)) {
600 properties->address.ReplaceValue(kUnconnectableDeviceAddress);
601 properties->bluetooth_class.ReplaceValue(kUnconnectableDeviceClass);
602 properties->name.ReplaceValue("UnconnectableDevice");
603 properties->alias.ReplaceValue(kUnconnectableDeviceName);
605 } else if (device_path == dbus::ObjectPath(kUnpairableDevicePath)) {
606 properties->address.ReplaceValue(kUnpairableDeviceAddress);
607 properties->bluetooth_class.ReplaceValue(kUnpairableDeviceClass);
608 properties->name.ReplaceValue("Fake Unpairable Device");
609 properties->alias.ReplaceValue(kUnpairableDeviceName);
611 } else if (device_path == dbus::ObjectPath(kJustWorksPath)) {
612 properties->address.ReplaceValue(kJustWorksAddress);
613 properties->bluetooth_class.ReplaceValue(kJustWorksClass);
614 properties->name.ReplaceValue("JustWorks");
615 properties->alias.ReplaceValue(kJustWorksName);
617 } else if (device_path == dbus::ObjectPath(kLowEnergyPath)) {
618 properties->address.ReplaceValue(kLowEnergyAddress);
619 properties->bluetooth_class.ReplaceValue(kLowEnergyClass);
620 properties->name.ReplaceValue("Heart Rate Monitor");
621 properties->alias.ReplaceValue(kLowEnergyName);
623 std::vector<std::string> uuids;
624 uuids.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID);
625 properties->uuids.ReplaceValue(uuids);
627 } else {
628 NOTREACHED();
632 properties_map_[device_path] = properties;
633 device_list_.push_back(device_path);
634 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
635 DeviceAdded(device_path));
638 void FakeBluetoothDeviceClient::RemoveDevice(
639 const dbus::ObjectPath& adapter_path,
640 const dbus::ObjectPath& device_path) {
641 std::vector<dbus::ObjectPath>::iterator listiter =
642 std::find(device_list_.begin(), device_list_.end(), device_path);
643 if (listiter == device_list_.end())
644 return;
646 PropertiesMap::iterator iter = properties_map_.find(device_path);
647 Properties* properties = iter->second;
649 VLOG(1) << "removing device: " << properties->alias.value();
650 device_list_.erase(listiter);
652 // Remove the Input interface if it exists. This should be called before the
653 // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
654 // BluetoothDeviceChromeOS object, including the device_path referenced here.
655 FakeBluetoothInputClient* fake_bluetooth_input_client =
656 static_cast<FakeBluetoothInputClient*>(
657 DBusThreadManager::Get()->GetBluetoothInputClient());
658 fake_bluetooth_input_client->RemoveInputDevice(device_path);
660 if (device_path == dbus::ObjectPath(kLowEnergyPath)) {
661 FakeBluetoothGattServiceClient* gatt_service_client =
662 static_cast<FakeBluetoothGattServiceClient*>(
663 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
664 gatt_service_client->HideHeartRateService();
667 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
668 DeviceRemoved(device_path));
670 delete properties;
671 properties_map_.erase(iter);
674 void FakeBluetoothDeviceClient::OnPropertyChanged(
675 const dbus::ObjectPath& object_path,
676 const std::string& property_name) {
677 VLOG(2) << "Fake Bluetooth device property changed: " << object_path.value()
678 << ": " << property_name;
679 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
680 DevicePropertyChanged(object_path, property_name));
683 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
684 if (!discovery_simulation_step_)
685 return;
687 // Timer fires every .75s, the numbers below are arbitrary to give a feel
688 // for a discovery process.
689 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_;
690 if (discovery_simulation_step_ == 2) {
691 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
692 dbus::ObjectPath(kLegacyAutopairPath));
693 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
694 dbus::ObjectPath(kLowEnergyPath));
696 } else if (discovery_simulation_step_ == 4) {
697 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
698 base::RandInt(kMinRSSI, kMaxRSSI));
699 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
700 dbus::ObjectPath(kDisplayPinCodePath));
701 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
702 dbus::ObjectPath(kVanishingDevicePath));
704 } else if (discovery_simulation_step_ == 7) {
705 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
706 dbus::ObjectPath(kConnectUnpairablePath));
707 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
708 base::RandInt(kMinRSSI, kMaxRSSI));
710 } else if (discovery_simulation_step_ == 8) {
711 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
712 dbus::ObjectPath(kDisplayPasskeyPath));
713 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
714 dbus::ObjectPath(kRequestPinCodePath));
715 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
716 base::RandInt(kMinRSSI, kMaxRSSI));
718 } else if (discovery_simulation_step_ == 10) {
719 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
720 dbus::ObjectPath(kConfirmPasskeyPath));
721 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
722 dbus::ObjectPath(kRequestPasskeyPath));
723 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
724 dbus::ObjectPath(kUnconnectableDevicePath));
725 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
726 dbus::ObjectPath(kUnpairableDevicePath));
727 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
728 dbus::ObjectPath(kJustWorksPath));
729 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
730 base::RandInt(kMinRSSI, kMaxRSSI));
732 } else if (discovery_simulation_step_ == 13) {
733 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
734 base::RandInt(kMinRSSI, kMaxRSSI));
735 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
736 dbus::ObjectPath(kVanishingDevicePath));
738 } else if (discovery_simulation_step_ == 14) {
739 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
740 base::RandInt(kMinRSSI, kMaxRSSI));
741 return;
745 ++discovery_simulation_step_;
746 base::MessageLoop::current()->PostDelayedTask(
747 FROM_HERE,
748 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
749 base::Unretained(this)),
750 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
753 void FakeBluetoothDeviceClient::IncomingPairingSimulationTimer() {
754 if (!incoming_pairing_simulation_step_)
755 return;
757 VLOG(1) << "incoming pairing simulation, step "
758 << incoming_pairing_simulation_step_;
759 switch (incoming_pairing_simulation_step_) {
760 case 1:
761 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
762 dbus::ObjectPath(kConfirmPasskeyPath));
763 SimulatePairing(dbus::ObjectPath(kConfirmPasskeyPath), true,
764 base::Bind(&base::DoNothing),
765 base::Bind(&SimpleErrorCallback));
766 break;
767 case 2:
768 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
769 dbus::ObjectPath(kJustWorksPath));
770 SimulatePairing(dbus::ObjectPath(kJustWorksPath), true,
771 base::Bind(&base::DoNothing),
772 base::Bind(&SimpleErrorCallback));
773 break;
774 case 3:
775 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
776 dbus::ObjectPath(kDisplayPinCodePath));
777 SimulatePairing(dbus::ObjectPath(kDisplayPinCodePath), true,
778 base::Bind(&base::DoNothing),
779 base::Bind(&SimpleErrorCallback));
780 break;
781 case 4:
782 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
783 dbus::ObjectPath(kDisplayPasskeyPath));
784 SimulatePairing(dbus::ObjectPath(kDisplayPasskeyPath), true,
785 base::Bind(&base::DoNothing),
786 base::Bind(&SimpleErrorCallback));
787 break;
788 case 5:
789 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
790 dbus::ObjectPath(kRequestPinCodePath));
791 SimulatePairing(dbus::ObjectPath(kRequestPinCodePath), true,
792 base::Bind(&base::DoNothing),
793 base::Bind(&SimpleErrorCallback));
794 break;
795 case 6:
796 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
797 dbus::ObjectPath(kRequestPasskeyPath));
798 SimulatePairing(dbus::ObjectPath(kRequestPasskeyPath), true,
799 base::Bind(&base::DoNothing),
800 base::Bind(&SimpleErrorCallback));
801 break;
802 default:
803 return;
806 ++incoming_pairing_simulation_step_;
807 base::MessageLoop::current()->PostDelayedTask(
808 FROM_HERE,
809 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
810 base::Unretained(this)),
811 base::TimeDelta::FromMilliseconds(45 * simulation_interval_ms_));
814 void FakeBluetoothDeviceClient::SimulatePairing(
815 const dbus::ObjectPath& object_path,
816 bool incoming_request,
817 const base::Closure& callback,
818 const ErrorCallback& error_callback) {
819 pairing_cancelled_ = false;
821 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
822 static_cast<FakeBluetoothAgentManagerClient*>(
823 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
824 FakeBluetoothAgentServiceProvider* agent_service_provider =
825 fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
826 CHECK(agent_service_provider != NULL);
828 if (object_path == dbus::ObjectPath(kLegacyAutopairPath) ||
829 object_path == dbus::ObjectPath(kConnectUnpairablePath) ||
830 object_path == dbus::ObjectPath(kUnconnectableDevicePath) ||
831 object_path == dbus::ObjectPath(kLowEnergyPath)) {
832 // No need to call anything on the pairing delegate, just wait 3 times
833 // the interval before acting as if the other end accepted it.
834 base::MessageLoop::current()->PostDelayedTask(
835 FROM_HERE,
836 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
837 base::Unretained(this),
838 object_path, callback, error_callback),
839 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
841 } else if (object_path == dbus::ObjectPath(kDisplayPinCodePath)) {
842 // Display a Pincode, and wait 7 times the interval before acting as
843 // if the other end accepted it.
844 agent_service_provider->DisplayPinCode(object_path, "123456");
846 base::MessageLoop::current()->PostDelayedTask(
847 FROM_HERE,
848 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
849 base::Unretained(this),
850 object_path, callback, error_callback),
851 base::TimeDelta::FromMilliseconds(7 * simulation_interval_ms_));
853 } else if (object_path == dbus::ObjectPath(kVanishingDevicePath)) {
854 // The vanishing device simulates being too far away, and thus times out.
855 base::MessageLoop::current()->PostDelayedTask(
856 FROM_HERE,
857 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing,
858 base::Unretained(this),
859 object_path, error_callback),
860 base::TimeDelta::FromMilliseconds(4 * simulation_interval_ms_));
862 } else if (object_path == dbus::ObjectPath(kDisplayPasskeyPath)) {
863 // Display a passkey, and each interval act as if another key was entered
864 // for it.
865 agent_service_provider->DisplayPasskey(object_path, 123456, 0);
867 base::MessageLoop::current()->PostDelayedTask(
868 FROM_HERE,
869 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
870 base::Unretained(this),
871 1, object_path, callback, error_callback),
872 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
874 } else if (object_path == dbus::ObjectPath(kRequestPinCodePath)) {
875 // Request a Pincode.
876 agent_service_provider->RequestPinCode(
877 object_path,
878 base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback,
879 base::Unretained(this),
880 object_path,
881 callback,
882 error_callback));
884 } else if (object_path == dbus::ObjectPath(kConfirmPasskeyPath)) {
885 // Request confirmation of a Passkey.
886 agent_service_provider->RequestConfirmation(
887 object_path, 123456,
888 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
889 base::Unretained(this),
890 object_path,
891 callback,
892 error_callback));
894 } else if (object_path == dbus::ObjectPath(kRequestPasskeyPath)) {
895 // Request a Passkey from the user.
896 agent_service_provider->RequestPasskey(
897 object_path,
898 base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback,
899 base::Unretained(this),
900 object_path,
901 callback,
902 error_callback));
904 } else if (object_path == dbus::ObjectPath(kUnpairableDevicePath)) {
905 // Fails the pairing with an org.bluez.Error.Failed error.
906 base::MessageLoop::current()->PostDelayedTask(
907 FROM_HERE,
908 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing,
909 base::Unretained(this),
910 object_path, error_callback),
911 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
913 } else if (object_path == dbus::ObjectPath(kJustWorksPath)) {
914 if (incoming_request) {
915 agent_service_provider->RequestAuthorization(
916 object_path,
917 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
918 base::Unretained(this),
919 object_path,
920 callback,
921 error_callback));
923 } else {
924 // No need to call anything on the pairing delegate, just wait 3 times
925 // the interval before acting as if the other end accepted it.
926 base::MessageLoop::current()->PostDelayedTask(
927 FROM_HERE,
928 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
929 base::Unretained(this),
930 object_path, callback, error_callback),
931 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
935 } else {
936 error_callback.Run(kNoResponseError, "No pairing fake");
940 void FakeBluetoothDeviceClient::CompleteSimulatedPairing(
941 const dbus::ObjectPath& object_path,
942 const base::Closure& callback,
943 const ErrorCallback& error_callback) {
944 VLOG(1) << "CompleteSimulatedPairing: " << object_path.value();
945 if (pairing_cancelled_) {
946 pairing_cancelled_ = false;
948 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
949 "Cancelled");
950 } else {
951 Properties* properties = GetProperties(object_path);
953 properties->paired.ReplaceValue(true);
954 callback.Run();
956 AddInputDeviceIfNeeded(object_path, properties);
960 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing(
961 const dbus::ObjectPath& object_path,
962 const ErrorCallback& error_callback) {
963 VLOG(1) << "TimeoutSimulatedPairing: " << object_path.value();
965 error_callback.Run(bluetooth_device::kErrorAuthenticationTimeout,
966 "Timed out");
969 void FakeBluetoothDeviceClient::CancelSimulatedPairing(
970 const dbus::ObjectPath& object_path,
971 const ErrorCallback& error_callback) {
972 VLOG(1) << "CancelSimulatedPairing: " << object_path.value();
974 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
975 "Canceled");
978 void FakeBluetoothDeviceClient::RejectSimulatedPairing(
979 const dbus::ObjectPath& object_path,
980 const ErrorCallback& error_callback) {
981 VLOG(1) << "RejectSimulatedPairing: " << object_path.value();
983 error_callback.Run(bluetooth_device::kErrorAuthenticationRejected,
984 "Rejected");
987 void FakeBluetoothDeviceClient::FailSimulatedPairing(
988 const dbus::ObjectPath& object_path,
989 const ErrorCallback& error_callback) {
990 VLOG(1) << "FailSimulatedPairing: " << object_path.value();
992 error_callback.Run(bluetooth_device::kErrorFailed, "Failed");
995 void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded(
996 const dbus::ObjectPath& object_path,
997 Properties* properties) {
998 // If the paired device is a HID device based on it's bluetooth class,
999 // simulate the Input interface.
1000 FakeBluetoothInputClient* fake_bluetooth_input_client =
1001 static_cast<FakeBluetoothInputClient*>(
1002 DBusThreadManager::Get()->GetBluetoothInputClient());
1004 if ((properties->bluetooth_class.value() & 0x001f03) == 0x000500)
1005 fake_bluetooth_input_client->AddInputDevice(object_path);
1008 void FakeBluetoothDeviceClient::UpdateDeviceRSSI(
1009 const dbus::ObjectPath& object_path,
1010 int16 rssi) {
1011 PropertiesMap::iterator iter = properties_map_.find(object_path);
1012 if (iter == properties_map_.end()) {
1013 VLOG(2) << "Fake device does not exist: " << object_path.value();
1014 return;
1016 Properties* properties = iter->second;
1017 DCHECK(properties);
1018 properties->rssi.ReplaceValue(rssi);
1021 void FakeBluetoothDeviceClient::PinCodeCallback(
1022 const dbus::ObjectPath& object_path,
1023 const base::Closure& callback,
1024 const ErrorCallback& error_callback,
1025 BluetoothAgentServiceProvider::Delegate::Status status,
1026 const std::string& pincode) {
1027 VLOG(1) << "PinCodeCallback: " << object_path.value();
1029 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1030 base::MessageLoop::current()->PostDelayedTask(
1031 FROM_HERE,
1032 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1033 base::Unretained(this),
1034 object_path, callback, error_callback),
1035 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
1037 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1038 base::MessageLoop::current()->PostDelayedTask(
1039 FROM_HERE,
1040 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1041 base::Unretained(this),
1042 object_path, error_callback),
1043 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1045 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1046 base::MessageLoop::current()->PostDelayedTask(
1047 FROM_HERE,
1048 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1049 base::Unretained(this),
1050 object_path, error_callback),
1051 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1056 void FakeBluetoothDeviceClient::PasskeyCallback(
1057 const dbus::ObjectPath& object_path,
1058 const base::Closure& callback,
1059 const ErrorCallback& error_callback,
1060 BluetoothAgentServiceProvider::Delegate::Status status,
1061 uint32 passkey) {
1062 VLOG(1) << "PasskeyCallback: " << object_path.value();
1064 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1065 base::MessageLoop::current()->PostDelayedTask(
1066 FROM_HERE,
1067 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1068 base::Unretained(this),
1069 object_path, callback, error_callback),
1070 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
1072 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1073 base::MessageLoop::current()->PostDelayedTask(
1074 FROM_HERE,
1075 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1076 base::Unretained(this),
1077 object_path, error_callback),
1078 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1080 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1081 base::MessageLoop::current()->PostDelayedTask(
1082 FROM_HERE,
1083 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1084 base::Unretained(this),
1085 object_path, error_callback),
1086 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1091 void FakeBluetoothDeviceClient::ConfirmationCallback(
1092 const dbus::ObjectPath& object_path,
1093 const base::Closure& callback,
1094 const ErrorCallback& error_callback,
1095 BluetoothAgentServiceProvider::Delegate::Status status) {
1096 VLOG(1) << "ConfirmationCallback: " << object_path.value();
1098 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1099 base::MessageLoop::current()->PostDelayedTask(
1100 FROM_HERE,
1101 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1102 base::Unretained(this),
1103 object_path, callback, error_callback),
1104 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));
1106 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1107 base::MessageLoop::current()->PostDelayedTask(
1108 FROM_HERE,
1109 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1110 base::Unretained(this),
1111 object_path, error_callback),
1112 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1114 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1115 base::MessageLoop::current()->PostDelayedTask(
1116 FROM_HERE,
1117 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1118 base::Unretained(this),
1119 object_path, error_callback),
1120 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1125 void FakeBluetoothDeviceClient::SimulateKeypress(
1126 uint16 entered,
1127 const dbus::ObjectPath& object_path,
1128 const base::Closure& callback,
1129 const ErrorCallback& error_callback) {
1130 VLOG(1) << "SimulateKeypress " << entered << ": " << object_path.value();
1132 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
1133 static_cast<FakeBluetoothAgentManagerClient*>(
1134 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
1135 FakeBluetoothAgentServiceProvider* agent_service_provider =
1136 fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
1138 // The agent service provider object could have been destroyed after the
1139 // pairing is canceled.
1140 if (!agent_service_provider)
1141 return;
1143 agent_service_provider->DisplayPasskey(object_path, 123456, entered);
1145 if (entered < 7) {
1146 base::MessageLoop::current()->PostDelayedTask(
1147 FROM_HERE,
1148 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
1149 base::Unretained(this),
1150 entered + 1, object_path, callback, error_callback),
1151 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1153 } else {
1154 base::MessageLoop::current()->PostDelayedTask(
1155 FROM_HERE,
1156 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1157 base::Unretained(this),
1158 object_path, callback, error_callback),
1159 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1164 void FakeBluetoothDeviceClient::ConnectionCallback(
1165 const dbus::ObjectPath& object_path,
1166 const base::Closure& callback,
1167 const ErrorCallback& error_callback,
1168 BluetoothProfileServiceProvider::Delegate::Status status) {
1169 VLOG(1) << "ConnectionCallback: " << object_path.value();
1171 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
1172 callback.Run();
1173 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
1174 // TODO(keybuk): tear down this side of the connection
1175 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
1176 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
1177 // TODO(keybuk): tear down this side of the connection
1178 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
1182 void FakeBluetoothDeviceClient::DisconnectionCallback(
1183 const dbus::ObjectPath& object_path,
1184 const base::Closure& callback,
1185 const ErrorCallback& error_callback,
1186 BluetoothProfileServiceProvider::Delegate::Status status) {
1187 VLOG(1) << "DisconnectionCallback: " << object_path.value();
1189 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
1190 // TODO(keybuk): tear down this side of the connection
1191 callback.Run();
1192 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
1193 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
1194 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
1195 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
1199 } // namespace chromeos