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