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_ptr.h" 6 #include "chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h" 7 #include "chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h" 8 #include "chrome/browser/extensions/extension_apitest.h" 9 #include "chrome/browser/extensions/extension_function_test_utils.h" 10 #include "chrome/browser/extensions/extension_test_message_listener.h" 11 #include "device/bluetooth/test/mock_bluetooth_adapter.h" 12 #include "device/bluetooth/test/mock_bluetooth_device.h" 13 #include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h" 14 #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h" 15 #include "device/bluetooth/test/mock_bluetooth_gatt_descriptor.h" 16 #include "device/bluetooth/test/mock_bluetooth_gatt_notify_session.h" 17 #include "device/bluetooth/test/mock_bluetooth_gatt_service.h" 18 #include "testing/gmock/include/gmock/gmock.h" 19 20 using device::BluetoothUUID; 21 using device::BluetoothAdapter; 22 using device::BluetoothDevice; 23 using device::BluetoothGattCharacteristic; 24 using device::BluetoothGattConnection; 25 using device::BluetoothGattDescriptor; 26 using device::BluetoothGattService; 27 using device::BluetoothGattNotifySession; 28 using device::MockBluetoothAdapter; 29 using device::MockBluetoothDevice; 30 using device::MockBluetoothGattCharacteristic; 31 using device::MockBluetoothGattConnection; 32 using device::MockBluetoothGattDescriptor; 33 using device::MockBluetoothGattService; 34 using device::MockBluetoothGattNotifySession; 35 using extensions::BluetoothLowEnergyEventRouter; 36 using testing::Invoke; 37 using testing::Return; 38 using testing::ReturnRef; 39 using testing::ReturnRefOfCopy; 40 using testing::SaveArg; 41 using testing::_; 42 43 namespace utils = extension_function_test_utils; 44 45 namespace { 46 47 // Test service constants. 48 const char kTestLeDeviceAddress0[] = "11:22:33:44:55:66"; 49 const char kTestLeDeviceName0[] = "Test LE Device 0"; 50 51 const char kTestLeDeviceAddress1[] = "77:88:99:AA:BB:CC"; 52 const char kTestLeDeviceName1[] = "Test LE Device 1"; 53 54 const char kTestServiceId0[] = "service_id0"; 55 const char kTestServiceUuid0[] = "1234"; 56 57 const char kTestServiceId1[] = "service_id1"; 58 const char kTestServiceUuid1[] = "5678"; 59 60 // Test characteristic constants. 61 const char kTestCharacteristicId0[] = "char_id0"; 62 const char kTestCharacteristicUuid0[] = "1211"; 63 const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties0 = 64 BluetoothGattCharacteristic::kPropertyBroadcast | 65 BluetoothGattCharacteristic::kPropertyRead | 66 BluetoothGattCharacteristic::kPropertyWriteWithoutResponse | 67 BluetoothGattCharacteristic::kPropertyIndicate; 68 const uint8 kTestCharacteristicDefaultValue0[] = {0x01, 0x02, 0x03, 0x04, 0x05}; 69 70 const char kTestCharacteristicId1[] = "char_id1"; 71 const char kTestCharacteristicUuid1[] = "1212"; 72 const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties1 = 73 BluetoothGattCharacteristic::kPropertyRead | 74 BluetoothGattCharacteristic::kPropertyWrite | 75 BluetoothGattCharacteristic::kPropertyNotify; 76 const uint8 kTestCharacteristicDefaultValue1[] = {0x06, 0x07, 0x08}; 77 78 const char kTestCharacteristicId2[] = "char_id2"; 79 const char kTestCharacteristicUuid2[] = "1213"; 80 const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties2 = 81 BluetoothGattCharacteristic::kPropertyNone; 82 83 // Test descriptor constants. 84 const char kTestDescriptorId0[] = "desc_id0"; 85 const char kTestDescriptorUuid0[] = "1221"; 86 const uint8 kTestDescriptorDefaultValue0[] = {0x01, 0x02, 0x03}; 87 88 const char kTestDescriptorId1[] = "desc_id1"; 89 const char kTestDescriptorUuid1[] = "1222"; 90 const uint8 kTestDescriptorDefaultValue1[] = {0x04, 0x05}; 91 92 class BluetoothLowEnergyApiTest : public ExtensionApiTest { 93 public: 94 BluetoothLowEnergyApiTest() {} 95 96 virtual ~BluetoothLowEnergyApiTest() {} 97 98 virtual void SetUpOnMainThread() OVERRIDE { 99 ExtensionApiTest::SetUpOnMainThread(); 100 empty_extension_ = utils::CreateEmptyExtension(); 101 SetUpMocks(); 102 } 103 104 virtual void CleanUpOnMainThread() OVERRIDE { 105 EXPECT_CALL(*mock_adapter_, RemoveObserver(_)); 106 } 107 108 void SetUpMocks() { 109 mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>(); 110 EXPECT_CALL(*mock_adapter_, GetDevices()) 111 .WillOnce(Return(BluetoothAdapter::ConstDeviceList())); 112 113 event_router()->SetAdapterForTesting(mock_adapter_); 114 115 device0_.reset( 116 new testing::NiceMock<MockBluetoothDevice>(mock_adapter_, 117 0, 118 kTestLeDeviceName0, 119 kTestLeDeviceAddress0, 120 false /* paired */, 121 true /* connected */)); 122 123 device1_.reset( 124 new testing::NiceMock<MockBluetoothDevice>(mock_adapter_, 125 0, 126 kTestLeDeviceName1, 127 kTestLeDeviceAddress1, 128 false /* paired */, 129 false /* connected */)); 130 131 service0_.reset(new testing::NiceMock<MockBluetoothGattService>( 132 device0_.get(), 133 kTestServiceId0, 134 BluetoothUUID(kTestServiceUuid0), 135 true /* is_primary */, 136 false /* is_local */)); 137 138 service1_.reset(new testing::NiceMock<MockBluetoothGattService>( 139 device0_.get(), 140 kTestServiceId1, 141 BluetoothUUID(kTestServiceUuid1), 142 false /* is_primary */, 143 false /* is_local */)); 144 145 // Assign characteristics some random properties and permissions. They don't 146 // need to reflect what the characteristic is actually capable of, since 147 // the JS API just passes values through from 148 // device::BluetoothGattCharacteristic. 149 std::vector<uint8> default_value; 150 chrc0_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>( 151 service0_.get(), 152 kTestCharacteristicId0, 153 BluetoothUUID(kTestCharacteristicUuid0), 154 false /* is_local */, 155 kTestCharacteristicProperties0, 156 BluetoothGattCharacteristic::kPermissionNone)); 157 default_value.assign(kTestCharacteristicDefaultValue0, 158 (kTestCharacteristicDefaultValue0 + 159 sizeof(kTestCharacteristicDefaultValue0))); 160 ON_CALL(*chrc0_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value)); 161 162 chrc1_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>( 163 service0_.get(), 164 kTestCharacteristicId1, 165 BluetoothUUID(kTestCharacteristicUuid1), 166 false /* is_local */, 167 kTestCharacteristicProperties1, 168 BluetoothGattCharacteristic::kPermissionNone)); 169 default_value.assign(kTestCharacteristicDefaultValue1, 170 (kTestCharacteristicDefaultValue1 + 171 sizeof(kTestCharacteristicDefaultValue1))); 172 ON_CALL(*chrc1_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value)); 173 174 chrc2_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>( 175 service1_.get(), 176 kTestCharacteristicId2, 177 BluetoothUUID(kTestCharacteristicUuid2), 178 false /* is_local */, 179 kTestCharacteristicProperties2, 180 BluetoothGattCharacteristic::kPermissionNone)); 181 182 desc0_.reset(new testing::NiceMock<MockBluetoothGattDescriptor>( 183 chrc0_.get(), 184 kTestDescriptorId0, 185 BluetoothUUID(kTestDescriptorUuid0), 186 false /* is_local */, 187 BluetoothGattCharacteristic::kPermissionNone)); 188 default_value.assign( 189 kTestDescriptorDefaultValue0, 190 (kTestDescriptorDefaultValue0 + sizeof(kTestDescriptorDefaultValue0))); 191 ON_CALL(*desc0_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value)); 192 193 desc1_.reset(new testing::NiceMock<MockBluetoothGattDescriptor>( 194 chrc0_.get(), 195 kTestDescriptorId1, 196 BluetoothUUID(kTestDescriptorUuid1), 197 false /* is_local */, 198 BluetoothGattCharacteristic::kPermissionNone)); 199 default_value.assign( 200 kTestDescriptorDefaultValue1, 201 (kTestDescriptorDefaultValue1 + sizeof(kTestDescriptorDefaultValue1))); 202 ON_CALL(*desc1_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value)); 203 } 204 205 protected: 206 BluetoothLowEnergyEventRouter* event_router() { 207 return extensions::BluetoothLowEnergyAPI::Get(browser()->profile()) 208 ->event_router(); 209 } 210 211 testing::StrictMock<MockBluetoothAdapter>* mock_adapter_; 212 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device0_; 213 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device1_; 214 scoped_ptr<testing::NiceMock<MockBluetoothGattService> > service0_; 215 scoped_ptr<testing::NiceMock<MockBluetoothGattService> > service1_; 216 scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc0_; 217 scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc1_; 218 scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc2_; 219 scoped_ptr<testing::NiceMock<MockBluetoothGattDescriptor> > desc0_; 220 scoped_ptr<testing::NiceMock<MockBluetoothGattDescriptor> > desc1_; 221 222 private: 223 scoped_refptr<extensions::Extension> empty_extension_; 224 }; 225 226 ACTION_TEMPLATE(InvokeCallbackArgument, 227 HAS_1_TEMPLATE_PARAMS(int, k), 228 AND_0_VALUE_PARAMS()) { 229 ::std::tr1::get<k>(args).Run(); 230 } 231 232 ACTION_TEMPLATE(InvokeCallbackArgument, 233 HAS_1_TEMPLATE_PARAMS(int, k), 234 AND_1_VALUE_PARAMS(p0)) { 235 ::std::tr1::get<k>(args).Run(p0); 236 } 237 238 ACTION_TEMPLATE(InvokeCallbackWithScopedPtrArg, 239 HAS_2_TEMPLATE_PARAMS(int, k, typename, T), 240 AND_1_VALUE_PARAMS(p0)) { 241 ::std::tr1::get<k>(args).Run(scoped_ptr<T>(p0)); 242 } 243 244 BluetoothGattConnection* CreateGattConnection( 245 const std::string& device_address, 246 bool expect_disconnect) { 247 testing::NiceMock<MockBluetoothGattConnection>* conn = 248 new testing::NiceMock<MockBluetoothGattConnection>(device_address); 249 250 if (expect_disconnect) { 251 EXPECT_CALL(*conn, Disconnect(_)) 252 .Times(1) 253 .WillOnce(InvokeCallbackArgument<0>()); 254 } else { 255 EXPECT_CALL(*conn, Disconnect(_)).Times(0); 256 } 257 258 return conn; 259 } 260 261 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetServices) { 262 ResultCatcher catcher; 263 catcher.RestrictToProfile(browser()->profile()); 264 265 std::vector<BluetoothGattService*> services; 266 services.push_back(service0_.get()); 267 services.push_back(service1_.get()); 268 269 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 270 .Times(3) 271 .WillOnce(Return(static_cast<BluetoothDevice*>(NULL))) 272 .WillRepeatedly(Return(device0_.get())); 273 274 EXPECT_CALL(*device0_, GetGattServices()) 275 .Times(2) 276 .WillOnce(Return(std::vector<BluetoothGattService*>())) 277 .WillOnce(Return(services)); 278 279 // Load and wait for setup. 280 ExtensionTestMessageListener listener("ready", true); 281 ASSERT_TRUE(LoadExtension( 282 test_data_dir_.AppendASCII("bluetooth_low_energy/get_services"))); 283 EXPECT_TRUE(listener.WaitUntilSatisfied()); 284 285 listener.Reply("go"); 286 287 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 288 } 289 290 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetService) { 291 ResultCatcher catcher; 292 catcher.RestrictToProfile(browser()->profile()); 293 294 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 295 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 296 297 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 298 .Times(3) 299 .WillOnce(Return(static_cast<BluetoothDevice*>(NULL))) 300 .WillRepeatedly(Return(device0_.get())); 301 302 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 303 .Times(2) 304 .WillOnce(Return(static_cast<BluetoothGattService*>(NULL))) 305 .WillOnce(Return(service0_.get())); 306 307 // Load and wait for setup. 308 ExtensionTestMessageListener listener("ready", true); 309 ASSERT_TRUE(LoadExtension( 310 test_data_dir_.AppendASCII("bluetooth_low_energy/get_service"))); 311 EXPECT_TRUE(listener.WaitUntilSatisfied()); 312 313 listener.Reply("go"); 314 315 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 316 317 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 318 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 319 } 320 321 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ServiceEvents) { 322 ResultCatcher catcher; 323 catcher.RestrictToProfile(browser()->profile()); 324 325 // Load the extension and let it set up. 326 ExtensionTestMessageListener listener("ready", true); 327 ASSERT_TRUE(LoadExtension( 328 test_data_dir_.AppendASCII("bluetooth_low_energy/service_events"))); 329 330 // Cause events to be sent to the extension. 331 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 332 333 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 334 event_router()->GattServiceAdded(device0_.get(), service1_.get()); 335 event_router()->GattServiceChanged(service1_.get()); 336 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 337 338 EXPECT_TRUE(listener.WaitUntilSatisfied()); 339 listener.Reply("go"); 340 341 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 342 event_router()->GattServiceRemoved(device0_.get(), service1_.get()); 343 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 344 } 345 346 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedService) { 347 ResultCatcher catcher; 348 catcher.RestrictToProfile(browser()->profile()); 349 350 // Load the extension and let it set up. 351 ASSERT_TRUE(LoadExtension( 352 test_data_dir_.AppendASCII("bluetooth_low_energy/get_removed_service"))); 353 354 // 1. getService success. 355 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 356 .Times(1) 357 .WillOnce(Return(device0_.get())); 358 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 359 .Times(1) 360 .WillOnce(Return(service0_.get())); 361 362 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 363 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 364 365 ExtensionTestMessageListener get_service_success_listener("getServiceSuccess", 366 true); 367 EXPECT_TRUE(get_service_success_listener.WaitUntilSatisfied()); 368 testing::Mock::VerifyAndClearExpectations(mock_adapter_); 369 testing::Mock::VerifyAndClearExpectations(device0_.get()); 370 371 // 2. getService fail. 372 EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0); 373 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)).Times(0); 374 375 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 376 377 ExtensionTestMessageListener get_service_fail_listener("getServiceFail", 378 true); 379 EXPECT_TRUE(get_service_fail_listener.WaitUntilSatisfied()); 380 testing::Mock::VerifyAndClearExpectations(mock_adapter_); 381 testing::Mock::VerifyAndClearExpectations(device0_.get()); 382 383 get_service_fail_listener.Reply("go"); 384 385 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 386 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 387 } 388 389 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetIncludedServices) { 390 ResultCatcher catcher; 391 catcher.RestrictToProfile(browser()->profile()); 392 393 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 394 "bluetooth_low_energy/get_included_services"))); 395 396 // Wait for initial call to end with failure as there is no mapping. 397 ExtensionTestMessageListener listener("ready", true); 398 EXPECT_TRUE(listener.WaitUntilSatisfied()); 399 400 // Set up for the rest of the calls before replying. Included services can be 401 // returned even if there is no instance ID mapping for them yet, so no need 402 // to call GattServiceAdded for |service1_| here. 403 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 404 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 405 406 std::vector<BluetoothGattService*> includes; 407 includes.push_back(service1_.get()); 408 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0)) 409 .Times(2) 410 .WillRepeatedly(Return(device0_.get())); 411 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 412 .Times(2) 413 .WillRepeatedly(Return(service0_.get())); 414 EXPECT_CALL(*service0_, GetIncludedServices()) 415 .Times(2) 416 .WillOnce(Return(std::vector<BluetoothGattService*>())) 417 .WillOnce(Return(includes)); 418 419 listener.Reply("go"); 420 listener.Reset(); 421 422 EXPECT_TRUE(listener.WaitUntilSatisfied()); 423 424 listener.Reply("go"); 425 426 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 427 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 428 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 429 } 430 431 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristics) { 432 ResultCatcher catcher; 433 catcher.RestrictToProfile(browser()->profile()); 434 435 std::vector<BluetoothGattCharacteristic*> characteristics; 436 characteristics.push_back(chrc0_.get()); 437 characteristics.push_back(chrc1_.get()); 438 439 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 440 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 441 442 EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(3).WillRepeatedly( 443 Return(device0_.get())); 444 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 445 .Times(3) 446 .WillOnce(Return(static_cast<BluetoothGattService*>(NULL))) 447 .WillRepeatedly(Return(service0_.get())); 448 EXPECT_CALL(*service0_, GetCharacteristics()) 449 .Times(2) 450 .WillOnce(Return(std::vector<BluetoothGattCharacteristic*>())) 451 .WillOnce(Return(characteristics)); 452 453 ExtensionTestMessageListener listener("ready", true); 454 ASSERT_TRUE(LoadExtension( 455 test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristics"))); 456 EXPECT_TRUE(listener.WaitUntilSatisfied()); 457 458 listener.Reply("go"); 459 460 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 461 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 462 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 463 } 464 465 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristic) { 466 ResultCatcher catcher; 467 catcher.RestrictToProfile(browser()->profile()); 468 469 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 470 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 471 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 472 473 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 474 .Times(4) 475 .WillOnce(Return(static_cast<BluetoothDevice*>(NULL))) 476 .WillRepeatedly(Return(device0_.get())); 477 478 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 479 .Times(3) 480 .WillOnce(Return(static_cast<BluetoothGattService*>(NULL))) 481 .WillRepeatedly(Return(service0_.get())); 482 483 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 484 .Times(2) 485 .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL))) 486 .WillOnce(Return(chrc0_.get())); 487 488 // Load the extension and wait for first test. 489 ExtensionTestMessageListener listener("ready", true); 490 ASSERT_TRUE(LoadExtension( 491 test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristic"))); 492 EXPECT_TRUE(listener.WaitUntilSatisfied()); 493 494 listener.Reply("go"); 495 496 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 497 498 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 499 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 500 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 501 } 502 503 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicProperties) { 504 ResultCatcher catcher; 505 catcher.RestrictToProfile(browser()->profile()); 506 507 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 508 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 509 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 510 511 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 512 .Times(12) 513 .WillRepeatedly(Return(device0_.get())); 514 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 515 .Times(12) 516 .WillRepeatedly(Return(service0_.get())); 517 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 518 .Times(12) 519 .WillRepeatedly(Return(chrc0_.get())); 520 EXPECT_CALL(*chrc0_, GetProperties()) 521 .Times(12) 522 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyNone)) 523 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyBroadcast)) 524 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyRead)) 525 .WillOnce( 526 Return(BluetoothGattCharacteristic::kPropertyWriteWithoutResponse)) 527 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyWrite)) 528 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyNotify)) 529 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyIndicate)) 530 .WillOnce(Return( 531 BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites)) 532 .WillOnce( 533 Return(BluetoothGattCharacteristic::kPropertyExtendedProperties)) 534 .WillOnce(Return(BluetoothGattCharacteristic::kPropertyReliableWrite)) 535 .WillOnce( 536 Return(BluetoothGattCharacteristic::kPropertyWritableAuxiliaries)) 537 .WillOnce(Return( 538 BluetoothGattCharacteristic::kPropertyBroadcast | 539 BluetoothGattCharacteristic::kPropertyRead | 540 BluetoothGattCharacteristic::kPropertyWriteWithoutResponse | 541 BluetoothGattCharacteristic::kPropertyWrite | 542 BluetoothGattCharacteristic::kPropertyNotify | 543 BluetoothGattCharacteristic::kPropertyIndicate | 544 BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites | 545 BluetoothGattCharacteristic::kPropertyExtendedProperties | 546 BluetoothGattCharacteristic::kPropertyReliableWrite | 547 BluetoothGattCharacteristic::kPropertyWritableAuxiliaries)); 548 549 ExtensionTestMessageListener listener("ready", true); 550 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 551 "bluetooth_low_energy/characteristic_properties"))); 552 EXPECT_TRUE(listener.WaitUntilSatisfied()); 553 554 listener.Reply("go"); 555 556 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 557 558 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 559 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 560 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 561 } 562 563 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedCharacteristic) { 564 ResultCatcher catcher; 565 catcher.RestrictToProfile(browser()->profile()); 566 567 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 568 .Times(1) 569 .WillOnce(Return(device0_.get())); 570 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 571 .Times(1) 572 .WillOnce(Return(service0_.get())); 573 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 574 .Times(1) 575 .WillOnce(Return(chrc0_.get())); 576 577 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 578 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 579 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 580 581 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 582 "bluetooth_low_energy/get_removed_characteristic"))); 583 584 ExtensionTestMessageListener listener("ready", true); 585 EXPECT_TRUE(listener.WaitUntilSatisfied()); 586 testing::Mock::VerifyAndClearExpectations(mock_adapter_); 587 testing::Mock::VerifyAndClearExpectations(device0_.get()); 588 testing::Mock::VerifyAndClearExpectations(service0_.get()); 589 590 EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0); 591 EXPECT_CALL(*device0_, GetGattService(_)).Times(0); 592 EXPECT_CALL(*service0_, GetCharacteristic(_)).Times(0); 593 594 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 595 596 listener.Reply("go"); 597 listener.Reset(); 598 EXPECT_TRUE(listener.WaitUntilSatisfied()); 599 600 listener.Reply("go"); 601 602 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 603 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 604 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 605 } 606 607 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicValueChanged) { 608 ResultCatcher catcher; 609 catcher.RestrictToProfile(browser()->profile()); 610 611 // Cause events to be sent to the extension. 612 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 613 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 614 event_router()->GattServiceAdded(device0_.get(), service1_.get()); 615 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 616 event_router()->GattCharacteristicAdded(service1_.get(), chrc2_.get()); 617 618 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 619 .Times(2) 620 .WillRepeatedly(Return(device0_.get())); 621 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 622 .Times(1) 623 .WillOnce(Return(service0_.get())); 624 EXPECT_CALL(*device0_, GetGattService(kTestServiceId1)) 625 .Times(1) 626 .WillOnce(Return(service1_.get())); 627 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 628 .Times(1) 629 .WillOnce(Return(chrc0_.get())); 630 EXPECT_CALL(*service1_, GetCharacteristic(kTestCharacteristicId2)) 631 .Times(1) 632 .WillOnce(Return(chrc2_.get())); 633 634 BluetoothGattNotifySession* session0 = 635 new testing::NiceMock<MockBluetoothGattNotifySession>( 636 kTestCharacteristicId0); 637 BluetoothGattNotifySession* session1 = 638 new testing::NiceMock<MockBluetoothGattNotifySession>( 639 kTestCharacteristicId2); 640 641 EXPECT_CALL(*chrc0_, StartNotifySession(_, _)) 642 .Times(1) 643 .WillOnce( 644 InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( 645 session0)); 646 EXPECT_CALL(*chrc2_, StartNotifySession(_, _)) 647 .Times(1) 648 .WillOnce( 649 InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( 650 session1)); 651 652 ExtensionTestMessageListener listener("ready", true); 653 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 654 "bluetooth_low_energy/characteristic_value_changed"))); 655 656 EXPECT_TRUE(listener.WaitUntilSatisfied()); 657 658 std::vector<uint8> value; 659 event_router()->GattCharacteristicValueChanged( 660 service0_.get(), chrc0_.get(), value); 661 event_router()->GattCharacteristicValueChanged( 662 service1_.get(), chrc2_.get(), value); 663 664 listener.Reply("go"); 665 666 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 667 event_router()->GattCharacteristicRemoved(service1_.get(), chrc2_.get()); 668 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 669 event_router()->GattServiceRemoved(device0_.get(), service1_.get()); 670 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 671 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 672 } 673 674 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadCharacteristicValue) { 675 ResultCatcher catcher; 676 catcher.RestrictToProfile(browser()->profile()); 677 678 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 679 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 680 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 681 682 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 683 .Times(3) 684 .WillRepeatedly(Return(device0_.get())); 685 686 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 687 .Times(3) 688 .WillRepeatedly(Return(service0_.get())); 689 690 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 691 .Times(3) 692 .WillRepeatedly(Return(chrc0_.get())); 693 694 std::vector<uint8> value; 695 EXPECT_CALL(*chrc0_, ReadRemoteCharacteristic(_, _)) 696 .Times(2) 697 .WillOnce(InvokeCallbackArgument<1>()) 698 .WillOnce(InvokeCallbackArgument<0>(value)); 699 700 ExtensionTestMessageListener listener("ready", true); 701 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 702 "bluetooth_low_energy/read_characteristic_value"))); 703 EXPECT_TRUE(listener.WaitUntilSatisfied()); 704 705 listener.Reply("go"); 706 707 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 708 709 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 710 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 711 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 712 } 713 714 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteCharacteristicValue) { 715 ResultCatcher catcher; 716 catcher.RestrictToProfile(browser()->profile()); 717 718 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 719 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 720 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 721 722 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 723 .Times(3) 724 .WillRepeatedly(Return(device0_.get())); 725 726 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 727 .Times(3) 728 .WillRepeatedly(Return(service0_.get())); 729 730 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 731 .Times(3) 732 .WillRepeatedly(Return(chrc0_.get())); 733 734 std::vector<uint8> write_value; 735 EXPECT_CALL(*chrc0_, WriteRemoteCharacteristic(_, _, _)) 736 .Times(2) 737 .WillOnce(InvokeCallbackArgument<2>()) 738 .WillOnce(DoAll(SaveArg<0>(&write_value), InvokeCallbackArgument<1>())); 739 740 EXPECT_CALL(*chrc0_, GetValue()).Times(1).WillOnce(ReturnRef(write_value)); 741 742 ExtensionTestMessageListener listener("ready", true); 743 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 744 "bluetooth_low_energy/write_characteristic_value"))); 745 EXPECT_TRUE(listener.WaitUntilSatisfied()); 746 747 listener.Reply("go"); 748 749 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 750 751 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 752 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 753 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 754 } 755 756 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetDescriptors) { 757 ResultCatcher catcher; 758 catcher.RestrictToProfile(browser()->profile()); 759 760 std::vector<BluetoothGattDescriptor*> descriptors; 761 descriptors.push_back(desc0_.get()); 762 descriptors.push_back(desc1_.get()); 763 764 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 765 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 766 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 767 768 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 769 .Times(3) 770 .WillRepeatedly(Return(device0_.get())); 771 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 772 .Times(3) 773 .WillRepeatedly(Return(service0_.get())); 774 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 775 .Times(3) 776 .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL))) 777 .WillRepeatedly(Return(chrc0_.get())); 778 EXPECT_CALL(*chrc0_, GetDescriptors()) 779 .Times(2) 780 .WillOnce(Return(std::vector<BluetoothGattDescriptor*>())) 781 .WillOnce(Return(descriptors)); 782 783 ExtensionTestMessageListener listener("ready", true); 784 ASSERT_TRUE(LoadExtension( 785 test_data_dir_.AppendASCII("bluetooth_low_energy/get_descriptors"))); 786 EXPECT_TRUE(listener.WaitUntilSatisfied()); 787 788 listener.Reply("go"); 789 790 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 791 792 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 793 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 794 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 795 } 796 797 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetDescriptor) { 798 ResultCatcher catcher; 799 catcher.RestrictToProfile(browser()->profile()); 800 801 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 802 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 803 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 804 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get()); 805 806 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 807 .Times(5) 808 .WillOnce(Return(static_cast<BluetoothDevice*>(NULL))) 809 .WillRepeatedly(Return(device0_.get())); 810 811 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 812 .Times(4) 813 .WillOnce(Return(static_cast<BluetoothGattService*>(NULL))) 814 .WillRepeatedly(Return(service0_.get())); 815 816 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 817 .Times(3) 818 .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL))) 819 .WillRepeatedly(Return(chrc0_.get())); 820 821 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0)) 822 .Times(2) 823 .WillOnce(Return(static_cast<BluetoothGattDescriptor*>(NULL))) 824 .WillOnce(Return(desc0_.get())); 825 826 // Load the extension and wait for first test. 827 ExtensionTestMessageListener listener("ready", true); 828 ASSERT_TRUE(LoadExtension( 829 test_data_dir_.AppendASCII("bluetooth_low_energy/get_descriptor"))); 830 EXPECT_TRUE(listener.WaitUntilSatisfied()); 831 832 listener.Reply("go"); 833 834 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 835 836 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get()); 837 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 838 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 839 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 840 } 841 842 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedDescriptor) { 843 ResultCatcher catcher; 844 catcher.RestrictToProfile(browser()->profile()); 845 846 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 847 .Times(1) 848 .WillOnce(Return(device0_.get())); 849 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 850 .Times(1) 851 .WillOnce(Return(service0_.get())); 852 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 853 .Times(1) 854 .WillOnce(Return(chrc0_.get())); 855 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0)) 856 .Times(1) 857 .WillOnce(Return(desc0_.get())); 858 859 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 860 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 861 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 862 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get()); 863 864 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 865 "bluetooth_low_energy/get_removed_descriptor"))); 866 867 ExtensionTestMessageListener listener("ready", true); 868 EXPECT_TRUE(listener.WaitUntilSatisfied()); 869 testing::Mock::VerifyAndClearExpectations(mock_adapter_); 870 testing::Mock::VerifyAndClearExpectations(device0_.get()); 871 testing::Mock::VerifyAndClearExpectations(service0_.get()); 872 testing::Mock::VerifyAndClearExpectations(chrc0_.get()); 873 874 EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(0); 875 EXPECT_CALL(*device0_, GetGattService(_)).Times(0); 876 EXPECT_CALL(*service0_, GetCharacteristic(_)).Times(0); 877 EXPECT_CALL(*chrc0_, GetDescriptor(_)).Times(0); 878 879 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get()); 880 881 listener.Reply("go"); 882 listener.Reset(); 883 EXPECT_TRUE(listener.WaitUntilSatisfied()); 884 885 listener.Reply("go"); 886 887 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 888 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 889 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 890 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 891 } 892 893 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, DescriptorValueChanged) { 894 ResultCatcher catcher; 895 catcher.RestrictToProfile(browser()->profile()); 896 897 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 898 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 899 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 900 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get()); 901 event_router()->GattDescriptorAdded(chrc0_.get(), desc1_.get()); 902 903 // Load the extension and let it set up. 904 ExtensionTestMessageListener listener("ready", true); 905 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 906 "bluetooth_low_energy/descriptor_value_changed"))); 907 908 // Cause events to be sent to the extension. 909 std::vector<uint8> value; 910 event_router()->GattDescriptorValueChanged(chrc0_.get(), desc0_.get(), value); 911 event_router()->GattDescriptorValueChanged(chrc0_.get(), desc1_.get(), value); 912 913 EXPECT_TRUE(listener.WaitUntilSatisfied()); 914 listener.Reply("go"); 915 916 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 917 event_router()->GattDescriptorRemoved(chrc0_.get(), desc1_.get()); 918 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get()); 919 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 920 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 921 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 922 } 923 924 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadDescriptorValue) { 925 ResultCatcher catcher; 926 catcher.RestrictToProfile(browser()->profile()); 927 928 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 929 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 930 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 931 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get()); 932 933 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 934 .Times(3) 935 .WillRepeatedly(Return(device0_.get())); 936 937 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 938 .Times(3) 939 .WillRepeatedly(Return(service0_.get())); 940 941 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 942 .Times(3) 943 .WillRepeatedly(Return(chrc0_.get())); 944 945 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0)) 946 .Times(3) 947 .WillRepeatedly(Return(desc0_.get())); 948 949 std::vector<uint8> value; 950 EXPECT_CALL(*desc0_, ReadRemoteDescriptor(_, _)) 951 .Times(2) 952 .WillOnce(InvokeCallbackArgument<1>()) 953 .WillOnce(InvokeCallbackArgument<0>(value)); 954 955 ExtensionTestMessageListener listener("ready", true); 956 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 957 "bluetooth_low_energy/read_descriptor_value"))); 958 EXPECT_TRUE(listener.WaitUntilSatisfied()); 959 960 listener.Reply("go"); 961 962 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 963 964 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get()); 965 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 966 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 967 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 968 } 969 970 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteDescriptorValue) { 971 ResultCatcher catcher; 972 catcher.RestrictToProfile(browser()->profile()); 973 974 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 975 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 976 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 977 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get()); 978 979 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 980 .Times(3) 981 .WillRepeatedly(Return(device0_.get())); 982 983 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 984 .Times(3) 985 .WillRepeatedly(Return(service0_.get())); 986 987 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 988 .Times(3) 989 .WillRepeatedly(Return(chrc0_.get())); 990 991 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0)) 992 .Times(3) 993 .WillRepeatedly(Return(desc0_.get())); 994 995 std::vector<uint8> write_value; 996 EXPECT_CALL(*desc0_, WriteRemoteDescriptor(_, _, _)) 997 .Times(2) 998 .WillOnce(InvokeCallbackArgument<2>()) 999 .WillOnce(DoAll(SaveArg<0>(&write_value), InvokeCallbackArgument<1>())); 1000 1001 EXPECT_CALL(*desc0_, GetValue()).Times(1).WillOnce(ReturnRef(write_value)); 1002 1003 ExtensionTestMessageListener listener("ready", true); 1004 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 1005 "bluetooth_low_energy/write_descriptor_value"))); 1006 EXPECT_TRUE(listener.WaitUntilSatisfied()); 1007 1008 listener.Reply("go"); 1009 1010 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 1011 1012 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get()); 1013 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 1014 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 1015 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 1016 } 1017 1018 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, PermissionDenied) { 1019 ResultCatcher catcher; 1020 catcher.RestrictToProfile(browser()->profile()); 1021 1022 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 1023 "bluetooth_low_energy/permission_denied"))); 1024 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 1025 } 1026 1027 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, UuidPermissionMethods) { 1028 ResultCatcher catcher; 1029 catcher.RestrictToProfile(browser()->profile()); 1030 1031 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 1032 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 1033 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 1034 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get()); 1035 1036 std::vector<BluetoothGattService*> services; 1037 services.push_back(service0_.get()); 1038 1039 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 1040 .WillRepeatedly(Return(device0_.get())); 1041 EXPECT_CALL(*device0_, GetGattServices()).WillOnce(Return(services)); 1042 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 1043 .WillRepeatedly(Return(service0_.get())); 1044 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 1045 .WillRepeatedly(Return(chrc0_.get())); 1046 EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0)) 1047 .WillRepeatedly(Return(desc0_.get())); 1048 1049 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 1050 "bluetooth_low_energy/uuid_permission_methods"))); 1051 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 1052 1053 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get()); 1054 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 1055 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 1056 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 1057 } 1058 1059 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, UuidPermissionEvents) { 1060 ResultCatcher catcher; 1061 catcher.RestrictToProfile(browser()->profile()); 1062 1063 ExtensionTestMessageListener listener("ready", true); 1064 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 1065 "bluetooth_low_energy/uuid_permission_events"))); 1066 1067 // Cause events to be sent to the extension. 1068 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 1069 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 1070 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 1071 event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get()); 1072 1073 std::vector<uint8> value; 1074 event_router()->GattCharacteristicValueChanged( 1075 service0_.get(), chrc0_.get(), value); 1076 event_router()->GattDescriptorValueChanged(chrc0_.get(), desc0_.get(), value); 1077 event_router()->GattServiceChanged(service0_.get()); 1078 1079 EXPECT_TRUE(listener.WaitUntilSatisfied()); 1080 listener.Reply("go"); 1081 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 1082 1083 event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get()); 1084 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 1085 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 1086 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 1087 } 1088 1089 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GattConnection) { 1090 ResultCatcher catcher; 1091 catcher.RestrictToProfile(browser()->profile()); 1092 1093 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 1094 event_router()->DeviceAdded(mock_adapter_, device1_.get()); 1095 1096 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 1097 .WillRepeatedly(Return(static_cast<BluetoothDevice*>(NULL))); 1098 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0)) 1099 .WillRepeatedly(Return(device0_.get())); 1100 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress1)) 1101 .WillRepeatedly(Return(device1_.get())); 1102 EXPECT_CALL(*device0_, CreateGattConnection(_, _)) 1103 .Times(3) 1104 .WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_FAILED)) 1105 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>( 1106 CreateGattConnection(kTestLeDeviceAddress0, 1107 true /* expect_disconnect */))) 1108 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>( 1109 CreateGattConnection(kTestLeDeviceAddress0, 1110 false /* expect_disconnect */))); 1111 EXPECT_CALL(*device1_, CreateGattConnection(_, _)) 1112 .Times(1) 1113 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>( 1114 CreateGattConnection(kTestLeDeviceAddress1, 1115 true /* expect_disconnect */))); 1116 1117 ASSERT_TRUE(LoadExtension( 1118 test_data_dir_.AppendASCII("bluetooth_low_energy/gatt_connection"))); 1119 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 1120 1121 event_router()->DeviceRemoved(mock_adapter_, device1_.get()); 1122 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 1123 } 1124 1125 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReconnectAfterDisconnected) { 1126 ResultCatcher catcher; 1127 catcher.RestrictToProfile(browser()->profile()); 1128 1129 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 1130 1131 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0)) 1132 .WillRepeatedly(Return(device0_.get())); 1133 1134 MockBluetoothGattConnection* first_conn = 1135 static_cast<MockBluetoothGattConnection*>(CreateGattConnection( 1136 kTestLeDeviceAddress0, false /* expect_disconnect */)); 1137 EXPECT_CALL(*first_conn, IsConnected()) 1138 .Times(2) 1139 .WillOnce(Return(true)) 1140 .WillOnce(Return(false)); 1141 1142 EXPECT_CALL(*device0_, CreateGattConnection(_, _)) 1143 .Times(2) 1144 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>( 1145 first_conn)) 1146 .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>( 1147 CreateGattConnection(kTestLeDeviceAddress0, 1148 false /* expect_disconnect */))); 1149 1150 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 1151 "bluetooth_low_energy/reconnect_after_disconnected"))); 1152 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 1153 1154 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 1155 } 1156 1157 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ConnectInProgress) { 1158 ResultCatcher catcher; 1159 catcher.RestrictToProfile(browser()->profile()); 1160 1161 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 1162 1163 EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress0)) 1164 .WillRepeatedly(Return(device0_.get())); 1165 1166 BluetoothDevice::GattConnectionCallback connect_callback; 1167 base::Closure disconnect_callback; 1168 1169 testing::NiceMock<MockBluetoothGattConnection>* conn = 1170 new testing::NiceMock<MockBluetoothGattConnection>( 1171 kTestLeDeviceAddress0); 1172 scoped_ptr<BluetoothGattConnection> conn_ptr(conn); 1173 EXPECT_CALL(*conn, Disconnect(_)) 1174 .Times(1) 1175 .WillOnce(SaveArg<0>(&disconnect_callback)); 1176 1177 EXPECT_CALL(*device0_, CreateGattConnection(_, _)) 1178 .Times(1) 1179 .WillOnce(SaveArg<0>(&connect_callback)); 1180 1181 ExtensionTestMessageListener listener("ready", true); 1182 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 1183 "bluetooth_low_energy/connect_in_progress"))); 1184 1185 listener.WaitUntilSatisfied(); 1186 connect_callback.Run(conn_ptr.Pass()); 1187 1188 listener.Reset(); 1189 listener.WaitUntilSatisfied(); 1190 disconnect_callback.Run(); 1191 1192 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 1193 1194 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 1195 } 1196 1197 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, StartStopNotifications) { 1198 ResultCatcher catcher; 1199 catcher.RestrictToProfile(browser()->profile()); 1200 1201 event_router()->DeviceAdded(mock_adapter_, device0_.get()); 1202 event_router()->GattServiceAdded(device0_.get(), service0_.get()); 1203 event_router()->GattServiceAdded(device0_.get(), service1_.get()); 1204 event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); 1205 event_router()->GattCharacteristicAdded(service0_.get(), chrc1_.get()); 1206 event_router()->GattCharacteristicAdded(service1_.get(), chrc2_.get()); 1207 1208 EXPECT_CALL(*mock_adapter_, GetDevice(_)) 1209 .WillRepeatedly(Return(device0_.get())); 1210 EXPECT_CALL(*device0_, GetGattService(kTestServiceId0)) 1211 .WillRepeatedly(Return(service0_.get())); 1212 EXPECT_CALL(*device0_, GetGattService(kTestServiceId1)) 1213 .WillRepeatedly(Return(service1_.get())); 1214 EXPECT_CALL(*service1_, GetCharacteristic(kTestCharacteristicId2)) 1215 .Times(1) 1216 .WillOnce(Return(chrc2_.get())); 1217 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) 1218 .Times(2) 1219 .WillRepeatedly(Return(chrc0_.get())); 1220 EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId1)) 1221 .Times(1) 1222 .WillOnce(Return(chrc1_.get())); 1223 1224 BluetoothGattNotifySession* session0 = 1225 new testing::NiceMock<MockBluetoothGattNotifySession>( 1226 kTestCharacteristicId0); 1227 MockBluetoothGattNotifySession* session1 = 1228 new testing::NiceMock<MockBluetoothGattNotifySession>( 1229 kTestCharacteristicId1); 1230 1231 EXPECT_CALL(*session1, Stop(_)) 1232 .Times(1) 1233 .WillOnce(InvokeCallbackArgument<0>()); 1234 1235 EXPECT_CALL(*chrc0_, StartNotifySession(_, _)) 1236 .Times(2) 1237 .WillOnce(InvokeCallbackArgument<1>()) 1238 .WillOnce( 1239 InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( 1240 session0)); 1241 EXPECT_CALL(*chrc1_, StartNotifySession(_, _)) 1242 .Times(1) 1243 .WillOnce( 1244 InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( 1245 session1)); 1246 1247 ExtensionTestMessageListener listener("ready", true); 1248 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( 1249 "bluetooth_low_energy/start_stop_notifications"))); 1250 1251 EXPECT_TRUE(listener.WaitUntilSatisfied()); 1252 1253 std::vector<uint8> value; 1254 event_router()->GattCharacteristicValueChanged( 1255 service0_.get(), chrc0_.get(), value); 1256 event_router()->GattCharacteristicValueChanged( 1257 service0_.get(), chrc1_.get(), value); 1258 event_router()->GattCharacteristicValueChanged( 1259 service1_.get(), chrc2_.get(), value); 1260 1261 listener.Reply("go"); 1262 1263 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 1264 event_router()->GattCharacteristicRemoved(service1_.get(), chrc2_.get()); 1265 event_router()->GattCharacteristicRemoved(service0_.get(), chrc1_.get()); 1266 event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); 1267 event_router()->GattServiceRemoved(device0_.get(), service1_.get()); 1268 event_router()->GattServiceRemoved(device0_.get(), service0_.get()); 1269 event_router()->DeviceRemoved(mock_adapter_, device0_.get()); 1270 } 1271 1272 } // namespace 1273