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. 4 5 #include "chromeos/dbus/fake_bluetooth_device_client.h" 6 7 #include <fcntl.h> 8 #include <unistd.h> 9 #include <sys/types.h> 10 #include <sys/socket.h> 11 12 #include <algorithm> 13 #include <map> 14 #include <string> 15 #include <utility> 16 #include <vector> 17 18 #include "base/bind.h" 19 #include "base/logging.h" 20 #include "base/memory/scoped_ptr.h" 21 #include "base/message_loop/message_loop.h" 22 #include "base/stl_util.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_input_client.h" 30 #include "chromeos/dbus/fake_bluetooth_profile_manager_client.h" 31 #include "chromeos/dbus/fake_bluetooth_profile_service_provider.h" 32 #include "dbus/file_descriptor.h" 33 #include "dbus/object_path.h" 34 #include "third_party/cros_system_api/dbus/service_constants.h" 35 36 namespace { 37 38 // Default interval between simulated events. 39 const int kSimulationIntervalMs = 750; 40 41 42 void SimulatedProfileSocket(int fd) { 43 // Simulate a server-side socket of a profile; read data from the socket, 44 // write it back, and then close. 45 char buf[1024]; 46 ssize_t len; 47 ssize_t count; 48 49 len = read(fd, buf, sizeof buf); 50 if (len < 0) { 51 close(fd); 52 return; 53 } 54 55 count = len; 56 len = write(fd, buf, count); 57 if (len < 0) { 58 close(fd); 59 return; 60 } 61 62 close(fd); 63 } 64 65 } // namespace 66 67 namespace chromeos { 68 69 const char FakeBluetoothDeviceClient::kPairedDevicePath[] = 70 "/fake/hci0/dev0"; 71 const char FakeBluetoothDeviceClient::kPairedDeviceAddress[] = 72 "00:11:22:33:44:55"; 73 const char FakeBluetoothDeviceClient::kPairedDeviceName[] = 74 "Fake Device"; 75 const uint32 FakeBluetoothDeviceClient::kPairedDeviceClass = 0x000104; 76 77 const char FakeBluetoothDeviceClient::kAppleMousePath[] = 78 "/fake/hci0/dev1"; 79 const char FakeBluetoothDeviceClient::kAppleMouseAddress[] = 80 "28:CF:DA:00:00:00"; 81 const char FakeBluetoothDeviceClient::kAppleMouseName[] = 82 "Apple Magic Mouse"; 83 const uint32 FakeBluetoothDeviceClient::kAppleMouseClass = 0x002580; 84 85 const char FakeBluetoothDeviceClient::kAppleKeyboardPath[] = 86 "/fake/hci0/dev2"; 87 const char FakeBluetoothDeviceClient::kAppleKeyboardAddress[] = 88 "28:37:37:00:00:00"; 89 const char FakeBluetoothDeviceClient::kAppleKeyboardName[] = 90 "Apple Wireless Keyboard"; 91 const uint32 FakeBluetoothDeviceClient::kAppleKeyboardClass = 0x002540; 92 93 const char FakeBluetoothDeviceClient::kVanishingDevicePath[] = 94 "/fake/hci0/dev3"; 95 const char FakeBluetoothDeviceClient::kVanishingDeviceAddress[] = 96 "01:02:03:04:05:06"; 97 const char FakeBluetoothDeviceClient::kVanishingDeviceName[] = 98 "Vanishing Device"; 99 const uint32 FakeBluetoothDeviceClient::kVanishingDeviceClass = 0x000104; 100 101 const char FakeBluetoothDeviceClient::kMicrosoftMousePath[] = 102 "/fake/hci0/dev4"; 103 const char FakeBluetoothDeviceClient::kMicrosoftMouseAddress[] = 104 "7C:ED:8D:00:00:00"; 105 const char FakeBluetoothDeviceClient::kMicrosoftMouseName[] = 106 "Microsoft Mouse"; 107 const uint32 FakeBluetoothDeviceClient::kMicrosoftMouseClass = 0x002580; 108 109 const char FakeBluetoothDeviceClient::kMotorolaKeyboardPath[] = 110 "/fake/hci0/dev5"; 111 const char FakeBluetoothDeviceClient::kMotorolaKeyboardAddress[] = 112 "00:0F:F6:00:00:00"; 113 const char FakeBluetoothDeviceClient::kMotorolaKeyboardName[] = 114 "Motorola Keyboard"; 115 const uint32 FakeBluetoothDeviceClient::kMotorolaKeyboardClass = 0x002540; 116 117 const char FakeBluetoothDeviceClient::kSonyHeadphonesPath[] = 118 "/fake/hci0/dev6"; 119 const char FakeBluetoothDeviceClient::kSonyHeadphonesAddress[] = 120 "00:24:BE:00:00:00"; 121 const char FakeBluetoothDeviceClient::kSonyHeadphonesName[] = 122 "Sony BT-00"; 123 const uint32 FakeBluetoothDeviceClient::kSonyHeadphonesClass = 0x240408; 124 125 const char FakeBluetoothDeviceClient::kPhonePath[] = 126 "/fake/hci0/dev7"; 127 const char FakeBluetoothDeviceClient::kPhoneAddress[] = 128 "20:7D:74:00:00:00"; 129 const char FakeBluetoothDeviceClient::kPhoneName[] = 130 "Phone"; 131 const uint32 FakeBluetoothDeviceClient::kPhoneClass = 0x7a020c; 132 133 const char FakeBluetoothDeviceClient::kWeirdDevicePath[] = 134 "/fake/hci0/dev8"; 135 const char FakeBluetoothDeviceClient::kWeirdDeviceAddress[] = 136 "20:7D:74:00:00:01"; 137 const char FakeBluetoothDeviceClient::kWeirdDeviceName[] = 138 "Weird Device"; 139 const uint32 FakeBluetoothDeviceClient::kWeirdDeviceClass = 0x7a020c; 140 141 const char FakeBluetoothDeviceClient::kUnconnectableDevicePath[] = 142 "/fake/hci0/dev9"; 143 const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress[] = 144 "20:7D:74:00:00:02"; 145 const char FakeBluetoothDeviceClient::kUnconnectableDeviceName[] = 146 "Unconnectable Device"; 147 const uint32 FakeBluetoothDeviceClient::kUnconnectableDeviceClass = 0x7a020c; 148 149 const char FakeBluetoothDeviceClient::kUnpairableDevicePath[] = 150 "/fake/hci0/devA"; 151 const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress[] = 152 "20:7D:74:00:00:03"; 153 const char FakeBluetoothDeviceClient::kUnpairableDeviceName[] = 154 "Unpairable Device"; 155 const uint32 FakeBluetoothDeviceClient::kUnpairableDeviceClass = 0x002540; 156 157 FakeBluetoothDeviceClient::Properties::Properties( 158 const PropertyChangedCallback& callback) 159 : BluetoothDeviceClient::Properties( 160 NULL, 161 bluetooth_device::kBluetoothDeviceInterface, 162 callback) { 163 } 164 165 FakeBluetoothDeviceClient::Properties::~Properties() { 166 } 167 168 void FakeBluetoothDeviceClient::Properties::Get( 169 dbus::PropertyBase* property, 170 dbus::PropertySet::GetCallback callback) { 171 VLOG(1) << "Get " << property->name(); 172 callback.Run(false); 173 } 174 175 void FakeBluetoothDeviceClient::Properties::GetAll() { 176 VLOG(1) << "GetAll"; 177 } 178 179 void FakeBluetoothDeviceClient::Properties::Set( 180 dbus::PropertyBase *property, 181 dbus::PropertySet::SetCallback callback) { 182 VLOG(1) << "Set " << property->name(); 183 if (property->name() == trusted.name()) { 184 callback.Run(true); 185 property->ReplaceValueWithSetValue(); 186 } else { 187 callback.Run(false); 188 } 189 } 190 191 FakeBluetoothDeviceClient::FakeBluetoothDeviceClient() 192 : simulation_interval_ms_(kSimulationIntervalMs), 193 discovery_simulation_step_(0), 194 pairing_cancelled_(false) { 195 Properties* properties = new Properties(base::Bind( 196 &FakeBluetoothDeviceClient::OnPropertyChanged, 197 base::Unretained(this), 198 dbus::ObjectPath(kPairedDevicePath))); 199 properties->address.ReplaceValue(kPairedDeviceAddress); 200 properties->bluetooth_class.ReplaceValue(kPairedDeviceClass); 201 properties->name.ReplaceValue("Fake Device (Name)"); 202 properties->alias.ReplaceValue(kPairedDeviceName); 203 properties->paired.ReplaceValue(true); 204 properties->trusted.ReplaceValue(true); 205 properties->adapter.ReplaceValue( 206 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 207 208 std::vector<std::string> uuids; 209 uuids.push_back("00001800-0000-1000-8000-00805f9b34fb"); 210 uuids.push_back("00001801-0000-1000-8000-00805f9b34fb"); 211 properties->uuids.ReplaceValue(uuids); 212 213 properties->modalias.ReplaceValue("usb:v05ACp030Dd0306"); 214 215 properties_map_[dbus::ObjectPath(kPairedDevicePath)] = properties; 216 device_list_.push_back(dbus::ObjectPath(kPairedDevicePath)); 217 } 218 219 FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() { 220 // Clean up Properties structures 221 STLDeleteValues(&properties_map_); 222 } 223 224 void FakeBluetoothDeviceClient::Init(dbus::Bus* bus) { 225 } 226 227 void FakeBluetoothDeviceClient::AddObserver(Observer* observer) { 228 observers_.AddObserver(observer); 229 } 230 231 void FakeBluetoothDeviceClient::RemoveObserver(Observer* observer) { 232 observers_.RemoveObserver(observer); 233 } 234 235 std::vector<dbus::ObjectPath> FakeBluetoothDeviceClient::GetDevicesForAdapter( 236 const dbus::ObjectPath& adapter_path) { 237 if (adapter_path == 238 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)) 239 return device_list_; 240 else 241 return std::vector<dbus::ObjectPath>(); 242 } 243 244 FakeBluetoothDeviceClient::Properties* 245 FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath& object_path) { 246 PropertiesMap::iterator iter = properties_map_.find(object_path); 247 if (iter != properties_map_.end()) 248 return iter->second; 249 return NULL; 250 } 251 252 void FakeBluetoothDeviceClient::Connect( 253 const dbus::ObjectPath& object_path, 254 const base::Closure& callback, 255 const ErrorCallback& error_callback) { 256 VLOG(1) << "Connect: " << object_path.value(); 257 Properties* properties = GetProperties(object_path); 258 259 if (properties->connected.value() == true) { 260 // Already connected. 261 callback.Run(); 262 return; 263 } 264 265 if (properties->paired.value() != true && 266 object_path != dbus::ObjectPath(kMicrosoftMousePath)) { 267 // Must be paired. 268 error_callback.Run(bluetooth_device::kErrorFailed, "Not paired"); 269 return; 270 } else if (properties->paired.value() == true && 271 object_path == dbus::ObjectPath(kUnconnectableDevicePath)) { 272 // Must not be paired 273 error_callback.Run(bluetooth_device::kErrorFailed, 274 "Connection fails while paired"); 275 return; 276 } 277 278 // The device can be connected. 279 properties->connected.ReplaceValue(true); 280 callback.Run(); 281 282 AddInputDeviceIfNeeded(object_path, properties); 283 } 284 285 void FakeBluetoothDeviceClient::Disconnect( 286 const dbus::ObjectPath& object_path, 287 const base::Closure& callback, 288 const ErrorCallback& error_callback) { 289 VLOG(1) << "Disconnect: " << object_path.value(); 290 Properties* properties = GetProperties(object_path); 291 292 if (properties->connected.value() == true) { 293 callback.Run(); 294 properties->connected.ReplaceValue(false); 295 } else { 296 error_callback.Run("org.bluez.Error.NotConnected", "Not Connected"); 297 } 298 } 299 300 void FakeBluetoothDeviceClient::ConnectProfile( 301 const dbus::ObjectPath& object_path, 302 const std::string& uuid, 303 const base::Closure& callback, 304 const ErrorCallback& error_callback) { 305 VLOG(1) << "ConnectProfile: " << object_path.value() << " " << uuid; 306 307 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client = 308 static_cast<FakeBluetoothProfileManagerClient*>( 309 DBusThreadManager::Get()->GetBluetoothProfileManagerClient()); 310 FakeBluetoothProfileServiceProvider* profile_service_provider = 311 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid); 312 if (profile_service_provider == NULL) { 313 error_callback.Run(kNoResponseError, "Missing profile"); 314 return; 315 } 316 317 // Make a socket pair of a compatible type with the type used by Bluetooth; 318 // spin up a thread to simulate the server side and wrap the client side in 319 // a D-Bus file descriptor object. 320 int socket_type = SOCK_STREAM; 321 if (uuid == FakeBluetoothProfileManagerClient::kL2capUuid) 322 socket_type = SOCK_SEQPACKET; 323 324 int fds[2]; 325 if (socketpair(AF_UNIX, socket_type, 0, fds) < 0) { 326 error_callback.Run(kNoResponseError, "socketpair call failed"); 327 return; 328 } 329 330 int args; 331 args = fcntl(fds[1], F_GETFL, NULL); 332 if (args < 0) { 333 error_callback.Run(kNoResponseError, "failed to get socket flags"); 334 return; 335 } 336 337 args |= O_NONBLOCK; 338 if (fcntl(fds[1], F_SETFL, args) < 0) { 339 error_callback.Run(kNoResponseError, "failed to set socket non-blocking"); 340 return; 341 } 342 343 base::WorkerPool::GetTaskRunner(false)->PostTask( 344 FROM_HERE, 345 base::Bind(&SimulatedProfileSocket, 346 fds[0])); 347 348 scoped_ptr<dbus::FileDescriptor> fd(new dbus::FileDescriptor(fds[1])); 349 350 // Post the new connection to the service provider. 351 BluetoothProfileServiceProvider::Delegate::Options options; 352 353 profile_service_provider->NewConnection( 354 object_path, 355 fd.Pass(), 356 options, 357 base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback, 358 base::Unretained(this), 359 object_path, 360 callback, 361 error_callback)); 362 } 363 364 void FakeBluetoothDeviceClient::DisconnectProfile( 365 const dbus::ObjectPath& object_path, 366 const std::string& uuid, 367 const base::Closure& callback, 368 const ErrorCallback& error_callback) { 369 VLOG(1) << "DisconnectProfile: " << object_path.value() << " " << uuid; 370 371 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client = 372 static_cast<FakeBluetoothProfileManagerClient*>( 373 DBusThreadManager::Get()->GetBluetoothProfileManagerClient()); 374 FakeBluetoothProfileServiceProvider* profile_service_provider = 375 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid); 376 if (profile_service_provider == NULL) { 377 error_callback.Run(kNoResponseError, "Missing profile"); 378 return; 379 } 380 381 profile_service_provider->RequestDisconnection( 382 object_path, 383 base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback, 384 base::Unretained(this), 385 object_path, 386 callback, 387 error_callback)); 388 } 389 390 void FakeBluetoothDeviceClient::Pair( 391 const dbus::ObjectPath& object_path, 392 const base::Closure& callback, 393 const ErrorCallback& error_callback) { 394 VLOG(1) << "Pair: " << object_path.value(); 395 Properties* properties = GetProperties(object_path); 396 397 if (properties->paired.value() == true) { 398 // Already paired. 399 callback.Run(); 400 return; 401 } 402 403 pairing_cancelled_ = false; 404 405 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client = 406 static_cast<FakeBluetoothAgentManagerClient*>( 407 DBusThreadManager::Get()->GetBluetoothAgentManagerClient()); 408 FakeBluetoothAgentServiceProvider* agent_service_provider = 409 fake_bluetooth_agent_manager_client->GetAgentServiceProvider(); 410 if (agent_service_provider == NULL) { 411 error_callback.Run(kNoResponseError, "Missing agent"); 412 return; 413 } 414 415 if (object_path == dbus::ObjectPath(kAppleMousePath) || 416 object_path == dbus::ObjectPath(kMicrosoftMousePath) || 417 object_path == dbus::ObjectPath(kUnconnectableDevicePath)) { 418 // No need to call anything on the pairing delegate, just wait 3 times 419 // the interval before acting as if the other end accepted it. 420 base::MessageLoop::current()->PostDelayedTask( 421 FROM_HERE, 422 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, 423 base::Unretained(this), 424 object_path, callback, error_callback), 425 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_)); 426 427 } else if (object_path == dbus::ObjectPath(kAppleKeyboardPath)) { 428 // Display a Pincode, and wait 7 times the interval before acting as 429 // if the other end accepted it. 430 agent_service_provider->DisplayPinCode(object_path, "123456"); 431 432 base::MessageLoop::current()->PostDelayedTask( 433 FROM_HERE, 434 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, 435 base::Unretained(this), 436 object_path, callback, error_callback), 437 base::TimeDelta::FromMilliseconds(7 * simulation_interval_ms_)); 438 439 } else if (object_path == dbus::ObjectPath(kVanishingDevicePath)) { 440 // The vanishing device simulates being too far away, and thus times out. 441 base::MessageLoop::current()->PostDelayedTask( 442 FROM_HERE, 443 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing, 444 base::Unretained(this), 445 object_path, error_callback), 446 base::TimeDelta::FromMilliseconds(4 * simulation_interval_ms_)); 447 448 } else if (object_path == dbus::ObjectPath(kMotorolaKeyboardPath)) { 449 // Display a passkey, and each interval act as if another key was entered 450 // for it. 451 agent_service_provider->DisplayPasskey(object_path, 123456, 0); 452 453 base::MessageLoop::current()->PostDelayedTask( 454 FROM_HERE, 455 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress, 456 base::Unretained(this), 457 1, object_path, callback, error_callback), 458 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 459 460 } else if (object_path == dbus::ObjectPath(kSonyHeadphonesPath)) { 461 // Request a Pincode. 462 agent_service_provider->RequestPinCode( 463 object_path, 464 base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback, 465 base::Unretained(this), 466 object_path, 467 callback, 468 error_callback)); 469 470 } else if (object_path == dbus::ObjectPath(kPhonePath)) { 471 // Request confirmation of a Passkey. 472 agent_service_provider->RequestConfirmation( 473 object_path, 123456, 474 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback, 475 base::Unretained(this), 476 object_path, 477 callback, 478 error_callback)); 479 480 } else if (object_path == dbus::ObjectPath(kWeirdDevicePath)) { 481 // Request a Passkey from the user. 482 agent_service_provider->RequestPasskey( 483 object_path, 484 base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback, 485 base::Unretained(this), 486 object_path, 487 callback, 488 error_callback)); 489 490 } else if (object_path == dbus::ObjectPath(kUnpairableDevicePath)) { 491 // Fails the pairing with an org.bluez.Error.Failed error. 492 base::MessageLoop::current()->PostDelayedTask( 493 FROM_HERE, 494 base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing, 495 base::Unretained(this), 496 object_path, error_callback), 497 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 498 499 } else { 500 error_callback.Run(kNoResponseError, "No pairing fake"); 501 } 502 } 503 504 void FakeBluetoothDeviceClient::CancelPairing( 505 const dbus::ObjectPath& object_path, 506 const base::Closure& callback, 507 const ErrorCallback& error_callback) { 508 VLOG(1) << "CancelPairing: " << object_path.value(); 509 pairing_cancelled_ = true; 510 callback.Run(); 511 } 512 513 514 void FakeBluetoothDeviceClient::BeginDiscoverySimulation( 515 const dbus::ObjectPath& adapter_path) { 516 VLOG(1) << "starting discovery simulation"; 517 518 discovery_simulation_step_ = 1; 519 520 base::MessageLoop::current()->PostDelayedTask( 521 FROM_HERE, 522 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer, 523 base::Unretained(this)), 524 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 525 } 526 527 void FakeBluetoothDeviceClient::EndDiscoverySimulation( 528 const dbus::ObjectPath& adapter_path) { 529 VLOG(1) << "stopping discovery simulation"; 530 discovery_simulation_step_ = 0; 531 } 532 533 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms) { 534 simulation_interval_ms_ = interval_ms; 535 } 536 537 void FakeBluetoothDeviceClient::RemoveDevice( 538 const dbus::ObjectPath& adapter_path, 539 const dbus::ObjectPath& device_path) { 540 std::vector<dbus::ObjectPath>::iterator listiter = 541 std::find(device_list_.begin(), device_list_.end(), device_path); 542 if (listiter == device_list_.end()) 543 return; 544 545 PropertiesMap::iterator iter = properties_map_.find(device_path); 546 Properties* properties = iter->second; 547 548 VLOG(1) << "removing device: " << properties->alias.value(); 549 device_list_.erase(listiter); 550 551 // Remove the Input interface if it exists. This should be called before the 552 // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the 553 // BluetoothDeviceChromeOS object, including the device_path referenced here. 554 FakeBluetoothInputClient* fake_bluetooth_input_client = 555 static_cast<FakeBluetoothInputClient*>( 556 DBusThreadManager::Get()->GetBluetoothInputClient()); 557 fake_bluetooth_input_client->RemoveInputDevice(device_path); 558 559 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 560 DeviceRemoved(device_path)); 561 562 delete properties; 563 properties_map_.erase(iter); 564 } 565 566 void FakeBluetoothDeviceClient::OnPropertyChanged( 567 const dbus::ObjectPath& object_path, 568 const std::string& property_name) { 569 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 570 DevicePropertyChanged(object_path, property_name)); 571 } 572 573 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() { 574 if (!discovery_simulation_step_) 575 return; 576 577 // Timer fires every .75s, the numbers below are arbitrary to give a feel 578 // for a discovery process. 579 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_; 580 if (discovery_simulation_step_ == 2) { 581 if (std::find(device_list_.begin(), device_list_.end(), 582 dbus::ObjectPath(kAppleMousePath)) == device_list_.end()) { 583 Properties* properties = new Properties(base::Bind( 584 &FakeBluetoothDeviceClient::OnPropertyChanged, 585 base::Unretained(this), 586 dbus::ObjectPath(kAppleMousePath))); 587 properties->address.ReplaceValue(kAppleMouseAddress); 588 properties->bluetooth_class.ReplaceValue(kAppleMouseClass); 589 properties->name.ReplaceValue("Fake Apple Magic Mouse"); 590 properties->alias.ReplaceValue(kAppleMouseName); 591 properties->adapter.ReplaceValue( 592 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 593 594 std::vector<std::string> uuids; 595 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb"); 596 properties->uuids.ReplaceValue(uuids); 597 598 properties_map_[dbus::ObjectPath(kAppleMousePath)] = properties; 599 device_list_.push_back(dbus::ObjectPath(kAppleMousePath)); 600 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 601 DeviceAdded(dbus::ObjectPath(kAppleMousePath))); 602 } 603 604 } else if (discovery_simulation_step_ == 4) { 605 if (std::find(device_list_.begin(), device_list_.end(), 606 dbus::ObjectPath(kAppleKeyboardPath)) == device_list_.end()) { 607 Properties *properties = new Properties(base::Bind( 608 &FakeBluetoothDeviceClient::OnPropertyChanged, 609 base::Unretained(this), 610 dbus::ObjectPath(kAppleKeyboardPath))); 611 properties->address.ReplaceValue(kAppleKeyboardAddress); 612 properties->bluetooth_class.ReplaceValue(kAppleKeyboardClass); 613 properties->name.ReplaceValue("Fake Apple Wireless Keyboard"); 614 properties->alias.ReplaceValue(kAppleKeyboardName); 615 properties->adapter.ReplaceValue( 616 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 617 618 std::vector<std::string> uuids; 619 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb"); 620 properties->uuids.ReplaceValue(uuids); 621 622 properties_map_[dbus::ObjectPath(kAppleKeyboardPath)] = properties; 623 device_list_.push_back(dbus::ObjectPath(kAppleKeyboardPath)); 624 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 625 DeviceAdded(dbus::ObjectPath(kAppleKeyboardPath))); 626 } 627 628 if (std::find(device_list_.begin(), device_list_.end(), 629 dbus::ObjectPath(kVanishingDevicePath)) == 630 device_list_.end()) { 631 Properties* properties = new Properties(base::Bind( 632 &FakeBluetoothDeviceClient::OnPropertyChanged, 633 base::Unretained(this), 634 dbus::ObjectPath(kVanishingDevicePath))); 635 properties->address.ReplaceValue(kVanishingDeviceAddress); 636 properties->bluetooth_class.ReplaceValue(kVanishingDeviceClass); 637 properties->name.ReplaceValue("Fake Vanishing Device"); 638 properties->alias.ReplaceValue(kVanishingDeviceName); 639 properties->adapter.ReplaceValue( 640 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 641 642 properties_map_[dbus::ObjectPath(kVanishingDevicePath)] = properties; 643 device_list_.push_back(dbus::ObjectPath(kVanishingDevicePath)); 644 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 645 DeviceAdded(dbus::ObjectPath(kVanishingDevicePath))); 646 } 647 648 } else if (discovery_simulation_step_ == 7) { 649 if (std::find(device_list_.begin(), device_list_.end(), 650 dbus::ObjectPath(kMicrosoftMousePath)) == 651 device_list_.end()) { 652 Properties* properties = new Properties(base::Bind( 653 &FakeBluetoothDeviceClient::OnPropertyChanged, 654 base::Unretained(this), 655 dbus::ObjectPath(kMicrosoftMousePath))); 656 properties->address.ReplaceValue(kMicrosoftMouseAddress); 657 properties->bluetooth_class.ReplaceValue(kMicrosoftMouseClass); 658 properties->name.ReplaceValue("Fake Microsoft Mouse"); 659 properties->alias.ReplaceValue(kMicrosoftMouseName); 660 properties->adapter.ReplaceValue( 661 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 662 663 std::vector<std::string> uuids; 664 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb"); 665 properties->uuids.ReplaceValue(uuids); 666 667 properties_map_[dbus::ObjectPath(kMicrosoftMousePath)] = properties; 668 device_list_.push_back(dbus::ObjectPath(kMicrosoftMousePath)); 669 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 670 DeviceAdded(dbus::ObjectPath(kMicrosoftMousePath))); 671 } 672 673 } else if (discovery_simulation_step_ == 8) { 674 if (std::find(device_list_.begin(), device_list_.end(), 675 dbus::ObjectPath(kMotorolaKeyboardPath)) == 676 device_list_.end()) { 677 Properties* properties = new Properties(base::Bind( 678 &FakeBluetoothDeviceClient::OnPropertyChanged, 679 base::Unretained(this), 680 dbus::ObjectPath(kMotorolaKeyboardPath))); 681 properties->address.ReplaceValue(kMotorolaKeyboardAddress); 682 properties->bluetooth_class.ReplaceValue(kMotorolaKeyboardClass); 683 properties->name.ReplaceValue("Fake Motorola Keyboard"); 684 properties->alias.ReplaceValue(kMotorolaKeyboardName); 685 properties->adapter.ReplaceValue( 686 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 687 688 std::vector<std::string> uuids; 689 uuids.push_back("00001124-0000-1000-8000-00805f9b34fb"); 690 properties->uuids.ReplaceValue(uuids); 691 692 properties_map_[dbus::ObjectPath(kMotorolaKeyboardPath)] = properties; 693 device_list_.push_back(dbus::ObjectPath(kMotorolaKeyboardPath)); 694 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 695 DeviceAdded(dbus::ObjectPath(kMotorolaKeyboardPath))); 696 } 697 698 if (std::find(device_list_.begin(), device_list_.end(), 699 dbus::ObjectPath(kSonyHeadphonesPath)) == 700 device_list_.end()) { 701 Properties* properties = new Properties(base::Bind( 702 &FakeBluetoothDeviceClient::OnPropertyChanged, 703 base::Unretained(this), 704 dbus::ObjectPath(kSonyHeadphonesPath))); 705 properties->address.ReplaceValue(kSonyHeadphonesAddress); 706 properties->bluetooth_class.ReplaceValue(kSonyHeadphonesClass); 707 properties->name.ReplaceValue("Fake Sony Headphones"); 708 properties->alias.ReplaceValue(kSonyHeadphonesName); 709 properties->adapter.ReplaceValue( 710 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 711 712 properties_map_[dbus::ObjectPath(kSonyHeadphonesPath)] = properties; 713 device_list_.push_back(dbus::ObjectPath(kSonyHeadphonesPath)); 714 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 715 DeviceAdded(dbus::ObjectPath(kSonyHeadphonesPath))); 716 } 717 718 } else if (discovery_simulation_step_ == 10) { 719 if (std::find(device_list_.begin(), device_list_.end(), 720 dbus::ObjectPath(kPhonePath)) == device_list_.end()) { 721 Properties* properties = new Properties(base::Bind( 722 &FakeBluetoothDeviceClient::OnPropertyChanged, 723 base::Unretained(this), 724 dbus::ObjectPath(kPhonePath))); 725 properties->address.ReplaceValue(kPhoneAddress); 726 properties->bluetooth_class.ReplaceValue(kPhoneClass); 727 properties->name.ReplaceValue("Fake Phone"); 728 properties->alias.ReplaceValue(kPhoneName); 729 properties->adapter.ReplaceValue( 730 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 731 732 properties_map_[dbus::ObjectPath(kPhonePath)] = properties; 733 device_list_.push_back(dbus::ObjectPath(kPhonePath)); 734 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 735 DeviceAdded(dbus::ObjectPath(kPhonePath))); 736 } 737 738 if (std::find(device_list_.begin(), device_list_.end(), 739 dbus::ObjectPath(kWeirdDevicePath)) == device_list_.end()) { 740 Properties* properties = new Properties(base::Bind( 741 &FakeBluetoothDeviceClient::OnPropertyChanged, 742 base::Unretained(this), 743 dbus::ObjectPath(kWeirdDevicePath))); 744 properties->address.ReplaceValue(kWeirdDeviceAddress); 745 properties->bluetooth_class.ReplaceValue(kWeirdDeviceClass); 746 properties->name.ReplaceValue("Fake Weird Device"); 747 properties->alias.ReplaceValue(kWeirdDeviceName); 748 properties->adapter.ReplaceValue( 749 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 750 751 properties_map_[dbus::ObjectPath(kWeirdDevicePath)] = properties; 752 device_list_.push_back(dbus::ObjectPath(kWeirdDevicePath)); 753 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 754 DeviceAdded(dbus::ObjectPath(kWeirdDevicePath))); 755 } 756 757 if (std::find(device_list_.begin(), device_list_.end(), 758 dbus::ObjectPath(kUnconnectableDevicePath)) == 759 device_list_.end()) { 760 Properties* properties = new Properties(base::Bind( 761 &FakeBluetoothDeviceClient::OnPropertyChanged, 762 base::Unretained(this), 763 dbus::ObjectPath(kUnconnectableDevicePath))); 764 properties->address.ReplaceValue(kUnconnectableDeviceAddress); 765 properties->bluetooth_class.ReplaceValue(kUnconnectableDeviceClass); 766 properties->name.ReplaceValue("Fake Unconnectable Device"); 767 properties->alias.ReplaceValue(kUnconnectableDeviceName); 768 properties->adapter.ReplaceValue( 769 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 770 771 properties_map_[dbus::ObjectPath(kUnconnectableDevicePath)] = properties; 772 device_list_.push_back(dbus::ObjectPath(kUnconnectableDevicePath)); 773 FOR_EACH_OBSERVER( 774 BluetoothDeviceClient::Observer, observers_, 775 DeviceAdded(dbus::ObjectPath(kUnconnectableDevicePath))); 776 } 777 778 if (std::find(device_list_.begin(), device_list_.end(), 779 dbus::ObjectPath(kUnpairableDevicePath)) == 780 device_list_.end()) { 781 Properties* properties = new Properties(base::Bind( 782 &FakeBluetoothDeviceClient::OnPropertyChanged, 783 base::Unretained(this), 784 dbus::ObjectPath(kUnpairableDevicePath))); 785 properties->address.ReplaceValue(kUnpairableDeviceAddress); 786 properties->bluetooth_class.ReplaceValue(kUnpairableDeviceClass); 787 properties->name.ReplaceValue("Fake Unpairable Device"); 788 properties->alias.ReplaceValue(kUnpairableDeviceName); 789 properties->adapter.ReplaceValue( 790 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); 791 792 properties_map_[dbus::ObjectPath(kUnpairableDevicePath)] = properties; 793 device_list_.push_back(dbus::ObjectPath(kUnpairableDevicePath)); 794 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, 795 DeviceAdded(dbus::ObjectPath(kUnpairableDevicePath))); 796 } 797 798 } else if (discovery_simulation_step_ == 13) { 799 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 800 dbus::ObjectPath(kVanishingDevicePath)); 801 802 } else if (discovery_simulation_step_ == 14) { 803 return; 804 805 } 806 807 ++discovery_simulation_step_; 808 base::MessageLoop::current()->PostDelayedTask( 809 FROM_HERE, 810 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer, 811 base::Unretained(this)), 812 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 813 } 814 815 816 void FakeBluetoothDeviceClient::CompleteSimulatedPairing( 817 const dbus::ObjectPath& object_path, 818 const base::Closure& callback, 819 const ErrorCallback& error_callback) { 820 VLOG(1) << "CompleteSimulatedPairing: " << object_path.value(); 821 if (pairing_cancelled_) { 822 pairing_cancelled_ = false; 823 824 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled, 825 "Cancaled"); 826 } else { 827 Properties* properties = GetProperties(object_path); 828 829 properties->paired.ReplaceValue(true); 830 callback.Run(); 831 832 AddInputDeviceIfNeeded(object_path, properties); 833 } 834 } 835 836 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing( 837 const dbus::ObjectPath& object_path, 838 const ErrorCallback& error_callback) { 839 VLOG(1) << "TimeoutSimulatedPairing: " << object_path.value(); 840 841 error_callback.Run(bluetooth_device::kErrorAuthenticationTimeout, 842 "Timed out"); 843 } 844 845 void FakeBluetoothDeviceClient::CancelSimulatedPairing( 846 const dbus::ObjectPath& object_path, 847 const ErrorCallback& error_callback) { 848 VLOG(1) << "CancelSimulatedPairing: " << object_path.value(); 849 850 error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled, 851 "Canceled"); 852 } 853 854 void FakeBluetoothDeviceClient::RejectSimulatedPairing( 855 const dbus::ObjectPath& object_path, 856 const ErrorCallback& error_callback) { 857 VLOG(1) << "RejectSimulatedPairing: " << object_path.value(); 858 859 error_callback.Run(bluetooth_device::kErrorAuthenticationRejected, 860 "Rejected"); 861 } 862 863 void FakeBluetoothDeviceClient::FailSimulatedPairing( 864 const dbus::ObjectPath& object_path, 865 const ErrorCallback& error_callback) { 866 VLOG(1) << "FailSimulatedPairing: " << object_path.value(); 867 868 error_callback.Run(bluetooth_device::kErrorFailed, "Failed"); 869 } 870 871 void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded( 872 const dbus::ObjectPath& object_path, 873 Properties* properties) { 874 // If the paired device is a HID device based on it's bluetooth class, 875 // simulate the Input interface. 876 FakeBluetoothInputClient* fake_bluetooth_input_client = 877 static_cast<FakeBluetoothInputClient*>( 878 DBusThreadManager::Get()->GetBluetoothInputClient()); 879 880 if ((properties->bluetooth_class.value() & 0x001f03) == 0x000500) 881 fake_bluetooth_input_client->AddInputDevice(object_path); 882 } 883 884 void FakeBluetoothDeviceClient::PinCodeCallback( 885 const dbus::ObjectPath& object_path, 886 const base::Closure& callback, 887 const ErrorCallback& error_callback, 888 BluetoothAgentServiceProvider::Delegate::Status status, 889 const std::string& pincode) { 890 VLOG(1) << "PinCodeCallback: " << object_path.value(); 891 892 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) { 893 base::MessageLoop::current()->PostDelayedTask( 894 FROM_HERE, 895 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, 896 base::Unretained(this), 897 object_path, callback, error_callback), 898 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_)); 899 900 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) { 901 base::MessageLoop::current()->PostDelayedTask( 902 FROM_HERE, 903 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing, 904 base::Unretained(this), 905 object_path, error_callback), 906 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 907 908 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) { 909 base::MessageLoop::current()->PostDelayedTask( 910 FROM_HERE, 911 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, 912 base::Unretained(this), 913 object_path, error_callback), 914 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 915 916 } 917 } 918 919 void FakeBluetoothDeviceClient::PasskeyCallback( 920 const dbus::ObjectPath& object_path, 921 const base::Closure& callback, 922 const ErrorCallback& error_callback, 923 BluetoothAgentServiceProvider::Delegate::Status status, 924 uint32 passkey) { 925 VLOG(1) << "PasskeyCallback: " << object_path.value(); 926 927 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) { 928 base::MessageLoop::current()->PostDelayedTask( 929 FROM_HERE, 930 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, 931 base::Unretained(this), 932 object_path, callback, error_callback), 933 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_)); 934 935 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) { 936 base::MessageLoop::current()->PostDelayedTask( 937 FROM_HERE, 938 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing, 939 base::Unretained(this), 940 object_path, error_callback), 941 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 942 943 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) { 944 base::MessageLoop::current()->PostDelayedTask( 945 FROM_HERE, 946 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, 947 base::Unretained(this), 948 object_path, error_callback), 949 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 950 951 } 952 } 953 954 void FakeBluetoothDeviceClient::ConfirmationCallback( 955 const dbus::ObjectPath& object_path, 956 const base::Closure& callback, 957 const ErrorCallback& error_callback, 958 BluetoothAgentServiceProvider::Delegate::Status status) { 959 VLOG(1) << "ConfirmationCallback: " << object_path.value(); 960 961 if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) { 962 base::MessageLoop::current()->PostDelayedTask( 963 FROM_HERE, 964 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, 965 base::Unretained(this), 966 object_path, callback, error_callback), 967 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_)); 968 969 } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) { 970 base::MessageLoop::current()->PostDelayedTask( 971 FROM_HERE, 972 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing, 973 base::Unretained(this), 974 object_path, error_callback), 975 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 976 977 } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) { 978 base::MessageLoop::current()->PostDelayedTask( 979 FROM_HERE, 980 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, 981 base::Unretained(this), 982 object_path, error_callback), 983 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 984 985 } 986 } 987 988 void FakeBluetoothDeviceClient::SimulateKeypress( 989 uint16 entered, 990 const dbus::ObjectPath& object_path, 991 const base::Closure& callback, 992 const ErrorCallback& error_callback) { 993 VLOG(1) << "SimulateKeypress " << entered << ": " << object_path.value(); 994 995 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client = 996 static_cast<FakeBluetoothAgentManagerClient*>( 997 DBusThreadManager::Get()->GetBluetoothAgentManagerClient()); 998 FakeBluetoothAgentServiceProvider* agent_service_provider = 999 fake_bluetooth_agent_manager_client->GetAgentServiceProvider(); 1000 1001 // The agent service provider object could have been destroyed after the 1002 // pairing is canceled. 1003 if (!agent_service_provider) 1004 return; 1005 1006 agent_service_provider->DisplayPasskey(object_path, 123456, entered); 1007 1008 if (entered < 7) { 1009 base::MessageLoop::current()->PostDelayedTask( 1010 FROM_HERE, 1011 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress, 1012 base::Unretained(this), 1013 entered + 1, object_path, callback, error_callback), 1014 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 1015 1016 } else { 1017 base::MessageLoop::current()->PostDelayedTask( 1018 FROM_HERE, 1019 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, 1020 base::Unretained(this), 1021 object_path, callback, error_callback), 1022 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); 1023 1024 } 1025 } 1026 1027 void FakeBluetoothDeviceClient::ConnectionCallback( 1028 const dbus::ObjectPath& object_path, 1029 const base::Closure& callback, 1030 const ErrorCallback& error_callback, 1031 BluetoothProfileServiceProvider::Delegate::Status status) { 1032 VLOG(1) << "ConnectionCallback: " << object_path.value(); 1033 1034 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) { 1035 callback.Run(); 1036 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) { 1037 // TODO(keybuk): tear down this side of the connection 1038 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled"); 1039 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) { 1040 // TODO(keybuk): tear down this side of the connection 1041 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected"); 1042 } 1043 } 1044 1045 void FakeBluetoothDeviceClient::DisconnectionCallback( 1046 const dbus::ObjectPath& object_path, 1047 const base::Closure& callback, 1048 const ErrorCallback& error_callback, 1049 BluetoothProfileServiceProvider::Delegate::Status status) { 1050 VLOG(1) << "DisconnectionCallback: " << object_path.value(); 1051 1052 if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) { 1053 // TODO(keybuk): tear down this side of the connection 1054 callback.Run(); 1055 } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) { 1056 error_callback.Run(bluetooth_device::kErrorFailed, "Canceled"); 1057 } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) { 1058 error_callback.Run(bluetooth_device::kErrorFailed, "Rejected"); 1059 } 1060 } 1061 1062 } // namespace chromeos 1063