Add ICU message format support
[chromium-blink-merge.git] / chromeos / dbus / fake_bluetooth_device_client.cc
blobce373e477dfbae9acf7df8cc05e9116f54e81743
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/dbus/fake_bluetooth_device_client.h"
7 #include <fcntl.h>
8 #include <sys/socket.h>
9 #include <sys/types.h>
10 #include <unistd.h>
12 #include <algorithm>
13 #include <string>
14 #include <utility>
16 #include "base/location.h"
17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/rand_util.h"
20 #include "base/single_thread_task_runner.h"
21 #include "base/stl_util.h"
22 #include "base/thread_task_runner_handle.h"
23 #include "base/threading/worker_pool.h"
24 #include "base/time/time.h"
25 #include "chromeos/dbus/dbus_thread_manager.h"
26 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
27 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
28 #include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
29 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
30 #include "chromeos/dbus/fake_bluetooth_input_client.h"
31 #include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
32 #include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
33 #include "dbus/file_descriptor.h"
34 #include "third_party/cros_system_api/dbus/service_constants.h"
36 namespace {
38 // Default interval between simulated events.
39 const int kSimulationIntervalMs = 750;
41 // Minimum and maximum bounds for randomly generated RSSI values.
42 const int kMinRSSI = -90;
43 const int kMaxRSSI = -30;
45 // The default value of connection info properties from GetConnInfo().
46 const int kUnkownPower = 127;
48 const char kPairingMethodNone[] = "None";
49 const char kPairingMethodPinCode[] = "PIN Code";
50 const char kPairingMethodPassKey[] = "PassKey";
51 const char kTestPinCode[] = "123456";
53 // This is meant to delay the removal of a pre defined device until the
54 // developer has time to see it.
55 const int kVanishingDevicePairTimeMultiplier = 4;
57 // Meant to delay a pair request for an observable amount of time.
58 const int kIncomingSimulationPairTimeMultiplier = 45;
60 // Meant to delay a request that asks for pair requests for an observable
61 // amount of time.
62 const int kIncomingSimulationStartPairTimeMultiplier = 30;
64 // This allows the PIN code dialog to be shown for a long enough time to see
65 // the PIN code UI in detail.
66 const int kPinCodeDevicePairTimeMultiplier = 7;
68 // This allows the pairing dialog to be shown for a long enough time to see
69 // its UI in detail.
70 const int kSimulateNormalPairTimeMultiplier = 3;
72 const int kTestPassKey = 123456;
74 void SimulatedProfileSocket(int fd) {
75 // Simulate a server-side socket of a profile; read data from the socket,
76 // write it back, and then close.
77 char buf[1024];
78 ssize_t len;
79 ssize_t count;
81 len = read(fd, buf, sizeof buf);
82 if (len < 0) {
83 close(fd);
84 return;
87 count = len;
88 len = write(fd, buf, count);
89 if (len < 0) {
90 close(fd);
91 return;
94 close(fd);
97 void SimpleErrorCallback(const std::string& error_name,
98 const std::string& error_message) {
99 VLOG(1) << "Bluetooth Error: " << error_name << ": " << error_message;
102 } // namespace
104 namespace chromeos {
106 const char FakeBluetoothDeviceClient::kPairedDevicePath[] =
107 "/fake/hci0/dev0";
108 const char FakeBluetoothDeviceClient::kPairedDeviceAddress[] =
109 "00:11:22:33:44:55";
110 const char FakeBluetoothDeviceClient::kPairedDeviceName[] =
111 "Fake Device";
112 const uint32 FakeBluetoothDeviceClient::kPairedDeviceClass = 0x000104;
114 const char FakeBluetoothDeviceClient::kLegacyAutopairPath[] =
115 "/fake/hci0/dev1";
116 const char FakeBluetoothDeviceClient::kLegacyAutopairAddress[] =
117 "28:CF:DA:00:00:00";
118 const char FakeBluetoothDeviceClient::kLegacyAutopairName[] =
119 "Bluetooth 2.0 Mouse";
120 const uint32 FakeBluetoothDeviceClient::kLegacyAutopairClass = 0x002580;
122 const char FakeBluetoothDeviceClient::kDisplayPinCodePath[] =
123 "/fake/hci0/dev2";
124 const char FakeBluetoothDeviceClient::kDisplayPinCodeAddress[] =
125 "28:37:37:00:00:00";
126 const char FakeBluetoothDeviceClient::kDisplayPinCodeName[] =
127 "Bluetooth 2.0 Keyboard";
128 const uint32 FakeBluetoothDeviceClient::kDisplayPinCodeClass = 0x002540;
130 const char FakeBluetoothDeviceClient::kVanishingDevicePath[] =
131 "/fake/hci0/dev3";
132 const char FakeBluetoothDeviceClient::kVanishingDeviceAddress[] =
133 "01:02:03:04:05:06";
134 const char FakeBluetoothDeviceClient::kVanishingDeviceName[] =
135 "Vanishing Device";
136 const uint32 FakeBluetoothDeviceClient::kVanishingDeviceClass = 0x000104;
138 const char FakeBluetoothDeviceClient::kConnectUnpairablePath[] =
139 "/fake/hci0/dev4";
140 const char FakeBluetoothDeviceClient::kConnectUnpairableAddress[] =
141 "7C:ED:8D:00:00:00";
142 const char FakeBluetoothDeviceClient::kConnectUnpairableName[] =
143 "Unpairable Device";
144 const uint32 FakeBluetoothDeviceClient::kConnectUnpairableClass = 0x002580;
146 const char FakeBluetoothDeviceClient::kDisplayPasskeyPath[] =
147 "/fake/hci0/dev5";
148 const char FakeBluetoothDeviceClient::kDisplayPasskeyAddress[] =
149 "00:0F:F6:00:00:00";
150 const char FakeBluetoothDeviceClient::kDisplayPasskeyName[] =
151 "Bluetooth 2.1+ Keyboard";
152 const uint32 FakeBluetoothDeviceClient::kDisplayPasskeyClass = 0x002540;
154 const char FakeBluetoothDeviceClient::kRequestPinCodePath[] =
155 "/fake/hci0/dev6";
156 const char FakeBluetoothDeviceClient::kRequestPinCodeAddress[] =
157 "00:24:BE:00:00:00";
158 const char FakeBluetoothDeviceClient::kRequestPinCodeName[] =
159 "PIN Device";
160 const uint32 FakeBluetoothDeviceClient::kRequestPinCodeClass = 0x240408;
162 const char FakeBluetoothDeviceClient::kConfirmPasskeyPath[] =
163 "/fake/hci0/dev7";
164 const char FakeBluetoothDeviceClient::kConfirmPasskeyAddress[] =
165 "20:7D:74:00:00:00";
166 const char FakeBluetoothDeviceClient::kConfirmPasskeyName[] =
167 "Phone";
168 const uint32 FakeBluetoothDeviceClient::kConfirmPasskeyClass = 0x7a020c;
170 const char FakeBluetoothDeviceClient::kRequestPasskeyPath[] =
171 "/fake/hci0/dev8";
172 const char FakeBluetoothDeviceClient::kRequestPasskeyAddress[] =
173 "20:7D:74:00:00:01";
174 const char FakeBluetoothDeviceClient::kRequestPasskeyName[] =
175 "Passkey Device";
176 const uint32 FakeBluetoothDeviceClient::kRequestPasskeyClass = 0x7a020c;
178 const char FakeBluetoothDeviceClient::kUnconnectableDevicePath[] =
179 "/fake/hci0/dev9";
180 const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress[] =
181 "20:7D:74:00:00:02";
182 const char FakeBluetoothDeviceClient::kUnconnectableDeviceName[] =
183 "Unconnectable Device";
184 const uint32 FakeBluetoothDeviceClient::kUnconnectableDeviceClass = 0x7a020c;
186 const char FakeBluetoothDeviceClient::kUnpairableDevicePath[] =
187 "/fake/hci0/devA";
188 const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress[] =
189 "20:7D:74:00:00:03";
190 const char FakeBluetoothDeviceClient::kUnpairableDeviceName[] =
191 "Unpairable Device";
192 const uint32 FakeBluetoothDeviceClient::kUnpairableDeviceClass = 0x002540;
194 const char FakeBluetoothDeviceClient::kJustWorksPath[] =
195 "/fake/hci0/devB";
196 const char FakeBluetoothDeviceClient::kJustWorksAddress[] =
197 "00:0C:8A:00:00:00";
198 const char FakeBluetoothDeviceClient::kJustWorksName[] =
199 "Just-Works Device";
200 const uint32 FakeBluetoothDeviceClient::kJustWorksClass = 0x240428;
202 const char FakeBluetoothDeviceClient::kLowEnergyPath[] =
203 "/fake/hci0/devC";
204 const char FakeBluetoothDeviceClient::kLowEnergyAddress[] =
205 "00:1A:11:00:15:30";
206 const char FakeBluetoothDeviceClient::kLowEnergyName[] =
207 "Bluetooth 4.0 Heart Rate Monitor";
208 const uint32 FakeBluetoothDeviceClient::kLowEnergyClass =
209 0x000918; // Major class "Health", Minor class "Heart/Pulse Rate Monitor."
211 const char FakeBluetoothDeviceClient::kPairedUnconnectableDevicePath[] =
212 "/fake/hci0/devD";
213 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress[] =
214 "20:7D:74:00:00:04";
215 const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceName[] =
216 "Paired Unconnectable Device";
217 const uint32 FakeBluetoothDeviceClient::kPairedUnconnectableDeviceClass =
218 0x000104;
220 FakeBluetoothDeviceClient::Properties::Properties(
221 const PropertyChangedCallback& callback)
222 : BluetoothDeviceClient::Properties(
223 NULL,
224 bluetooth_device::kBluetoothDeviceInterface,
225 callback) {
228 FakeBluetoothDeviceClient::Properties::~Properties() {
231 void FakeBluetoothDeviceClient::Properties::Get(
232 dbus::PropertyBase* property,
233 dbus::PropertySet::GetCallback callback) {
234 VLOG(1) << "Get " << property->name();
235 callback.Run(false);
238 void FakeBluetoothDeviceClient::Properties::GetAll() {
239 VLOG(1) << "GetAll";
242 void FakeBluetoothDeviceClient::Properties::Set(
243 dbus::PropertyBase *property,
244 dbus::PropertySet::SetCallback callback) {
245 VLOG(1) << "Set " << property->name();
246 if (property->name() == trusted.name()) {
247 callback.Run(true);
248 property->ReplaceValueWithSetValue();
249 } else {
250 callback.Run(false);
254 FakeBluetoothDeviceClient::IncomingDeviceProperties::
255 IncomingDeviceProperties() {}
257 FakeBluetoothDeviceClient::IncomingDeviceProperties::
258 ~IncomingDeviceProperties() {}
260 FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
261 : simulation_interval_ms_(kSimulationIntervalMs),
262 discovery_simulation_step_(0),
263 incoming_pairing_simulation_step_(0),
264 pairing_cancelled_(false),
265 connection_rssi_(kUnkownPower),
266 transmit_power_(kUnkownPower),
267 max_transmit_power_(kUnkownPower) {
268 scoped_ptr<Properties> properties(new Properties(
269 base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged,
270 base::Unretained(this), dbus::ObjectPath(kPairedDevicePath))));
271 properties->address.ReplaceValue(kPairedDeviceAddress);
272 properties->bluetooth_class.ReplaceValue(kPairedDeviceClass);
273 properties->name.ReplaceValue("Fake Device (Name)");
274 properties->alias.ReplaceValue(kPairedDeviceName);
275 properties->paired.ReplaceValue(true);
276 properties->trusted.ReplaceValue(true);
277 properties->adapter.ReplaceValue(
278 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
280 std::vector<std::string> uuids;
281 uuids.push_back("00001800-0000-1000-8000-00805f9b34fb");
282 uuids.push_back("00001801-0000-1000-8000-00805f9b34fb");
283 properties->uuids.ReplaceValue(uuids);
285 properties->modalias.ReplaceValue("usb:v05ACp030Dd0306");
287 properties_map_.insert(dbus::ObjectPath(kPairedDevicePath),
288 properties.Pass());
289 device_list_.push_back(dbus::ObjectPath(kPairedDevicePath));
291 properties.reset(new Properties(base::Bind(
292 &FakeBluetoothDeviceClient::OnPropertyChanged, base::Unretained(this),
293 dbus::ObjectPath(kPairedUnconnectableDevicePath))));
294 properties->address.ReplaceValue(kPairedUnconnectableDeviceAddress);
295 properties->bluetooth_class.ReplaceValue(kPairedUnconnectableDeviceClass);
296 properties->name.ReplaceValue("Fake Device 2 (Unconnectable)");
297 properties->alias.ReplaceValue(kPairedUnconnectableDeviceName);
298 properties->paired.ReplaceValue(true);
299 properties->trusted.ReplaceValue(true);
300 properties->adapter.ReplaceValue(
301 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
303 properties->uuids.ReplaceValue(uuids);
305 properties->modalias.ReplaceValue("usb:v05ACp030Dd0306");
307 properties_map_.insert(dbus::ObjectPath(kPairedUnconnectableDevicePath),
308 properties.Pass());
309 device_list_.push_back(dbus::ObjectPath(kPairedUnconnectableDevicePath));
312 FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() {
315 void FakeBluetoothDeviceClient::Init(dbus::Bus* bus) {
318 void FakeBluetoothDeviceClient::AddObserver(Observer* observer) {
319 observers_.AddObserver(observer);
322 void FakeBluetoothDeviceClient::RemoveObserver(Observer* observer) {
323 observers_.RemoveObserver(observer);
326 std::vector<dbus::ObjectPath> FakeBluetoothDeviceClient::GetDevicesForAdapter(
327 const dbus::ObjectPath& adapter_path) {
328 if (adapter_path ==
329 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath))
330 return device_list_;
331 else
332 return std::vector<dbus::ObjectPath>();
335 FakeBluetoothDeviceClient::Properties*
336 FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath& object_path) {
337 PropertiesMap::const_iterator iter = properties_map_.find(object_path);
338 if (iter != properties_map_.end())
339 return iter->second;
340 return NULL;
343 FakeBluetoothDeviceClient::SimulatedPairingOptions*
344 FakeBluetoothDeviceClient::GetPairingOptions(
345 const dbus::ObjectPath& object_path) {
346 PairingOptionsMap::const_iterator iter =
347 pairing_options_map_.find(object_path);
348 if (iter != pairing_options_map_.end())
349 return iter->second;
350 return iter != pairing_options_map_.end() ? iter->second : nullptr;
353 void FakeBluetoothDeviceClient::Connect(
354 const dbus::ObjectPath& object_path,
355 const base::Closure& callback,
356 const ErrorCallback& error_callback) {
357 VLOG(1) << "Connect: " << object_path.value();
358 Properties* properties = GetProperties(object_path);
360 if (properties->connected.value() == true) {
361 // Already connected.
362 callback.Run();
363 return;
366 if (properties->paired.value() != true &&
367 object_path != dbus::ObjectPath(kConnectUnpairablePath) &&
368 object_path != dbus::ObjectPath(kLowEnergyPath)) {
369 // Must be paired.
370 error_callback.Run(bluetooth_device::kErrorFailed, "Not paired");
371 return;
372 } else if (properties->paired.value() == true &&
373 (object_path == dbus::ObjectPath(kUnconnectableDevicePath) ||
374 object_path ==
375 dbus::ObjectPath(kPairedUnconnectableDevicePath))) {
376 // Must not be paired
377 error_callback.Run(bluetooth_device::kErrorFailed,
378 "Connection fails while paired");
379 return;
382 // The device can be connected.
383 properties->connected.ReplaceValue(true);
384 callback.Run();
386 // Expose GATT services if connected to LE device.
387 if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
388 FakeBluetoothGattServiceClient* gatt_service_client =
389 static_cast<FakeBluetoothGattServiceClient*>(
390 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
391 gatt_service_client->ExposeHeartRateService(
392 dbus::ObjectPath(kLowEnergyPath));
395 AddInputDeviceIfNeeded(object_path, properties);
398 void FakeBluetoothDeviceClient::Disconnect(
399 const dbus::ObjectPath& object_path,
400 const base::Closure& callback,
401 const ErrorCallback& error_callback) {
402 VLOG(1) << "Disconnect: " << object_path.value();
403 Properties* properties = GetProperties(object_path);
405 if (!properties->connected.value()) {
406 error_callback.Run("org.bluez.Error.NotConnected", "Not Connected");
407 return;
410 // Hide the Heart Rate Service if disconnected from LE device.
411 if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
412 FakeBluetoothGattServiceClient* gatt_service_client =
413 static_cast<FakeBluetoothGattServiceClient*>(
414 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
415 gatt_service_client->HideHeartRateService();
418 callback.Run();
419 properties->connected.ReplaceValue(false);
422 void FakeBluetoothDeviceClient::ConnectProfile(
423 const dbus::ObjectPath& object_path,
424 const std::string& uuid,
425 const base::Closure& callback,
426 const ErrorCallback& error_callback) {
427 VLOG(1) << "ConnectProfile: " << object_path.value() << " " << uuid;
429 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
430 static_cast<FakeBluetoothProfileManagerClient*>(
431 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
432 FakeBluetoothProfileServiceProvider* profile_service_provider =
433 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
434 if (profile_service_provider == NULL) {
435 error_callback.Run(kNoResponseError, "Missing profile");
436 return;
439 if (object_path == dbus::ObjectPath(kPairedUnconnectableDevicePath)) {
440 error_callback.Run(bluetooth_device::kErrorFailed, "unconnectable");
441 return;
444 // Make a socket pair of a compatible type with the type used by Bluetooth;
445 // spin up a thread to simulate the server side and wrap the client side in
446 // a D-Bus file descriptor object.
447 int socket_type = SOCK_STREAM;
448 if (uuid == FakeBluetoothProfileManagerClient::kL2capUuid)
449 socket_type = SOCK_SEQPACKET;
451 int fds[2];
452 if (socketpair(AF_UNIX, socket_type, 0, fds) < 0) {
453 error_callback.Run(kNoResponseError, "socketpair call failed");
454 return;
457 int args;
458 args = fcntl(fds[1], F_GETFL, NULL);
459 if (args < 0) {
460 error_callback.Run(kNoResponseError, "failed to get socket flags");
461 return;
464 args |= O_NONBLOCK;
465 if (fcntl(fds[1], F_SETFL, args) < 0) {
466 error_callback.Run(kNoResponseError, "failed to set socket non-blocking");
467 return;
470 base::WorkerPool::GetTaskRunner(false)->PostTask(
471 FROM_HERE,
472 base::Bind(&SimulatedProfileSocket,
473 fds[0]));
475 scoped_ptr<dbus::FileDescriptor> fd(new dbus::FileDescriptor(fds[1]));
477 // Post the new connection to the service provider.
478 BluetoothProfileServiceProvider::Delegate::Options options;
480 profile_service_provider->NewConnection(
481 object_path,
482 fd.Pass(),
483 options,
484 base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback,
485 base::Unretained(this),
486 object_path,
487 callback,
488 error_callback));
491 void FakeBluetoothDeviceClient::DisconnectProfile(
492 const dbus::ObjectPath& object_path,
493 const std::string& uuid,
494 const base::Closure& callback,
495 const ErrorCallback& error_callback) {
496 VLOG(1) << "DisconnectProfile: " << object_path.value() << " " << uuid;
498 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
499 static_cast<FakeBluetoothProfileManagerClient*>(
500 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
501 FakeBluetoothProfileServiceProvider* profile_service_provider =
502 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
503 if (profile_service_provider == NULL) {
504 error_callback.Run(kNoResponseError, "Missing profile");
505 return;
508 profile_service_provider->RequestDisconnection(
509 object_path,
510 base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback,
511 base::Unretained(this),
512 object_path,
513 callback,
514 error_callback));
517 void FakeBluetoothDeviceClient::Pair(
518 const dbus::ObjectPath& object_path,
519 const base::Closure& callback,
520 const ErrorCallback& error_callback) {
521 VLOG(1) << "Pair: " << object_path.value();
522 Properties* properties = GetProperties(object_path);
524 if (properties->paired.value() == true) {
525 // Already paired.
526 callback.Run();
527 return;
530 SimulatePairing(object_path, false, callback, error_callback);
533 void FakeBluetoothDeviceClient::CancelPairing(
534 const dbus::ObjectPath& object_path,
535 const base::Closure& callback,
536 const ErrorCallback& error_callback) {
537 VLOG(1) << "CancelPairing: " << object_path.value();
538 pairing_cancelled_ = true;
539 callback.Run();
542 void FakeBluetoothDeviceClient::GetConnInfo(
543 const dbus::ObjectPath& object_path,
544 const ConnInfoCallback& callback,
545 const ErrorCallback& error_callback) {
546 Properties* properties = GetProperties(object_path);
547 if (!properties->connected.value()) {
548 error_callback.Run("org.bluez.Error.NotConnected", "Not Connected");
549 return;
552 callback.Run(connection_rssi_, transmit_power_, max_transmit_power_);
555 void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
556 const dbus::ObjectPath& adapter_path) {
557 VLOG(1) << "starting discovery simulation";
559 discovery_simulation_step_ = 1;
561 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
562 FROM_HERE,
563 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
564 base::Unretained(this)),
565 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
568 void FakeBluetoothDeviceClient::EndDiscoverySimulation(
569 const dbus::ObjectPath& adapter_path) {
570 VLOG(1) << "stopping discovery simulation";
571 discovery_simulation_step_ = 0;
574 void FakeBluetoothDeviceClient::BeginIncomingPairingSimulation(
575 const dbus::ObjectPath& adapter_path) {
576 VLOG(1) << "starting incoming pairing simulation";
578 incoming_pairing_simulation_step_ = 1;
580 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
581 FROM_HERE,
582 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
583 base::Unretained(this)),
584 base::TimeDelta::FromMilliseconds(
585 kIncomingSimulationStartPairTimeMultiplier *
586 simulation_interval_ms_));
589 void FakeBluetoothDeviceClient::EndIncomingPairingSimulation(
590 const dbus::ObjectPath& adapter_path) {
591 VLOG(1) << "stopping incoming pairing simulation";
592 incoming_pairing_simulation_step_ = 0;
595 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms) {
596 simulation_interval_ms_ = interval_ms;
599 void FakeBluetoothDeviceClient::CreateDevice(
600 const dbus::ObjectPath& adapter_path,
601 const dbus::ObjectPath& device_path) {
602 if (std::find(device_list_.begin(),
603 device_list_.end(), device_path) != device_list_.end())
604 return;
606 scoped_ptr<Properties> properties(
607 new Properties(base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged,
608 base::Unretained(this), device_path)));
609 properties->adapter.ReplaceValue(adapter_path);
611 if (device_path == dbus::ObjectPath(kLegacyAutopairPath)) {
612 properties->address.ReplaceValue(kLegacyAutopairAddress);
613 properties->bluetooth_class.ReplaceValue(kLegacyAutopairClass);
614 properties->name.ReplaceValue("LegacyAutopair");
615 properties->alias.ReplaceValue(kLegacyAutopairName);
617 std::vector<std::string> uuids;
618 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
619 properties->uuids.ReplaceValue(uuids);
621 } else if (device_path == dbus::ObjectPath(kDisplayPinCodePath)) {
622 properties->address.ReplaceValue(kDisplayPinCodeAddress);
623 properties->bluetooth_class.ReplaceValue(kDisplayPinCodeClass);
624 properties->name.ReplaceValue("DisplayPinCode");
625 properties->alias.ReplaceValue(kDisplayPinCodeName);
627 std::vector<std::string> uuids;
628 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
629 properties->uuids.ReplaceValue(uuids);
631 } else if (device_path == dbus::ObjectPath(kVanishingDevicePath)) {
632 properties->address.ReplaceValue(kVanishingDeviceAddress);
633 properties->bluetooth_class.ReplaceValue(kVanishingDeviceClass);
634 properties->name.ReplaceValue("VanishingDevice");
635 properties->alias.ReplaceValue(kVanishingDeviceName);
637 } else if (device_path == dbus::ObjectPath(kConnectUnpairablePath)) {
638 properties->address.ReplaceValue(kConnectUnpairableAddress);
639 properties->bluetooth_class.ReplaceValue(kConnectUnpairableClass);
640 properties->name.ReplaceValue("ConnectUnpairable");
641 properties->alias.ReplaceValue(kConnectUnpairableName);
643 std::vector<std::string> uuids;
644 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
645 properties->uuids.ReplaceValue(uuids);
647 } else if (device_path == dbus::ObjectPath(kDisplayPasskeyPath)) {
648 properties->address.ReplaceValue(kDisplayPasskeyAddress);
649 properties->bluetooth_class.ReplaceValue(kDisplayPasskeyClass);
650 properties->name.ReplaceValue("DisplayPasskey");
651 properties->alias.ReplaceValue(kDisplayPasskeyName);
653 std::vector<std::string> uuids;
654 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
655 properties->uuids.ReplaceValue(uuids);
657 } else if (device_path == dbus::ObjectPath(kRequestPinCodePath)) {
658 properties->address.ReplaceValue(kRequestPinCodeAddress);
659 properties->bluetooth_class.ReplaceValue(kRequestPinCodeClass);
660 properties->name.ReplaceValue("RequestPinCode");
661 properties->alias.ReplaceValue(kRequestPinCodeName);
663 } else if (device_path == dbus::ObjectPath(kConfirmPasskeyPath)) {
664 properties->address.ReplaceValue(kConfirmPasskeyAddress);
665 properties->bluetooth_class.ReplaceValue(kConfirmPasskeyClass);
666 properties->name.ReplaceValue("ConfirmPasskey");
667 properties->alias.ReplaceValue(kConfirmPasskeyName);
669 } else if (device_path == dbus::ObjectPath(kRequestPasskeyPath)) {
670 properties->address.ReplaceValue(kRequestPasskeyAddress);
671 properties->bluetooth_class.ReplaceValue(kRequestPasskeyClass);
672 properties->name.ReplaceValue("RequestPasskey");
673 properties->alias.ReplaceValue(kRequestPasskeyName);
675 } else if (device_path == dbus::ObjectPath(kUnconnectableDevicePath)) {
676 properties->address.ReplaceValue(kUnconnectableDeviceAddress);
677 properties->bluetooth_class.ReplaceValue(kUnconnectableDeviceClass);
678 properties->name.ReplaceValue("UnconnectableDevice");
679 properties->alias.ReplaceValue(kUnconnectableDeviceName);
681 } else if (device_path == dbus::ObjectPath(kUnpairableDevicePath)) {
682 properties->address.ReplaceValue(kUnpairableDeviceAddress);
683 properties->bluetooth_class.ReplaceValue(kUnpairableDeviceClass);
684 properties->name.ReplaceValue("Fake Unpairable Device");
685 properties->alias.ReplaceValue(kUnpairableDeviceName);
687 } else if (device_path == dbus::ObjectPath(kJustWorksPath)) {
688 properties->address.ReplaceValue(kJustWorksAddress);
689 properties->bluetooth_class.ReplaceValue(kJustWorksClass);
690 properties->name.ReplaceValue("JustWorks");
691 properties->alias.ReplaceValue(kJustWorksName);
693 } else if (device_path == dbus::ObjectPath(kLowEnergyPath)) {
694 properties->address.ReplaceValue(kLowEnergyAddress);
695 properties->bluetooth_class.ReplaceValue(kLowEnergyClass);
696 properties->name.ReplaceValue("Heart Rate Monitor");
697 properties->alias.ReplaceValue(kLowEnergyName);
699 std::vector<std::string> uuids;
700 uuids.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID);
701 properties->uuids.ReplaceValue(uuids);
703 } else {
704 NOTREACHED();
708 properties_map_.insert(device_path, properties.Pass());
709 device_list_.push_back(device_path);
710 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
711 DeviceAdded(device_path));
714 void FakeBluetoothDeviceClient::CreateDeviceWithProperties(
715 const dbus::ObjectPath& adapter_path,
716 const IncomingDeviceProperties& props) {
717 dbus::ObjectPath device_path(props.device_path);
718 if (std::find(device_list_.begin(), device_list_.end(), device_path) !=
719 device_list_.end())
720 return;
722 scoped_ptr<Properties> properties(
723 new Properties(base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged,
724 base::Unretained(this), device_path)));
725 properties->adapter.ReplaceValue(adapter_path);
726 properties->name.ReplaceValue(props.device_name);
727 properties->alias.ReplaceValue(props.device_alias);
728 properties->address.ReplaceValue(props.device_address);
729 properties->bluetooth_class.ReplaceValue(props.device_class);
730 properties->trusted.ReplaceValue(props.is_trusted);
732 if (props.is_trusted)
733 properties->paired.ReplaceValue(true);
735 scoped_ptr<SimulatedPairingOptions> options(new SimulatedPairingOptions);
736 options->pairing_method = props.pairing_method;
737 options->pairing_auth_token = props.pairing_auth_token;
739 properties_map_.insert(device_path, properties.Pass());
740 device_list_.push_back(device_path);
741 pairing_options_map_.insert(device_path, options.Pass());
742 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
743 DeviceAdded(device_path));
746 void FakeBluetoothDeviceClient::RemoveDevice(
747 const dbus::ObjectPath& adapter_path,
748 const dbus::ObjectPath& device_path) {
749 std::vector<dbus::ObjectPath>::iterator listiter =
750 std::find(device_list_.begin(), device_list_.end(), device_path);
751 if (listiter == device_list_.end())
752 return;
754 PropertiesMap::const_iterator iter = properties_map_.find(device_path);
755 Properties* properties = iter->second;
757 VLOG(1) << "removing device: " << properties->alias.value();
758 device_list_.erase(listiter);
760 // Remove the Input interface if it exists. This should be called before the
761 // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
762 // BluetoothDeviceChromeOS object, including the device_path referenced here.
763 FakeBluetoothInputClient* fake_bluetooth_input_client =
764 static_cast<FakeBluetoothInputClient*>(
765 DBusThreadManager::Get()->GetBluetoothInputClient());
766 fake_bluetooth_input_client->RemoveInputDevice(device_path);
768 if (device_path == dbus::ObjectPath(kLowEnergyPath)) {
769 FakeBluetoothGattServiceClient* gatt_service_client =
770 static_cast<FakeBluetoothGattServiceClient*>(
771 DBusThreadManager::Get()->GetBluetoothGattServiceClient());
772 gatt_service_client->HideHeartRateService();
775 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
776 DeviceRemoved(device_path));
778 properties_map_.erase(iter);
779 PairingOptionsMap::const_iterator options_iter =
780 pairing_options_map_.find(device_path);
782 if (options_iter != pairing_options_map_.end()) {
783 pairing_options_map_.erase(options_iter);
787 void FakeBluetoothDeviceClient::OnPropertyChanged(
788 const dbus::ObjectPath& object_path,
789 const std::string& property_name) {
790 VLOG(2) << "Fake Bluetooth device property changed: " << object_path.value()
791 << ": " << property_name;
792 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
793 DevicePropertyChanged(object_path, property_name));
796 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
797 if (!discovery_simulation_step_)
798 return;
800 // Timer fires every .75s, the numbers below are arbitrary to give a feel
801 // for a discovery process.
802 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_;
803 if (discovery_simulation_step_ == 2) {
804 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
805 dbus::ObjectPath(kLegacyAutopairPath));
806 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
807 dbus::ObjectPath(kLowEnergyPath));
809 } else if (discovery_simulation_step_ == 4) {
810 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
811 base::RandInt(kMinRSSI, kMaxRSSI));
812 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
813 dbus::ObjectPath(kDisplayPinCodePath));
814 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
815 dbus::ObjectPath(kVanishingDevicePath));
817 } else if (discovery_simulation_step_ == 7) {
818 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
819 dbus::ObjectPath(kConnectUnpairablePath));
820 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
821 base::RandInt(kMinRSSI, kMaxRSSI));
823 } else if (discovery_simulation_step_ == 8) {
824 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
825 dbus::ObjectPath(kDisplayPasskeyPath));
826 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
827 dbus::ObjectPath(kRequestPinCodePath));
828 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
829 base::RandInt(kMinRSSI, kMaxRSSI));
831 } else if (discovery_simulation_step_ == 10) {
832 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
833 dbus::ObjectPath(kConfirmPasskeyPath));
834 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
835 dbus::ObjectPath(kRequestPasskeyPath));
836 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
837 dbus::ObjectPath(kUnconnectableDevicePath));
838 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
839 dbus::ObjectPath(kUnpairableDevicePath));
840 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
841 dbus::ObjectPath(kJustWorksPath));
842 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
843 base::RandInt(kMinRSSI, kMaxRSSI));
845 } else if (discovery_simulation_step_ == 13) {
846 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
847 base::RandInt(kMinRSSI, kMaxRSSI));
848 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
849 dbus::ObjectPath(kVanishingDevicePath));
850 } else if (discovery_simulation_step_ == 14) {
851 UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
852 base::RandInt(kMinRSSI, kMaxRSSI));
853 return;
857 ++discovery_simulation_step_;
858 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
859 FROM_HERE,
860 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
861 base::Unretained(this)),
862 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
865 void FakeBluetoothDeviceClient::IncomingPairingSimulationTimer() {
866 if (!incoming_pairing_simulation_step_)
867 return;
869 VLOG(1) << "incoming pairing simulation, step "
870 << incoming_pairing_simulation_step_;
871 switch (incoming_pairing_simulation_step_) {
872 case 1:
873 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
874 dbus::ObjectPath(kConfirmPasskeyPath));
875 SimulatePairing(dbus::ObjectPath(kConfirmPasskeyPath), true,
876 base::Bind(&base::DoNothing),
877 base::Bind(&SimpleErrorCallback));
878 break;
879 case 2:
880 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
881 dbus::ObjectPath(kJustWorksPath));
882 SimulatePairing(dbus::ObjectPath(kJustWorksPath), true,
883 base::Bind(&base::DoNothing),
884 base::Bind(&SimpleErrorCallback));
885 break;
886 case 3:
887 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
888 dbus::ObjectPath(kDisplayPinCodePath));
889 SimulatePairing(dbus::ObjectPath(kDisplayPinCodePath), true,
890 base::Bind(&base::DoNothing),
891 base::Bind(&SimpleErrorCallback));
892 break;
893 case 4:
894 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
895 dbus::ObjectPath(kDisplayPasskeyPath));
896 SimulatePairing(dbus::ObjectPath(kDisplayPasskeyPath), true,
897 base::Bind(&base::DoNothing),
898 base::Bind(&SimpleErrorCallback));
899 break;
900 case 5:
901 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
902 dbus::ObjectPath(kRequestPinCodePath));
903 SimulatePairing(dbus::ObjectPath(kRequestPinCodePath), true,
904 base::Bind(&base::DoNothing),
905 base::Bind(&SimpleErrorCallback));
906 break;
907 case 6:
908 CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
909 dbus::ObjectPath(kRequestPasskeyPath));
910 SimulatePairing(dbus::ObjectPath(kRequestPasskeyPath), true,
911 base::Bind(&base::DoNothing),
912 base::Bind(&SimpleErrorCallback));
913 break;
914 default:
915 return;
918 ++incoming_pairing_simulation_step_;
919 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
920 FROM_HERE,
921 base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
922 base::Unretained(this)),
923 base::TimeDelta::FromMilliseconds(kIncomingSimulationPairTimeMultiplier *
924 simulation_interval_ms_));
927 void FakeBluetoothDeviceClient::SimulatePairing(
928 const dbus::ObjectPath& object_path,
929 bool incoming_request,
930 const base::Closure& callback,
931 const ErrorCallback& error_callback) {
932 pairing_cancelled_ = false;
934 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
935 static_cast<FakeBluetoothAgentManagerClient*>(
936 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
937 FakeBluetoothAgentServiceProvider* agent_service_provider =
938 fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
939 CHECK(agent_service_provider != NULL);
941 // Grab the device's pairing properties.
942 PairingOptionsMap::const_iterator iter =
943 pairing_options_map_.find(object_path);
945 // If the device with path |object_path| has simulated pairing properties
946 // defined, then pair it based on its |pairing_method|.
947 if (iter != pairing_options_map_.end()) {
948 if (iter->second->pairing_method == kPairingMethodNone ||
949 iter->second->pairing_method.empty()) {
950 // Simply pair and connect the device.
951 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
952 FROM_HERE,
953 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
954 base::Unretained(this), object_path, callback,
955 error_callback),
956 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
957 simulation_interval_ms_));
958 } else if (iter->second->pairing_method == kPairingMethodPinCode) {
959 // Display a Pincode, and wait before acting as if the other end accepted
960 // it.
961 agent_service_provider->DisplayPinCode(object_path,
962 iter->second->pairing_auth_token);
964 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
965 FROM_HERE,
966 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
967 base::Unretained(this), object_path, callback,
968 error_callback),
969 base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier *
970 simulation_interval_ms_));
971 } else if (iter->second->pairing_method == kPairingMethodPassKey) {
972 // Display a passkey, and each interval act as if another key was entered
973 // for it.
974 agent_service_provider->DisplayPasskey(
975 object_path, std::stoi(iter->second->pairing_auth_token), 0);
977 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
978 FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
979 base::Unretained(this), 1, object_path,
980 callback, error_callback),
981 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
983 } else {
984 if (object_path == dbus::ObjectPath(kLegacyAutopairPath) ||
985 object_path == dbus::ObjectPath(kConnectUnpairablePath) ||
986 object_path == dbus::ObjectPath(kUnconnectableDevicePath) ||
987 object_path == dbus::ObjectPath(kLowEnergyPath)) {
988 // No need to call anything on the pairing delegate, just wait 3 times
989 // the interval before acting as if the other end accepted it.
990 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
991 FROM_HERE,
992 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
993 base::Unretained(this), object_path, callback,
994 error_callback),
995 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
996 simulation_interval_ms_));
998 } else if (object_path == dbus::ObjectPath(kDisplayPinCodePath)) {
999 // Display a Pincode, and wait before acting as if the other end accepted
1000 // it.
1001 agent_service_provider->DisplayPinCode(object_path, kTestPinCode);
1003 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1004 FROM_HERE,
1005 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1006 base::Unretained(this), object_path, callback,
1007 error_callback),
1008 base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier *
1009 simulation_interval_ms_));
1011 } else if (object_path == dbus::ObjectPath(kVanishingDevicePath)) {
1012 // The vanishing device simulates being too far away, and thus times out.
1013 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1014 FROM_HERE,
1015 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing,
1016 base::Unretained(this), object_path, error_callback),
1017 base::TimeDelta::FromMilliseconds(kVanishingDevicePairTimeMultiplier *
1018 simulation_interval_ms_));
1020 } else if (object_path == dbus::ObjectPath(kDisplayPasskeyPath)) {
1021 // Display a passkey, and each interval act as if another key was entered
1022 // for it.
1023 agent_service_provider->DisplayPasskey(object_path, kTestPassKey, 0);
1025 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1026 FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
1027 base::Unretained(this), 1, object_path,
1028 callback, error_callback),
1029 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1031 } else if (object_path == dbus::ObjectPath(kRequestPinCodePath)) {
1032 // Request a Pincode.
1033 agent_service_provider->RequestPinCode(
1034 object_path, base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback,
1035 base::Unretained(this), object_path, callback,
1036 error_callback));
1038 } else if (object_path == dbus::ObjectPath(kConfirmPasskeyPath)) {
1039 // Request confirmation of a Passkey.
1040 agent_service_provider->RequestConfirmation(
1041 object_path, kTestPassKey,
1042 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
1043 base::Unretained(this), object_path, callback,
1044 error_callback));
1046 } else if (object_path == dbus::ObjectPath(kRequestPasskeyPath)) {
1047 // Request a Passkey from the user.
1048 agent_service_provider->RequestPasskey(
1049 object_path, base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback,
1050 base::Unretained(this), object_path, callback,
1051 error_callback));
1053 } else if (object_path == dbus::ObjectPath(kUnpairableDevicePath)) {
1054 // Fails the pairing with an org.bluez.Error.Failed error.
1055 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1056 FROM_HERE,
1057 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing,
1058 base::Unretained(this), object_path, error_callback),
1059 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1061 } else if (object_path == dbus::ObjectPath(kJustWorksPath)) {
1062 if (incoming_request) {
1063 agent_service_provider->RequestAuthorization(
1064 object_path,
1065 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
1066 base::Unretained(this), object_path, callback,
1067 error_callback));
1069 } else {
1070 // No need to call anything on the pairing delegate, just wait before
1071 // acting as if the other end accepted it.
1072 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1073 FROM_HERE,
1074 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1075 base::Unretained(this), object_path, callback,
1076 error_callback),
1077 base::TimeDelta::FromMilliseconds(
1078 kSimulateNormalPairTimeMultiplier * simulation_interval_ms_));
1081 } else {
1082 error_callback.Run(kNoResponseError, "No pairing fake");
1087 void FakeBluetoothDeviceClient::CompleteSimulatedPairing(
1088 const dbus::ObjectPath& object_path,
1089 const base::Closure& callback,
1090 const ErrorCallback& error_callback) {
1091 VLOG(1) << "CompleteSimulatedPairing: " << object_path.value();
1092 if (pairing_cancelled_) {
1093 pairing_cancelled_ = false;
1095 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
1096 "Cancelled");
1097 } else {
1098 Properties* properties = GetProperties(object_path);
1100 properties->paired.ReplaceValue(true);
1101 callback.Run();
1103 AddInputDeviceIfNeeded(object_path, properties);
1107 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing(
1108 const dbus::ObjectPath& object_path,
1109 const ErrorCallback& error_callback) {
1110 VLOG(1) << "TimeoutSimulatedPairing: " << object_path.value();
1112 error_callback.Run(bluetooth_device::kErrorAuthenticationTimeout,
1113 "Timed out");
1116 void FakeBluetoothDeviceClient::CancelSimulatedPairing(
1117 const dbus::ObjectPath& object_path,
1118 const ErrorCallback& error_callback) {
1119 VLOG(1) << "CancelSimulatedPairing: " << object_path.value();
1121 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
1122 "Canceled");
1125 void FakeBluetoothDeviceClient::RejectSimulatedPairing(
1126 const dbus::ObjectPath& object_path,
1127 const ErrorCallback& error_callback) {
1128 VLOG(1) << "RejectSimulatedPairing: " << object_path.value();
1130 error_callback.Run(bluetooth_device::kErrorAuthenticationRejected,
1131 "Rejected");
1134 void FakeBluetoothDeviceClient::FailSimulatedPairing(
1135 const dbus::ObjectPath& object_path,
1136 const ErrorCallback& error_callback) {
1137 VLOG(1) << "FailSimulatedPairing: " << object_path.value();
1139 error_callback.Run(bluetooth_device::kErrorFailed, "Failed");
1142 void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded(
1143 const dbus::ObjectPath& object_path,
1144 Properties* properties) {
1145 // If the paired device is a HID device based on it's bluetooth class,
1146 // simulate the Input interface.
1147 FakeBluetoothInputClient* fake_bluetooth_input_client =
1148 static_cast<FakeBluetoothInputClient*>(
1149 DBusThreadManager::Get()->GetBluetoothInputClient());
1151 if ((properties->bluetooth_class.value() & 0x001f03) == 0x000500)
1152 fake_bluetooth_input_client->AddInputDevice(object_path);
1155 void FakeBluetoothDeviceClient::UpdateDeviceRSSI(
1156 const dbus::ObjectPath& object_path,
1157 int16 rssi) {
1158 PropertiesMap::const_iterator iter = properties_map_.find(object_path);
1159 if (iter == properties_map_.end()) {
1160 VLOG(2) << "Fake device does not exist: " << object_path.value();
1161 return;
1163 Properties* properties = iter->second;
1164 DCHECK(properties);
1165 properties->rssi.ReplaceValue(rssi);
1168 void FakeBluetoothDeviceClient::UpdateConnectionInfo(
1169 uint16 connection_rssi,
1170 uint16 transmit_power,
1171 uint16 max_transmit_power) {
1172 connection_rssi_ = connection_rssi;
1173 transmit_power_ = transmit_power;
1174 max_transmit_power_ = max_transmit_power;
1177 void FakeBluetoothDeviceClient::PinCodeCallback(
1178 const dbus::ObjectPath& object_path,
1179 const base::Closure& callback,
1180 const ErrorCallback& error_callback,
1181 BluetoothAgentServiceProvider::Delegate::Status status,
1182 const std::string& pincode) {
1183 VLOG(1) << "PinCodeCallback: " << object_path.value();
1185 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1186 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1187 FROM_HERE,
1188 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1189 base::Unretained(this), object_path, callback,
1190 error_callback),
1191 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
1192 simulation_interval_ms_));
1194 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1195 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1196 FROM_HERE,
1197 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1198 base::Unretained(this), object_path, error_callback),
1199 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1201 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1202 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1203 FROM_HERE,
1204 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1205 base::Unretained(this), object_path, error_callback),
1206 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1210 void FakeBluetoothDeviceClient::PasskeyCallback(
1211 const dbus::ObjectPath& object_path,
1212 const base::Closure& callback,
1213 const ErrorCallback& error_callback,
1214 BluetoothAgentServiceProvider::Delegate::Status status,
1215 uint32 passkey) {
1216 VLOG(1) << "PasskeyCallback: " << object_path.value();
1218 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1219 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1220 FROM_HERE,
1221 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1222 base::Unretained(this), object_path, callback,
1223 error_callback),
1224 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
1225 simulation_interval_ms_));
1227 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1228 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1229 FROM_HERE,
1230 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1231 base::Unretained(this), object_path, error_callback),
1232 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1234 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1235 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1236 FROM_HERE,
1237 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1238 base::Unretained(this), object_path, error_callback),
1239 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1243 void FakeBluetoothDeviceClient::ConfirmationCallback(
1244 const dbus::ObjectPath& object_path,
1245 const base::Closure& callback,
1246 const ErrorCallback& error_callback,
1247 BluetoothAgentServiceProvider::Delegate::Status status) {
1248 VLOG(1) << "ConfirmationCallback: " << object_path.value();
1250 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
1251 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1252 FROM_HERE,
1253 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1254 base::Unretained(this), object_path, callback,
1255 error_callback),
1256 base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
1257 simulation_interval_ms_));
1259 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
1260 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1261 FROM_HERE,
1262 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
1263 base::Unretained(this), object_path, error_callback),
1264 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1266 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
1267 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1268 FROM_HERE,
1269 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
1270 base::Unretained(this), object_path, error_callback),
1271 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1275 void FakeBluetoothDeviceClient::SimulateKeypress(
1276 uint16 entered,
1277 const dbus::ObjectPath& object_path,
1278 const base::Closure& callback,
1279 const ErrorCallback& error_callback) {
1280 VLOG(1) << "SimulateKeypress " << entered << ": " << object_path.value();
1282 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
1283 static_cast<FakeBluetoothAgentManagerClient*>(
1284 DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
1285 FakeBluetoothAgentServiceProvider* agent_service_provider =
1286 fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
1288 // The agent service provider object could have been destroyed after the
1289 // pairing is canceled.
1290 if (!agent_service_provider)
1291 return;
1293 agent_service_provider->DisplayPasskey(object_path, kTestPassKey, entered);
1295 if (entered < 7) {
1296 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1297 FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
1298 base::Unretained(this), entered + 1, object_path,
1299 callback, error_callback),
1300 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1302 } else {
1303 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1304 FROM_HERE,
1305 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
1306 base::Unretained(this), object_path, callback,
1307 error_callback),
1308 base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
1312 void FakeBluetoothDeviceClient::ConnectionCallback(
1313 const dbus::ObjectPath& object_path,
1314 const base::Closure& callback,
1315 const ErrorCallback& error_callback,
1316 BluetoothProfileServiceProvider::Delegate::Status status) {
1317 VLOG(1) << "ConnectionCallback: " << object_path.value();
1319 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
1320 callback.Run();
1321 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
1322 // TODO(keybuk): tear down this side of the connection
1323 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
1324 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
1325 // TODO(keybuk): tear down this side of the connection
1326 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
1330 void FakeBluetoothDeviceClient::DisconnectionCallback(
1331 const dbus::ObjectPath& object_path,
1332 const base::Closure& callback,
1333 const ErrorCallback& error_callback,
1334 BluetoothProfileServiceProvider::Delegate::Status status) {
1335 VLOG(1) << "DisconnectionCallback: " << object_path.value();
1337 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
1338 // TODO(keybuk): tear down this side of the connection
1339 callback.Run();
1340 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
1341 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
1342 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
1343 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
1347 } // namespace chromeos