1 // Copyright 2014 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 "base/memory/scoped_vector.h" 6 #include "base/message_loop/message_loop.h" 7 #include "base/run_loop.h" 8 #include "chromeos/dbus/dbus_thread_manager.h" 9 #include "chromeos/dbus/fake_bluetooth_adapter_client.h" 10 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h" 11 #include "chromeos/dbus/fake_bluetooth_device_client.h" 12 #include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h" 13 #include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h" 14 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h" 15 #include "chromeos/dbus/fake_bluetooth_input_client.h" 16 #include "dbus/object_path.h" 17 #include "device/bluetooth/bluetooth_adapter.h" 18 #include "device/bluetooth/bluetooth_adapter_factory.h" 19 #include "device/bluetooth/bluetooth_device.h" 20 #include "device/bluetooth/bluetooth_gatt_characteristic.h" 21 #include "device/bluetooth/bluetooth_gatt_connection.h" 22 #include "device/bluetooth/bluetooth_gatt_descriptor.h" 23 #include "device/bluetooth/bluetooth_gatt_notify_session.h" 24 #include "device/bluetooth/bluetooth_gatt_service.h" 25 #include "device/bluetooth/bluetooth_uuid.h" 26 #include "testing/gtest/include/gtest/gtest.h" 27 28 using device::BluetoothAdapter; 29 using device::BluetoothDevice; 30 using device::BluetoothGattCharacteristic; 31 using device::BluetoothGattConnection; 32 using device::BluetoothGattDescriptor; 33 using device::BluetoothGattService; 34 using device::BluetoothGattNotifySession; 35 using device::BluetoothUUID; 36 37 namespace chromeos { 38 39 namespace { 40 41 const BluetoothUUID kHeartRateMeasurementUUID( 42 FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID); 43 const BluetoothUUID kBodySensorLocationUUID( 44 FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID); 45 const BluetoothUUID kHeartRateControlPointUUID( 46 FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID); 47 48 // Compares GATT characteristic/descriptor values. Returns true, if the values 49 // are equal. 50 bool ValuesEqual(const std::vector<uint8>& value0, 51 const std::vector<uint8>& value1) { 52 if (value0.size() != value1.size()) 53 return false; 54 for (size_t i = 0; i < value0.size(); ++i) 55 if (value0[i] != value1[i]) 56 return false; 57 return true; 58 } 59 60 class TestObserver : public BluetoothAdapter::Observer { 61 public: 62 TestObserver(scoped_refptr<BluetoothAdapter> adapter) 63 : gatt_service_added_count_(0), 64 gatt_service_removed_count_(0), 65 gatt_service_changed_count_(0), 66 gatt_discovery_complete_count_(0), 67 gatt_characteristic_added_count_(0), 68 gatt_characteristic_removed_count_(0), 69 gatt_characteristic_value_changed_count_(0), 70 gatt_descriptor_added_count_(0), 71 gatt_descriptor_removed_count_(0), 72 gatt_descriptor_value_changed_count_(0), 73 adapter_(adapter) { 74 adapter_->AddObserver(this); 75 } 76 77 virtual ~TestObserver() { 78 adapter_->RemoveObserver(this); 79 } 80 81 // BluetoothAdapter::Observer overrides. 82 virtual void GattServiceAdded(BluetoothAdapter* adapter, 83 BluetoothDevice* device, 84 BluetoothGattService* service) OVERRIDE { 85 ASSERT_EQ(adapter_.get(), adapter); 86 ASSERT_EQ(service->GetDevice(), device); 87 88 ++gatt_service_added_count_; 89 last_gatt_service_id_ = service->GetIdentifier(); 90 last_gatt_service_uuid_ = service->GetUUID(); 91 92 EXPECT_FALSE(service->IsLocal()); 93 EXPECT_TRUE(service->IsPrimary()); 94 95 EXPECT_EQ(device->GetGattService(last_gatt_service_id_), service); 96 97 QuitMessageLoop(); 98 } 99 100 virtual void GattServiceRemoved(BluetoothAdapter* adapter, 101 BluetoothDevice* device, 102 BluetoothGattService* service) OVERRIDE { 103 ASSERT_EQ(adapter_.get(), adapter); 104 ASSERT_EQ(service->GetDevice(), device); 105 106 ++gatt_service_removed_count_; 107 last_gatt_service_id_ = service->GetIdentifier(); 108 last_gatt_service_uuid_ = service->GetUUID(); 109 110 EXPECT_FALSE(service->IsLocal()); 111 EXPECT_TRUE(service->IsPrimary()); 112 113 // The device should return NULL for this service. 114 EXPECT_FALSE(device->GetGattService(last_gatt_service_id_)); 115 116 QuitMessageLoop(); 117 } 118 119 virtual void GattDiscoveryCompleteForService( 120 BluetoothAdapter* adapter, 121 BluetoothGattService* service) OVERRIDE { 122 ASSERT_EQ(adapter_.get(), adapter); 123 ++gatt_discovery_complete_count_; 124 125 QuitMessageLoop(); 126 } 127 128 virtual void GattServiceChanged(BluetoothAdapter* adapter, 129 BluetoothGattService* service) OVERRIDE { 130 ASSERT_EQ(adapter_.get(), adapter); 131 ++gatt_service_changed_count_; 132 133 QuitMessageLoop(); 134 } 135 136 virtual void GattCharacteristicAdded( 137 BluetoothAdapter* adapter, 138 BluetoothGattCharacteristic* characteristic) OVERRIDE { 139 ASSERT_EQ(adapter_.get(), adapter); 140 141 ++gatt_characteristic_added_count_; 142 last_gatt_characteristic_id_ = characteristic->GetIdentifier(); 143 last_gatt_characteristic_uuid_ = characteristic->GetUUID(); 144 145 ASSERT_TRUE(characteristic->GetService()); 146 EXPECT_EQ(characteristic->GetService()->GetCharacteristic( 147 last_gatt_characteristic_id_), 148 characteristic); 149 150 QuitMessageLoop(); 151 } 152 153 virtual void GattCharacteristicRemoved( 154 BluetoothAdapter* adapter, 155 BluetoothGattCharacteristic* characteristic) OVERRIDE { 156 ASSERT_EQ(adapter_.get(), adapter); 157 158 ++gatt_characteristic_removed_count_; 159 last_gatt_characteristic_id_ = characteristic->GetIdentifier(); 160 last_gatt_characteristic_uuid_ = characteristic->GetUUID(); 161 162 // The service should return NULL for this characteristic. 163 ASSERT_TRUE(characteristic->GetService()); 164 EXPECT_FALSE(characteristic->GetService()->GetCharacteristic( 165 last_gatt_characteristic_id_)); 166 167 QuitMessageLoop(); 168 } 169 170 virtual void GattCharacteristicValueChanged( 171 BluetoothAdapter* adapter, 172 BluetoothGattCharacteristic* characteristic, 173 const std::vector<uint8>& value) OVERRIDE { 174 ASSERT_EQ(adapter_.get(), adapter); 175 176 ++gatt_characteristic_value_changed_count_; 177 last_gatt_characteristic_id_ = characteristic->GetIdentifier(); 178 last_gatt_characteristic_uuid_ = characteristic->GetUUID(); 179 last_changed_characteristic_value_ = value; 180 181 ASSERT_TRUE(characteristic->GetService()); 182 EXPECT_EQ(characteristic->GetService()->GetCharacteristic( 183 last_gatt_characteristic_id_), 184 characteristic); 185 186 QuitMessageLoop(); 187 } 188 189 virtual void GattDescriptorAdded( 190 BluetoothAdapter* adapter, 191 BluetoothGattDescriptor* descriptor) OVERRIDE { 192 ASSERT_EQ(adapter_.get(), adapter); 193 194 ++gatt_descriptor_added_count_; 195 last_gatt_descriptor_id_ = descriptor->GetIdentifier(); 196 last_gatt_descriptor_uuid_ = descriptor->GetUUID(); 197 198 ASSERT_TRUE(descriptor->GetCharacteristic()); 199 EXPECT_EQ(descriptor->GetCharacteristic()->GetDescriptor( 200 last_gatt_descriptor_id_), 201 descriptor); 202 203 QuitMessageLoop(); 204 } 205 206 virtual void GattDescriptorRemoved( 207 BluetoothAdapter* adapter, 208 BluetoothGattDescriptor* descriptor) OVERRIDE { 209 ASSERT_EQ(adapter_.get(), adapter); 210 211 ++gatt_descriptor_removed_count_; 212 last_gatt_descriptor_id_ = descriptor->GetIdentifier(); 213 last_gatt_descriptor_uuid_ = descriptor->GetUUID(); 214 215 // The characteristic should return NULL for this descriptor.. 216 ASSERT_TRUE(descriptor->GetCharacteristic()); 217 EXPECT_FALSE(descriptor->GetCharacteristic()->GetDescriptor( 218 last_gatt_descriptor_id_)); 219 220 QuitMessageLoop(); 221 } 222 223 virtual void GattDescriptorValueChanged( 224 BluetoothAdapter* adapter, 225 BluetoothGattDescriptor* descriptor, 226 const std::vector<uint8>& value) OVERRIDE { 227 ASSERT_EQ(adapter_.get(), adapter); 228 229 ++gatt_descriptor_value_changed_count_; 230 last_gatt_descriptor_id_ = descriptor->GetIdentifier(); 231 last_gatt_descriptor_uuid_ = descriptor->GetUUID(); 232 last_changed_descriptor_value_ = value; 233 234 ASSERT_TRUE(descriptor->GetCharacteristic()); 235 EXPECT_EQ(descriptor->GetCharacteristic()->GetDescriptor( 236 last_gatt_descriptor_id_), 237 descriptor); 238 239 QuitMessageLoop(); 240 } 241 242 int gatt_service_added_count_; 243 int gatt_service_removed_count_; 244 int gatt_service_changed_count_; 245 int gatt_discovery_complete_count_; 246 int gatt_characteristic_added_count_; 247 int gatt_characteristic_removed_count_; 248 int gatt_characteristic_value_changed_count_; 249 int gatt_descriptor_added_count_; 250 int gatt_descriptor_removed_count_; 251 int gatt_descriptor_value_changed_count_; 252 std::string last_gatt_service_id_; 253 BluetoothUUID last_gatt_service_uuid_; 254 std::string last_gatt_characteristic_id_; 255 BluetoothUUID last_gatt_characteristic_uuid_; 256 std::vector<uint8> last_changed_characteristic_value_; 257 std::string last_gatt_descriptor_id_; 258 BluetoothUUID last_gatt_descriptor_uuid_; 259 std::vector<uint8> last_changed_descriptor_value_; 260 261 private: 262 // Some tests use a message loop since background processing is simulated; 263 // break out of those loops. 264 void QuitMessageLoop() { 265 if (base::MessageLoop::current() && 266 base::MessageLoop::current()->is_running()) 267 base::MessageLoop::current()->Quit(); 268 } 269 270 scoped_refptr<BluetoothAdapter> adapter_; 271 }; 272 273 } // namespace 274 275 class BluetoothGattChromeOSTest : public testing::Test { 276 public: 277 BluetoothGattChromeOSTest() 278 : fake_bluetooth_gatt_service_client_(NULL), 279 success_callback_count_(0), 280 error_callback_count_(0) { 281 } 282 283 virtual void SetUp() { 284 scoped_ptr<DBusThreadManagerSetter> dbus_setter = 285 chromeos::DBusThreadManager::GetSetterForTesting(); 286 fake_bluetooth_device_client_ = new FakeBluetoothDeviceClient; 287 fake_bluetooth_gatt_service_client_ = 288 new FakeBluetoothGattServiceClient; 289 fake_bluetooth_gatt_characteristic_client_ = 290 new FakeBluetoothGattCharacteristicClient; 291 fake_bluetooth_gatt_descriptor_client_ = 292 new FakeBluetoothGattDescriptorClient; 293 dbus_setter->SetBluetoothDeviceClient( 294 scoped_ptr<BluetoothDeviceClient>( 295 fake_bluetooth_device_client_)); 296 dbus_setter->SetBluetoothGattServiceClient( 297 scoped_ptr<BluetoothGattServiceClient>( 298 fake_bluetooth_gatt_service_client_)); 299 dbus_setter->SetBluetoothGattCharacteristicClient( 300 scoped_ptr<BluetoothGattCharacteristicClient>( 301 fake_bluetooth_gatt_characteristic_client_)); 302 dbus_setter->SetBluetoothGattDescriptorClient( 303 scoped_ptr<BluetoothGattDescriptorClient>( 304 fake_bluetooth_gatt_descriptor_client_)); 305 dbus_setter->SetBluetoothAdapterClient( 306 scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient)); 307 dbus_setter->SetBluetoothInputClient( 308 scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient)); 309 dbus_setter->SetBluetoothAgentManagerClient( 310 scoped_ptr<BluetoothAgentManagerClient>( 311 new FakeBluetoothAgentManagerClient)); 312 313 GetAdapter(); 314 315 adapter_->SetPowered( 316 true, 317 base::Bind(&base::DoNothing), 318 base::Bind(&base::DoNothing)); 319 ASSERT_TRUE(adapter_->IsPowered()); 320 } 321 322 virtual void TearDown() { 323 adapter_ = NULL; 324 update_sessions_.clear(); 325 gatt_conn_.reset(); 326 DBusThreadManager::Shutdown(); 327 } 328 329 void GetAdapter() { 330 device::BluetoothAdapterFactory::GetAdapter( 331 base::Bind(&BluetoothGattChromeOSTest::AdapterCallback, 332 base::Unretained(this))); 333 ASSERT_TRUE(adapter_.get() != NULL); 334 ASSERT_TRUE(adapter_->IsInitialized()); 335 ASSERT_TRUE(adapter_->IsPresent()); 336 } 337 338 void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) { 339 adapter_ = adapter; 340 } 341 342 void SuccessCallback() { 343 ++success_callback_count_; 344 } 345 346 void ValueCallback(const std::vector<uint8>& value) { 347 ++success_callback_count_; 348 last_read_value_ = value; 349 } 350 351 void GattConnectionCallback(scoped_ptr<BluetoothGattConnection> conn) { 352 ++success_callback_count_; 353 gatt_conn_ = conn.Pass(); 354 } 355 356 void NotifySessionCallback(scoped_ptr<BluetoothGattNotifySession> session) { 357 ++success_callback_count_; 358 update_sessions_.push_back(session.release()); 359 QuitMessageLoop(); 360 } 361 362 void ErrorCallback() { 363 ++error_callback_count_; 364 } 365 366 void DBusErrorCallback(const std::string& error_name, 367 const std::string& error_message) { 368 ++error_callback_count_; 369 } 370 371 void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error) { 372 ++error_callback_count_; 373 } 374 375 protected: 376 void QuitMessageLoop() { 377 if (base::MessageLoop::current() && 378 base::MessageLoop::current()->is_running()) 379 base::MessageLoop::current()->Quit(); 380 } 381 382 base::MessageLoop message_loop_; 383 384 FakeBluetoothDeviceClient* fake_bluetooth_device_client_; 385 FakeBluetoothGattServiceClient* fake_bluetooth_gatt_service_client_; 386 FakeBluetoothGattCharacteristicClient* 387 fake_bluetooth_gatt_characteristic_client_; 388 FakeBluetoothGattDescriptorClient* fake_bluetooth_gatt_descriptor_client_; 389 scoped_ptr<device::BluetoothGattConnection> gatt_conn_; 390 ScopedVector<BluetoothGattNotifySession> update_sessions_; 391 scoped_refptr<BluetoothAdapter> adapter_; 392 393 int success_callback_count_; 394 int error_callback_count_; 395 std::vector<uint8> last_read_value_; 396 }; 397 398 TEST_F(BluetoothGattChromeOSTest, GattConnection) { 399 fake_bluetooth_device_client_->CreateDevice( 400 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 401 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 402 BluetoothDevice* device = adapter_->GetDevice( 403 FakeBluetoothDeviceClient::kLowEnergyAddress); 404 ASSERT_TRUE(device); 405 ASSERT_FALSE(device->IsConnected()); 406 ASSERT_FALSE(gatt_conn_.get()); 407 ASSERT_EQ(0, success_callback_count_); 408 ASSERT_EQ(0, error_callback_count_); 409 410 device->CreateGattConnection( 411 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback, 412 base::Unretained(this)), 413 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback, 414 base::Unretained(this))); 415 416 EXPECT_EQ(1, success_callback_count_); 417 EXPECT_EQ(0, error_callback_count_); 418 EXPECT_TRUE(device->IsConnected()); 419 ASSERT_TRUE(gatt_conn_.get()); 420 EXPECT_TRUE(gatt_conn_->IsConnected()); 421 EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress, 422 gatt_conn_->GetDeviceAddress()); 423 424 gatt_conn_->Disconnect( 425 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback, 426 base::Unretained(this))); 427 EXPECT_EQ(2, success_callback_count_); 428 EXPECT_EQ(0, error_callback_count_); 429 EXPECT_TRUE(device->IsConnected()); 430 EXPECT_FALSE(gatt_conn_->IsConnected()); 431 432 device->CreateGattConnection( 433 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback, 434 base::Unretained(this)), 435 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback, 436 base::Unretained(this))); 437 438 EXPECT_EQ(3, success_callback_count_); 439 EXPECT_EQ(0, error_callback_count_); 440 EXPECT_TRUE(device->IsConnected()); 441 ASSERT_TRUE(gatt_conn_.get()); 442 EXPECT_TRUE(gatt_conn_->IsConnected()); 443 444 device->Disconnect( 445 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback, 446 base::Unretained(this)), 447 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 448 base::Unretained(this))); 449 450 EXPECT_EQ(4, success_callback_count_); 451 EXPECT_EQ(0, error_callback_count_); 452 ASSERT_TRUE(gatt_conn_.get()); 453 EXPECT_FALSE(gatt_conn_->IsConnected()); 454 455 device->CreateGattConnection( 456 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback, 457 base::Unretained(this)), 458 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback, 459 base::Unretained(this))); 460 461 EXPECT_EQ(5, success_callback_count_); 462 EXPECT_EQ(0, error_callback_count_); 463 EXPECT_TRUE(device->IsConnected()); 464 EXPECT_TRUE(gatt_conn_->IsConnected()); 465 466 fake_bluetooth_device_client_->RemoveDevice( 467 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 468 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 469 ASSERT_TRUE(gatt_conn_.get()); 470 EXPECT_FALSE(gatt_conn_->IsConnected()); 471 } 472 473 TEST_F(BluetoothGattChromeOSTest, GattServiceAddedAndRemoved) { 474 // Create a fake LE device. We store the device pointer here because this is a 475 // test. It's unsafe to do this in production as the device might get deleted. 476 fake_bluetooth_device_client_->CreateDevice( 477 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 478 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 479 BluetoothDevice* device = adapter_->GetDevice( 480 FakeBluetoothDeviceClient::kLowEnergyAddress); 481 ASSERT_TRUE(device); 482 483 TestObserver observer(adapter_); 484 485 EXPECT_EQ(0, observer.gatt_service_added_count_); 486 EXPECT_EQ(0, observer.gatt_service_removed_count_); 487 EXPECT_TRUE(observer.last_gatt_service_id_.empty()); 488 EXPECT_FALSE(observer.last_gatt_service_uuid_.IsValid()); 489 EXPECT_TRUE(device->GetGattServices().empty()); 490 491 // Expose the fake Heart Rate Service. 492 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 493 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 494 EXPECT_EQ(1, observer.gatt_service_added_count_); 495 EXPECT_EQ(0, observer.gatt_service_removed_count_); 496 EXPECT_FALSE(observer.last_gatt_service_id_.empty()); 497 EXPECT_EQ(1U, device->GetGattServices().size()); 498 EXPECT_EQ( 499 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), 500 observer.last_gatt_service_uuid_); 501 502 BluetoothGattService* service = 503 device->GetGattService(observer.last_gatt_service_id_); 504 EXPECT_FALSE(service->IsLocal()); 505 EXPECT_TRUE(service->IsPrimary()); 506 EXPECT_EQ(service, device->GetGattServices()[0]); 507 EXPECT_EQ(service, device->GetGattService(service->GetIdentifier())); 508 509 EXPECT_EQ(observer.last_gatt_service_uuid_, service->GetUUID()); 510 511 // Hide the service. 512 observer.last_gatt_service_uuid_ = BluetoothUUID(); 513 observer.last_gatt_service_id_.clear(); 514 fake_bluetooth_gatt_service_client_->HideHeartRateService(); 515 516 EXPECT_EQ(1, observer.gatt_service_added_count_); 517 EXPECT_EQ(1, observer.gatt_service_removed_count_); 518 EXPECT_FALSE(observer.last_gatt_service_id_.empty()); 519 EXPECT_TRUE(device->GetGattServices().empty()); 520 EXPECT_EQ( 521 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), 522 observer.last_gatt_service_uuid_); 523 524 EXPECT_EQ(NULL, device->GetGattService(observer.last_gatt_service_id_)); 525 526 // Expose the service again. 527 observer.last_gatt_service_uuid_ = BluetoothUUID(); 528 observer.last_gatt_service_id_.clear(); 529 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 530 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 531 EXPECT_EQ(2, observer.gatt_service_added_count_); 532 EXPECT_EQ(1, observer.gatt_service_removed_count_); 533 EXPECT_FALSE(observer.last_gatt_service_id_.empty()); 534 EXPECT_EQ(1U, device->GetGattServices().size()); 535 EXPECT_EQ( 536 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), 537 observer.last_gatt_service_uuid_); 538 539 // The object |service| points to should have been deallocated. |device| 540 // should contain a brand new instance. 541 service = device->GetGattService(observer.last_gatt_service_id_); 542 EXPECT_EQ(service, device->GetGattServices()[0]); 543 EXPECT_FALSE(service->IsLocal()); 544 EXPECT_TRUE(service->IsPrimary()); 545 546 EXPECT_EQ(observer.last_gatt_service_uuid_, service->GetUUID()); 547 548 // Remove the device. The observer should be notified of the removed service. 549 // |device| becomes invalid after this. 550 observer.last_gatt_service_uuid_ = BluetoothUUID(); 551 observer.last_gatt_service_id_.clear(); 552 fake_bluetooth_device_client_->RemoveDevice( 553 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 554 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 555 556 EXPECT_EQ(2, observer.gatt_service_added_count_); 557 EXPECT_EQ(2, observer.gatt_service_removed_count_); 558 EXPECT_FALSE(observer.last_gatt_service_id_.empty()); 559 EXPECT_EQ( 560 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), 561 observer.last_gatt_service_uuid_); 562 EXPECT_EQ( 563 NULL, adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress)); 564 } 565 566 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicAddedAndRemoved) { 567 fake_bluetooth_device_client_->CreateDevice( 568 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 569 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 570 BluetoothDevice* device = adapter_->GetDevice( 571 FakeBluetoothDeviceClient::kLowEnergyAddress); 572 ASSERT_TRUE(device); 573 574 TestObserver observer(adapter_); 575 576 // Expose the fake Heart Rate service. This will asynchronously expose 577 // characteristics. 578 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 579 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 580 ASSERT_EQ(1, observer.gatt_service_added_count_); 581 582 BluetoothGattService* service = 583 device->GetGattService(observer.last_gatt_service_id_); 584 585 EXPECT_EQ(0, observer.gatt_service_changed_count_); 586 EXPECT_EQ(0, observer.gatt_discovery_complete_count_); 587 EXPECT_EQ(0, observer.gatt_characteristic_added_count_); 588 EXPECT_EQ(0, observer.gatt_characteristic_removed_count_); 589 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 590 EXPECT_TRUE(service->GetCharacteristics().empty()); 591 592 // Run the message loop so that the characteristics appear. 593 base::MessageLoop::current()->Run(); 594 595 // 3 characteristics should appear. Only 1 of the characteristics sends 596 // value changed signals. Service changed should be fired once for 597 // descriptor added. 598 EXPECT_EQ(0, observer.gatt_service_changed_count_); 599 EXPECT_EQ(1, observer.gatt_discovery_complete_count_); 600 EXPECT_EQ(3, observer.gatt_characteristic_added_count_); 601 EXPECT_EQ(0, observer.gatt_characteristic_removed_count_); 602 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 603 EXPECT_EQ(3U, service->GetCharacteristics().size()); 604 605 // Hide the characteristics. 3 removed signals should be received. 606 fake_bluetooth_gatt_characteristic_client_->HideHeartRateCharacteristics(); 607 EXPECT_EQ(0, observer.gatt_service_changed_count_); 608 EXPECT_EQ(3, observer.gatt_characteristic_added_count_); 609 EXPECT_EQ(3, observer.gatt_characteristic_removed_count_); 610 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 611 EXPECT_TRUE(service->GetCharacteristics().empty()); 612 613 // Re-expose the heart rate characteristics. We shouldn't get another 614 // GattDiscoveryCompleteForService call, since the service thinks that 615 // discovery is done. On the bluetoothd side, characteristics will be removed 616 // only if the service will also be subsequently removed. 617 fake_bluetooth_gatt_characteristic_client_->ExposeHeartRateCharacteristics( 618 fake_bluetooth_gatt_service_client_->GetHeartRateServicePath()); 619 EXPECT_EQ(0, observer.gatt_service_changed_count_); 620 EXPECT_EQ(1, observer.gatt_discovery_complete_count_); 621 EXPECT_EQ(6, observer.gatt_characteristic_added_count_); 622 EXPECT_EQ(3, observer.gatt_characteristic_removed_count_); 623 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 624 EXPECT_EQ(3U, service->GetCharacteristics().size()); 625 626 // Hide the service. All characteristics should disappear. 627 fake_bluetooth_gatt_service_client_->HideHeartRateService(); 628 EXPECT_EQ(0, observer.gatt_service_changed_count_); 629 EXPECT_EQ(6, observer.gatt_characteristic_added_count_); 630 EXPECT_EQ(6, observer.gatt_characteristic_removed_count_); 631 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 632 } 633 634 TEST_F(BluetoothGattChromeOSTest, GattDescriptorAddedAndRemoved) { 635 fake_bluetooth_device_client_->CreateDevice( 636 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 637 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 638 BluetoothDevice* device = adapter_->GetDevice( 639 FakeBluetoothDeviceClient::kLowEnergyAddress); 640 ASSERT_TRUE(device); 641 642 TestObserver observer(adapter_); 643 644 // Expose the fake Heart Rate service. This will asynchronously expose 645 // characteristics. 646 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 647 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 648 ASSERT_EQ(1, observer.gatt_service_added_count_); 649 650 BluetoothGattService* service = 651 device->GetGattService(observer.last_gatt_service_id_); 652 653 EXPECT_EQ(0, observer.gatt_service_changed_count_); 654 EXPECT_EQ(0, observer.gatt_descriptor_added_count_); 655 EXPECT_EQ(0, observer.gatt_descriptor_removed_count_); 656 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count_); 657 658 EXPECT_TRUE(service->GetCharacteristics().empty()); 659 660 // Run the message loop so that the characteristics appear. 661 base::MessageLoop::current()->Run(); 662 EXPECT_EQ(0, observer.gatt_service_changed_count_); 663 664 // Only the Heart Rate Measurement characteristic has a descriptor. 665 EXPECT_EQ(1, observer.gatt_descriptor_added_count_); 666 EXPECT_EQ(0, observer.gatt_descriptor_removed_count_); 667 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count_); 668 669 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic( 670 fake_bluetooth_gatt_characteristic_client_-> 671 GetBodySensorLocationPath().value()); 672 ASSERT_TRUE(characteristic); 673 EXPECT_TRUE(characteristic->GetDescriptors().empty()); 674 675 characteristic = service->GetCharacteristic( 676 fake_bluetooth_gatt_characteristic_client_-> 677 GetHeartRateControlPointPath().value()); 678 ASSERT_TRUE(characteristic); 679 EXPECT_TRUE(characteristic->GetDescriptors().empty()); 680 681 characteristic = service->GetCharacteristic( 682 fake_bluetooth_gatt_characteristic_client_-> 683 GetHeartRateMeasurementPath().value()); 684 ASSERT_TRUE(characteristic); 685 EXPECT_EQ(1U, characteristic->GetDescriptors().size()); 686 687 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0]; 688 EXPECT_FALSE(descriptor->IsLocal()); 689 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(), 690 descriptor->GetUUID()); 691 EXPECT_EQ(descriptor->GetUUID(), observer.last_gatt_descriptor_uuid_); 692 EXPECT_EQ(descriptor->GetIdentifier(), observer.last_gatt_descriptor_id_); 693 694 // Hide the descriptor. 695 fake_bluetooth_gatt_descriptor_client_->HideDescriptor( 696 dbus::ObjectPath(descriptor->GetIdentifier())); 697 EXPECT_TRUE(characteristic->GetDescriptors().empty()); 698 EXPECT_EQ(0, observer.gatt_service_changed_count_); 699 EXPECT_EQ(1, observer.gatt_descriptor_added_count_); 700 EXPECT_EQ(1, observer.gatt_descriptor_removed_count_); 701 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count_); 702 703 // Expose the descriptor again. 704 observer.last_gatt_descriptor_id_.clear(); 705 observer.last_gatt_descriptor_uuid_ = BluetoothUUID(); 706 fake_bluetooth_gatt_descriptor_client_->ExposeDescriptor( 707 dbus::ObjectPath(characteristic->GetIdentifier()), 708 FakeBluetoothGattDescriptorClient:: 709 kClientCharacteristicConfigurationUUID); 710 EXPECT_EQ(0, observer.gatt_service_changed_count_); 711 EXPECT_EQ(1U, characteristic->GetDescriptors().size()); 712 EXPECT_EQ(2, observer.gatt_descriptor_added_count_); 713 EXPECT_EQ(1, observer.gatt_descriptor_removed_count_); 714 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count_); 715 716 descriptor = characteristic->GetDescriptors()[0]; 717 EXPECT_FALSE(descriptor->IsLocal()); 718 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(), 719 descriptor->GetUUID()); 720 EXPECT_EQ(descriptor->GetUUID(), observer.last_gatt_descriptor_uuid_); 721 EXPECT_EQ(descriptor->GetIdentifier(), observer.last_gatt_descriptor_id_); 722 } 723 724 TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) { 725 // This unit test tests that all remote GATT objects are created for D-Bus 726 // objects that were already exposed. 727 adapter_ = NULL; 728 ASSERT_FALSE(device::BluetoothAdapterFactory::HasSharedInstanceForTesting()); 729 730 // Create the fake D-Bus objects. 731 fake_bluetooth_device_client_->CreateDevice( 732 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 733 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 734 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 735 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 736 while (!fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible()) 737 base::RunLoop().RunUntilIdle(); 738 ASSERT_TRUE(fake_bluetooth_gatt_service_client_->IsHeartRateVisible()); 739 ASSERT_TRUE(fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible()); 740 741 // Create the adapter. This should create all the GATT objects. 742 GetAdapter(); 743 BluetoothDevice* device = adapter_->GetDevice( 744 FakeBluetoothDeviceClient::kLowEnergyAddress); 745 ASSERT_TRUE(device); 746 EXPECT_EQ(1U, device->GetGattServices().size()); 747 748 BluetoothGattService* service = device->GetGattServices()[0]; 749 ASSERT_TRUE(service); 750 EXPECT_FALSE(service->IsLocal()); 751 EXPECT_TRUE(service->IsPrimary()); 752 EXPECT_EQ( 753 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), 754 service->GetUUID()); 755 EXPECT_EQ(service, device->GetGattServices()[0]); 756 EXPECT_EQ(service, device->GetGattService(service->GetIdentifier())); 757 EXPECT_FALSE(service->IsLocal()); 758 EXPECT_EQ(3U, service->GetCharacteristics().size()); 759 760 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic( 761 fake_bluetooth_gatt_characteristic_client_-> 762 GetBodySensorLocationPath().value()); 763 ASSERT_TRUE(characteristic); 764 EXPECT_EQ( 765 BluetoothUUID(FakeBluetoothGattCharacteristicClient:: 766 kBodySensorLocationUUID), 767 characteristic->GetUUID()); 768 EXPECT_FALSE(characteristic->IsLocal()); 769 EXPECT_TRUE(characteristic->GetDescriptors().empty()); 770 771 characteristic = service->GetCharacteristic( 772 fake_bluetooth_gatt_characteristic_client_-> 773 GetHeartRateControlPointPath().value()); 774 ASSERT_TRUE(characteristic); 775 EXPECT_EQ( 776 BluetoothUUID(FakeBluetoothGattCharacteristicClient:: 777 kHeartRateControlPointUUID), 778 characteristic->GetUUID()); 779 EXPECT_FALSE(characteristic->IsLocal()); 780 EXPECT_TRUE(characteristic->GetDescriptors().empty()); 781 782 characteristic = service->GetCharacteristic( 783 fake_bluetooth_gatt_characteristic_client_-> 784 GetHeartRateMeasurementPath().value()); 785 ASSERT_TRUE(characteristic); 786 EXPECT_EQ( 787 BluetoothUUID(FakeBluetoothGattCharacteristicClient:: 788 kHeartRateMeasurementUUID), 789 characteristic->GetUUID()); 790 EXPECT_FALSE(characteristic->IsLocal()); 791 EXPECT_EQ(1U, characteristic->GetDescriptors().size()); 792 793 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0]; 794 ASSERT_TRUE(descriptor); 795 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(), 796 descriptor->GetUUID()); 797 EXPECT_FALSE(descriptor->IsLocal()); 798 } 799 800 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicValue) { 801 fake_bluetooth_device_client_->CreateDevice( 802 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 803 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 804 BluetoothDevice* device = adapter_->GetDevice( 805 FakeBluetoothDeviceClient::kLowEnergyAddress); 806 ASSERT_TRUE(device); 807 808 TestObserver observer(adapter_); 809 810 // Expose the fake Heart Rate service. This will asynchronously expose 811 // characteristics. 812 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 813 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 814 ASSERT_EQ(1, observer.gatt_service_added_count_); 815 816 BluetoothGattService* service = 817 device->GetGattService(observer.last_gatt_service_id_); 818 819 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 820 821 // Run the message loop so that the characteristics appear. 822 base::MessageLoop::current()->Run(); 823 824 // Issue write request to non-writeable characteristics. 825 observer.last_gatt_characteristic_id_.clear(); 826 observer.last_gatt_characteristic_uuid_ = BluetoothUUID(); 827 828 std::vector<uint8> write_value; 829 write_value.push_back(0x01); 830 BluetoothGattCharacteristic* characteristic = 831 service->GetCharacteristic(fake_bluetooth_gatt_characteristic_client_-> 832 GetHeartRateMeasurementPath().value()); 833 ASSERT_TRUE(characteristic); 834 EXPECT_FALSE(characteristic->IsNotifying()); 835 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_-> 836 GetHeartRateMeasurementPath().value(), 837 characteristic->GetIdentifier()); 838 EXPECT_EQ(kHeartRateMeasurementUUID, characteristic->GetUUID()); 839 characteristic->WriteRemoteCharacteristic( 840 write_value, 841 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback, 842 base::Unretained(this)), 843 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 844 base::Unretained(this))); 845 EXPECT_TRUE(observer.last_gatt_characteristic_id_.empty()); 846 EXPECT_FALSE(observer.last_gatt_characteristic_uuid_.IsValid()); 847 EXPECT_EQ(0, success_callback_count_); 848 EXPECT_EQ(1, error_callback_count_); 849 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 850 851 characteristic = service->GetCharacteristic( 852 fake_bluetooth_gatt_characteristic_client_-> 853 GetBodySensorLocationPath().value()); 854 ASSERT_TRUE(characteristic); 855 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_-> 856 GetBodySensorLocationPath().value(), 857 characteristic->GetIdentifier()); 858 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID()); 859 characteristic->WriteRemoteCharacteristic( 860 write_value, 861 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback, 862 base::Unretained(this)), 863 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 864 base::Unretained(this))); 865 EXPECT_TRUE(observer.last_gatt_characteristic_id_.empty()); 866 EXPECT_FALSE(observer.last_gatt_characteristic_uuid_.IsValid()); 867 EXPECT_EQ(0, success_callback_count_); 868 EXPECT_EQ(2, error_callback_count_); 869 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 870 871 // Issue write request to writeable characteristic. The "Body Sensor Location" 872 // characteristic does not send notifications and WriteValue does not result 873 // in a CharacteristicValueChanged event, thus no such event should be 874 // received. 875 characteristic = service->GetCharacteristic( 876 fake_bluetooth_gatt_characteristic_client_-> 877 GetHeartRateControlPointPath().value()); 878 ASSERT_TRUE(characteristic); 879 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_-> 880 GetHeartRateControlPointPath().value(), 881 characteristic->GetIdentifier()); 882 EXPECT_EQ(kHeartRateControlPointUUID, characteristic->GetUUID()); 883 characteristic->WriteRemoteCharacteristic( 884 write_value, 885 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback, 886 base::Unretained(this)), 887 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 888 base::Unretained(this))); 889 EXPECT_TRUE(observer.last_gatt_characteristic_id_.empty()); 890 EXPECT_FALSE(observer.last_gatt_characteristic_uuid_.IsValid()); 891 EXPECT_EQ(1, success_callback_count_); 892 EXPECT_EQ(2, error_callback_count_); 893 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 894 895 // Issue a read request. A successful read results in a 896 // CharacteristicValueChanged notification. 897 characteristic = service->GetCharacteristic( 898 fake_bluetooth_gatt_characteristic_client_-> 899 GetBodySensorLocationPath().value()); 900 ASSERT_TRUE(characteristic); 901 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_-> 902 GetBodySensorLocationPath().value(), 903 characteristic->GetIdentifier()); 904 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID()); 905 characteristic->ReadRemoteCharacteristic( 906 base::Bind(&BluetoothGattChromeOSTest::ValueCallback, 907 base::Unretained(this)), 908 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 909 base::Unretained(this))); 910 EXPECT_EQ(2, success_callback_count_); 911 EXPECT_EQ(2, error_callback_count_); 912 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 913 EXPECT_TRUE(ValuesEqual(characteristic->GetValue(), last_read_value_)); 914 } 915 916 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicProperties) { 917 fake_bluetooth_device_client_->CreateDevice( 918 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 919 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 920 BluetoothDevice* device = adapter_->GetDevice( 921 FakeBluetoothDeviceClient::kLowEnergyAddress); 922 ASSERT_TRUE(device); 923 924 TestObserver observer(adapter_); 925 926 // Expose the fake Heart Rate service. This will asynchronously expose 927 // characteristics. 928 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 929 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 930 931 BluetoothGattService* service = 932 device->GetGattService(observer.last_gatt_service_id_); 933 934 EXPECT_TRUE(service->GetCharacteristics().empty()); 935 936 // Run the message loop so that the characteristics appear. 937 base::MessageLoop::current()->Run(); 938 939 BluetoothGattCharacteristic *characteristic = service->GetCharacteristic( 940 fake_bluetooth_gatt_characteristic_client_-> 941 GetBodySensorLocationPath().value()); 942 EXPECT_EQ(BluetoothGattCharacteristic::kPropertyRead, 943 characteristic->GetProperties()); 944 945 characteristic = service->GetCharacteristic( 946 fake_bluetooth_gatt_characteristic_client_-> 947 GetHeartRateControlPointPath().value()); 948 EXPECT_EQ(BluetoothGattCharacteristic::kPropertyWrite, 949 characteristic->GetProperties()); 950 951 characteristic = service->GetCharacteristic( 952 fake_bluetooth_gatt_characteristic_client_-> 953 GetHeartRateMeasurementPath().value()); 954 EXPECT_EQ(BluetoothGattCharacteristic::kPropertyNotify, 955 characteristic->GetProperties()); 956 } 957 958 TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) { 959 fake_bluetooth_device_client_->CreateDevice( 960 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 961 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 962 BluetoothDevice* device = adapter_->GetDevice( 963 FakeBluetoothDeviceClient::kLowEnergyAddress); 964 ASSERT_TRUE(device); 965 966 TestObserver observer(adapter_); 967 968 // Expose the fake Heart Rate service. This will asynchronously expose 969 // characteristics. 970 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 971 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 972 ASSERT_EQ(1, observer.gatt_service_added_count_); 973 974 BluetoothGattService* service = 975 device->GetGattService(observer.last_gatt_service_id_); 976 977 EXPECT_EQ(0, observer.gatt_service_changed_count_); 978 EXPECT_EQ(0, observer.gatt_discovery_complete_count_); 979 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count_); 980 EXPECT_TRUE(service->GetCharacteristics().empty()); 981 982 // Run the message loop so that the characteristics appear. 983 base::MessageLoop::current()->Run(); 984 EXPECT_EQ(0, observer.gatt_service_changed_count_); 985 EXPECT_EQ(1, observer.gatt_discovery_complete_count_); 986 987 // Only the Heart Rate Measurement characteristic has a descriptor. 988 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic( 989 fake_bluetooth_gatt_characteristic_client_-> 990 GetHeartRateMeasurementPath().value()); 991 ASSERT_TRUE(characteristic); 992 EXPECT_EQ(1U, characteristic->GetDescriptors().size()); 993 994 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0]; 995 EXPECT_FALSE(descriptor->IsLocal()); 996 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(), 997 descriptor->GetUUID()); 998 999 std::vector<uint8> desc_value; 1000 desc_value.push_back(1); 1001 desc_value.push_back(0); 1002 1003 /* The cached value will be empty until the first read request */ 1004 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue())); 1005 EXPECT_TRUE(descriptor->GetValue().empty()); 1006 1007 EXPECT_EQ(0, success_callback_count_); 1008 EXPECT_EQ(0, error_callback_count_); 1009 EXPECT_TRUE(last_read_value_.empty()); 1010 1011 // Read value. GattDescriptorValueChanged event will be sent after a 1012 // successful read. 1013 descriptor->ReadRemoteDescriptor( 1014 base::Bind(&BluetoothGattChromeOSTest::ValueCallback, 1015 base::Unretained(this)), 1016 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1017 base::Unretained(this))); 1018 EXPECT_EQ(1, success_callback_count_); 1019 EXPECT_EQ(0, error_callback_count_); 1020 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue())); 1021 EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue())); 1022 EXPECT_EQ(0, observer.gatt_service_changed_count_); 1023 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count_); 1024 1025 // Write value. Writes to this descriptor will fail. 1026 desc_value[0] = 0x03; 1027 descriptor->WriteRemoteDescriptor( 1028 desc_value, 1029 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback, 1030 base::Unretained(this)), 1031 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1032 base::Unretained(this))); 1033 EXPECT_EQ(1, success_callback_count_); 1034 EXPECT_EQ(1, error_callback_count_); 1035 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue())); 1036 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue())); 1037 EXPECT_EQ(0, observer.gatt_service_changed_count_); 1038 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count_); 1039 1040 // Read new value. 1041 descriptor->ReadRemoteDescriptor( 1042 base::Bind(&BluetoothGattChromeOSTest::ValueCallback, 1043 base::Unretained(this)), 1044 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1045 base::Unretained(this))); 1046 EXPECT_EQ(2, success_callback_count_); 1047 EXPECT_EQ(1, error_callback_count_); 1048 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue())); 1049 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue())); 1050 EXPECT_EQ(0, observer.gatt_service_changed_count_); 1051 EXPECT_EQ(2, observer.gatt_descriptor_value_changed_count_); 1052 } 1053 1054 TEST_F(BluetoothGattChromeOSTest, NotifySessions) { 1055 fake_bluetooth_device_client_->CreateDevice( 1056 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 1057 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 1058 BluetoothDevice* device = 1059 adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); 1060 ASSERT_TRUE(device); 1061 1062 TestObserver observer(adapter_); 1063 1064 // Expose the fake Heart Rate service. This will asynchronously expose 1065 // characteristics. 1066 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 1067 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 1068 ASSERT_EQ(1, observer.gatt_service_added_count_); 1069 1070 BluetoothGattService* service = 1071 device->GetGattService(observer.last_gatt_service_id_); 1072 1073 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 1074 1075 // Run the message loop so that the characteristics appear. 1076 base::MessageLoop::current()->Run(); 1077 1078 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic( 1079 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath() 1080 .value()); 1081 ASSERT_TRUE(characteristic); 1082 EXPECT_FALSE(characteristic->IsNotifying()); 1083 EXPECT_TRUE(update_sessions_.empty()); 1084 1085 // Request to start notifications. 1086 characteristic->StartNotifySession( 1087 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1088 base::Unretained(this)), 1089 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1090 base::Unretained(this))); 1091 1092 // The operation still hasn't completed but we should have received the first 1093 // notification. 1094 EXPECT_EQ(0, success_callback_count_); 1095 EXPECT_EQ(0, error_callback_count_); 1096 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 1097 EXPECT_TRUE(update_sessions_.empty()); 1098 1099 // Send a two more requests, which should get queued. 1100 characteristic->StartNotifySession( 1101 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1102 base::Unretained(this)), 1103 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1104 base::Unretained(this))); 1105 characteristic->StartNotifySession( 1106 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1107 base::Unretained(this)), 1108 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1109 base::Unretained(this))); 1110 EXPECT_EQ(0, success_callback_count_); 1111 EXPECT_EQ(0, error_callback_count_); 1112 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 1113 EXPECT_TRUE(update_sessions_.empty()); 1114 EXPECT_TRUE(characteristic->IsNotifying()); 1115 1116 // Run the main loop. The initial call should complete. The queued call should 1117 // succeed immediately. 1118 base::MessageLoop::current()->Run(); 1119 1120 EXPECT_EQ(3, success_callback_count_); 1121 EXPECT_EQ(0, error_callback_count_); 1122 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 1123 EXPECT_EQ(3U, update_sessions_.size()); 1124 1125 // Notifications should be getting sent regularly now. 1126 base::MessageLoop::current()->Run(); 1127 EXPECT_GT(observer.gatt_characteristic_value_changed_count_, 1); 1128 1129 // Stop one of the sessions. The session should become inactive but the 1130 // characteristic should still be notifying. 1131 BluetoothGattNotifySession* session = update_sessions_[0]; 1132 EXPECT_TRUE(session->IsActive()); 1133 session->Stop(base::Bind(&BluetoothGattChromeOSTest::SuccessCallback, 1134 base::Unretained(this))); 1135 EXPECT_EQ(4, success_callback_count_); 1136 EXPECT_EQ(0, error_callback_count_); 1137 EXPECT_FALSE(session->IsActive()); 1138 EXPECT_EQ(characteristic->GetIdentifier(), 1139 session->GetCharacteristicIdentifier()); 1140 EXPECT_TRUE(characteristic->IsNotifying()); 1141 1142 // Delete another session. Characteristic should still be notifying. 1143 update_sessions_.pop_back(); 1144 EXPECT_EQ(2U, update_sessions_.size()); 1145 EXPECT_TRUE(characteristic->IsNotifying()); 1146 EXPECT_FALSE(update_sessions_[0]->IsActive()); 1147 EXPECT_TRUE(update_sessions_[1]->IsActive()); 1148 1149 // Clear the last session. 1150 update_sessions_.clear(); 1151 EXPECT_TRUE(update_sessions_.empty()); 1152 EXPECT_FALSE(characteristic->IsNotifying()); 1153 1154 success_callback_count_ = 0; 1155 observer.gatt_characteristic_value_changed_count_ = 0; 1156 1157 // Enable notifications again. 1158 characteristic->StartNotifySession( 1159 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1160 base::Unretained(this)), 1161 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1162 base::Unretained(this))); 1163 EXPECT_EQ(0, success_callback_count_); 1164 EXPECT_EQ(0, error_callback_count_); 1165 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 1166 EXPECT_TRUE(update_sessions_.empty()); 1167 EXPECT_TRUE(characteristic->IsNotifying()); 1168 1169 // Run the message loop. Notifications should begin. 1170 base::MessageLoop::current()->Run(); 1171 1172 EXPECT_EQ(1, success_callback_count_); 1173 EXPECT_EQ(0, error_callback_count_); 1174 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 1175 EXPECT_EQ(1U, update_sessions_.size()); 1176 EXPECT_TRUE(update_sessions_[0]->IsActive()); 1177 EXPECT_TRUE(characteristic->IsNotifying()); 1178 1179 // Check that notifications are happening. 1180 base::MessageLoop::current()->Run(); 1181 EXPECT_GT(observer.gatt_characteristic_value_changed_count_, 1); 1182 1183 // Request another session. This should return immediately. 1184 characteristic->StartNotifySession( 1185 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1186 base::Unretained(this)), 1187 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1188 base::Unretained(this))); 1189 EXPECT_EQ(2, success_callback_count_); 1190 EXPECT_EQ(0, error_callback_count_); 1191 EXPECT_EQ(2U, update_sessions_.size()); 1192 EXPECT_TRUE(update_sessions_[0]->IsActive()); 1193 EXPECT_TRUE(update_sessions_[1]->IsActive()); 1194 EXPECT_TRUE(characteristic->IsNotifying()); 1195 1196 // Hide the characteristic. The sessions should become inactive. 1197 fake_bluetooth_gatt_characteristic_client_->HideHeartRateCharacteristics(); 1198 EXPECT_EQ(2U, update_sessions_.size()); 1199 EXPECT_FALSE(update_sessions_[0]->IsActive()); 1200 EXPECT_FALSE(update_sessions_[1]->IsActive()); 1201 } 1202 1203 TEST_F(BluetoothGattChromeOSTest, NotifySessionsMadeInactive) { 1204 fake_bluetooth_device_client_->CreateDevice( 1205 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), 1206 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 1207 BluetoothDevice* device = 1208 adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); 1209 ASSERT_TRUE(device); 1210 1211 TestObserver observer(adapter_); 1212 1213 // Expose the fake Heart Rate service. This will asynchronously expose 1214 // characteristics. 1215 fake_bluetooth_gatt_service_client_->ExposeHeartRateService( 1216 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); 1217 ASSERT_EQ(1, observer.gatt_service_added_count_); 1218 1219 BluetoothGattService* service = 1220 device->GetGattService(observer.last_gatt_service_id_); 1221 1222 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_); 1223 1224 // Run the message loop so that the characteristics appear. 1225 base::MessageLoop::current()->Run(); 1226 1227 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic( 1228 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath() 1229 .value()); 1230 ASSERT_TRUE(characteristic); 1231 EXPECT_FALSE(characteristic->IsNotifying()); 1232 EXPECT_TRUE(update_sessions_.empty()); 1233 1234 // Send several requests to start notifications. 1235 characteristic->StartNotifySession( 1236 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1237 base::Unretained(this)), 1238 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1239 base::Unretained(this))); 1240 characteristic->StartNotifySession( 1241 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1242 base::Unretained(this)), 1243 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1244 base::Unretained(this))); 1245 characteristic->StartNotifySession( 1246 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1247 base::Unretained(this)), 1248 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1249 base::Unretained(this))); 1250 characteristic->StartNotifySession( 1251 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1252 base::Unretained(this)), 1253 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1254 base::Unretained(this))); 1255 1256 // The operation still hasn't completed but we should have received the first 1257 // notification. 1258 EXPECT_EQ(0, success_callback_count_); 1259 EXPECT_EQ(0, error_callback_count_); 1260 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 1261 EXPECT_TRUE(characteristic->IsNotifying()); 1262 EXPECT_TRUE(update_sessions_.empty()); 1263 1264 // Run the main loop. The initial call should complete. The queued calls 1265 // should succeed immediately. 1266 base::MessageLoop::current()->Run(); 1267 1268 EXPECT_EQ(4, success_callback_count_); 1269 EXPECT_EQ(0, error_callback_count_); 1270 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 1271 EXPECT_TRUE(characteristic->IsNotifying()); 1272 EXPECT_EQ(4U, update_sessions_.size()); 1273 1274 for (int i = 0; i < 4; i++) 1275 EXPECT_TRUE(update_sessions_[0]->IsActive()); 1276 1277 // Stop notifications directly through the client. The sessions should get 1278 // marked as inactive. 1279 fake_bluetooth_gatt_characteristic_client_->StopNotify( 1280 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath(), 1281 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback, 1282 base::Unretained(this)), 1283 base::Bind(&BluetoothGattChromeOSTest::DBusErrorCallback, 1284 base::Unretained(this))); 1285 EXPECT_EQ(5, success_callback_count_); 1286 EXPECT_EQ(0, error_callback_count_); 1287 EXPECT_FALSE(characteristic->IsNotifying()); 1288 EXPECT_EQ(4U, update_sessions_.size()); 1289 1290 for (int i = 0; i < 4; i++) 1291 EXPECT_FALSE(update_sessions_[0]->IsActive()); 1292 1293 // It should be possible to restart notifications and the call should reset 1294 // the session count and make a request through the client. 1295 update_sessions_.clear(); 1296 success_callback_count_ = 0; 1297 observer.gatt_characteristic_value_changed_count_ = 0; 1298 characteristic->StartNotifySession( 1299 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback, 1300 base::Unretained(this)), 1301 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, 1302 base::Unretained(this))); 1303 1304 EXPECT_EQ(0, success_callback_count_); 1305 EXPECT_EQ(0, error_callback_count_); 1306 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 1307 EXPECT_TRUE(characteristic->IsNotifying()); 1308 EXPECT_TRUE(update_sessions_.empty()); 1309 1310 base::MessageLoop::current()->Run(); 1311 1312 EXPECT_EQ(1, success_callback_count_); 1313 EXPECT_EQ(0, error_callback_count_); 1314 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_); 1315 EXPECT_TRUE(characteristic->IsNotifying()); 1316 EXPECT_EQ(1U, update_sessions_.size()); 1317 EXPECT_TRUE(update_sessions_[0]->IsActive()); 1318 } 1319 1320 } // namespace chromeos 1321