bluetooth_remote_gatt_service_unittest.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. // Copyright 2015 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. #include "base/logging.h"
  5. #include "base/run_loop.h"
  6. #include "build/build_config.h"
  7. #include "device/bluetooth/bluetooth_gatt_service.h"
  8. #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
  9. #include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. #if BUILDFLAG(IS_ANDROID)
  12. #include "device/bluetooth/test/bluetooth_test_android.h"
  13. #elif BUILDFLAG(IS_MAC)
  14. #include "device/bluetooth/test/bluetooth_test_mac.h"
  15. #elif BUILDFLAG(IS_WIN)
  16. #include "device/bluetooth/test/bluetooth_test_win.h"
  17. #elif defined(USE_CAST_BLUETOOTH_ADAPTER)
  18. #include "device/bluetooth/test/bluetooth_test_cast.h"
  19. #elif BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
  20. #include "device/bluetooth/test/bluetooth_test_bluez.h"
  21. #elif BUILDFLAG(IS_FUCHSIA)
  22. #include "device/bluetooth/test/bluetooth_test_fuchsia.h"
  23. #endif
  24. namespace device {
  25. class BluetoothRemoteGattServiceTest : public BluetoothTest {};
  26. #if BUILDFLAG(IS_WIN)
  27. class BluetoothRemoteGattServiceTestWinrt : public BluetoothTestWinrt {};
  28. #endif
  29. // Android is excluded because it fires a single discovery event per device.
  30. #if BUILDFLAG(IS_MAC)
  31. #define MAYBE_IsDiscoveryComplete IsDiscoveryComplete
  32. #else
  33. #define MAYBE_IsDiscoveryComplete DISABLED_IsDiscoveryComplete
  34. #endif
  35. #if BUILDFLAG(IS_WIN)
  36. TEST_P(BluetoothRemoteGattServiceTestWinrt, IsDiscoveryComplete) {
  37. #else
  38. TEST_F(BluetoothRemoteGattServiceTest, MAYBE_IsDiscoveryComplete) {
  39. #endif
  40. if (!PlatformSupportsLowEnergy()) {
  41. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  42. return;
  43. }
  44. InitWithFakeAdapter();
  45. StartLowEnergyDiscoverySession();
  46. BluetoothDevice* device = SimulateLowEnergyDevice(1);
  47. device->CreateGattConnection(
  48. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  49. SimulateGattConnection(device);
  50. base::RunLoop().RunUntilIdle();
  51. SimulateGattServicesDiscovered(
  52. device, std::vector<std::string>(
  53. {kTestUUIDGenericAccess, kTestUUIDGenericAccess}));
  54. base::RunLoop().RunUntilIdle();
  55. BluetoothRemoteGattService* service = device->GetGattServices()[0];
  56. EXPECT_TRUE(service->IsDiscoveryComplete());
  57. }
  58. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
  59. #define MAYBE_GetIdentifier GetIdentifier
  60. #else
  61. #define MAYBE_GetIdentifier DISABLED_GetIdentifier
  62. #endif
  63. #if BUILDFLAG(IS_WIN)
  64. TEST_P(BluetoothRemoteGattServiceTestWinrt, GetIdentifier) {
  65. #else
  66. TEST_F(BluetoothRemoteGattServiceTest, MAYBE_GetIdentifier) {
  67. #endif
  68. if (!PlatformSupportsLowEnergy()) {
  69. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  70. return;
  71. }
  72. InitWithFakeAdapter();
  73. StartLowEnergyDiscoverySession();
  74. // 2 devices to verify unique IDs across them.
  75. BluetoothDevice* device1 = SimulateLowEnergyDevice(3);
  76. BluetoothDevice* device2 = SimulateLowEnergyDevice(4);
  77. device1->CreateGattConnection(
  78. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  79. device2->CreateGattConnection(
  80. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  81. SimulateGattConnection(device1);
  82. SimulateGattConnection(device2);
  83. base::RunLoop().RunUntilIdle();
  84. // 2 duplicate UUIDs creating 2 service instances on each device.
  85. SimulateGattServicesDiscovered(
  86. device1, std::vector<std::string>(
  87. {kTestUUIDGenericAccess, kTestUUIDGenericAccess}));
  88. SimulateGattServicesDiscovered(
  89. device2, std::vector<std::string>(
  90. {kTestUUIDGenericAccess, kTestUUIDGenericAccess}));
  91. base::RunLoop().RunUntilIdle();
  92. BluetoothRemoteGattService* service1 = device1->GetGattServices()[0];
  93. BluetoothRemoteGattService* service2 = device1->GetGattServices()[1];
  94. BluetoothRemoteGattService* service3 = device2->GetGattServices()[0];
  95. BluetoothRemoteGattService* service4 = device2->GetGattServices()[1];
  96. // All IDs are unique, even though they have the same UUID.
  97. EXPECT_NE(service1->GetIdentifier(), service2->GetIdentifier());
  98. EXPECT_NE(service1->GetIdentifier(), service3->GetIdentifier());
  99. EXPECT_NE(service1->GetIdentifier(), service4->GetIdentifier());
  100. EXPECT_NE(service2->GetIdentifier(), service3->GetIdentifier());
  101. EXPECT_NE(service2->GetIdentifier(), service4->GetIdentifier());
  102. EXPECT_NE(service3->GetIdentifier(), service4->GetIdentifier());
  103. }
  104. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
  105. #define MAYBE_GetUUID GetUUID
  106. #else
  107. #define MAYBE_GetUUID DISABLED_GetUUID
  108. #endif
  109. #if BUILDFLAG(IS_WIN)
  110. TEST_P(BluetoothRemoteGattServiceTestWinrt, GetUUID) {
  111. #else
  112. TEST_F(BluetoothRemoteGattServiceTest, MAYBE_GetUUID) {
  113. #endif
  114. if (!PlatformSupportsLowEnergy()) {
  115. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  116. return;
  117. }
  118. InitWithFakeAdapter();
  119. StartLowEnergyDiscoverySession();
  120. BluetoothDevice* device = SimulateLowEnergyDevice(3);
  121. device->CreateGattConnection(
  122. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  123. SimulateGattConnection(device);
  124. base::RunLoop().RunUntilIdle();
  125. // Create multiple instances with the same UUID.
  126. BluetoothUUID uuid(kTestUUIDGenericAccess);
  127. std::vector<std::string> services;
  128. services.push_back(uuid.canonical_value());
  129. services.push_back(uuid.canonical_value());
  130. SimulateGattServicesDiscovered(device, services);
  131. base::RunLoop().RunUntilIdle();
  132. // Each has the same UUID.
  133. EXPECT_EQ(uuid, device->GetGattServices()[0]->GetUUID());
  134. EXPECT_EQ(uuid, device->GetGattServices()[1]->GetUUID());
  135. }
  136. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
  137. #define MAYBE_GetCharacteristics_FindNone GetCharacteristics_FindNone
  138. #else
  139. #define MAYBE_GetCharacteristics_FindNone DISABLED_GetCharacteristics_FindNone
  140. #endif
  141. #if BUILDFLAG(IS_WIN)
  142. TEST_P(BluetoothRemoteGattServiceTestWinrt, GetCharacteristics_FindNone) {
  143. #else
  144. TEST_F(BluetoothRemoteGattServiceTest, MAYBE_GetCharacteristics_FindNone) {
  145. #endif
  146. if (!PlatformSupportsLowEnergy()) {
  147. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  148. return;
  149. }
  150. InitWithFakeAdapter();
  151. StartLowEnergyDiscoverySession();
  152. BluetoothDevice* device = SimulateLowEnergyDevice(3);
  153. device->CreateGattConnection(
  154. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  155. SimulateGattConnection(device);
  156. base::RunLoop().RunUntilIdle();
  157. // Simulate a service, with no Characteristics:
  158. SimulateGattServicesDiscovered(
  159. device, std::vector<std::string>({kTestUUIDGenericAccess}));
  160. base::RunLoop().RunUntilIdle();
  161. BluetoothRemoteGattService* service = device->GetGattServices()[0];
  162. EXPECT_EQ(0u, service->GetCharacteristics().size());
  163. }
  164. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
  165. #define MAYBE_GetCharacteristics_and_GetCharacteristic \
  166. GetCharacteristics_and_GetCharacteristic
  167. #else
  168. #define MAYBE_GetCharacteristics_and_GetCharacteristic \
  169. DISABLED_GetCharacteristics_and_GetCharacteristic
  170. #endif
  171. #if BUILDFLAG(IS_WIN)
  172. TEST_P(BluetoothRemoteGattServiceTestWinrt,
  173. GetCharacteristics_and_GetCharacteristic) {
  174. #else
  175. TEST_F(BluetoothRemoteGattServiceTest,
  176. MAYBE_GetCharacteristics_and_GetCharacteristic) {
  177. #endif
  178. if (!PlatformSupportsLowEnergy()) {
  179. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  180. return;
  181. }
  182. InitWithFakeAdapter();
  183. StartLowEnergyDiscoverySession();
  184. BluetoothDevice* device = SimulateLowEnergyDevice(3);
  185. device->CreateGattConnection(
  186. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  187. SimulateGattConnection(device);
  188. base::RunLoop().RunUntilIdle();
  189. // Simulate a service, with several Characteristics:
  190. SimulateGattServicesDiscovered(
  191. device, std::vector<std::string>({kTestUUIDGenericAccess}));
  192. base::RunLoop().RunUntilIdle();
  193. BluetoothRemoteGattService* service = device->GetGattServices()[0];
  194. SimulateGattCharacteristic(service, kTestUUIDDeviceName, /* properties */ 0);
  195. SimulateGattCharacteristic(service, kTestUUIDAppearance,
  196. /* properties */ 0);
  197. // Duplicate UUID.
  198. SimulateGattCharacteristic(service, kTestUUIDAppearance,
  199. /* properties */ 0);
  200. SimulateGattCharacteristic(service, kTestUUIDReconnectionAddress,
  201. /* properties */ 0);
  202. base::RunLoop().RunUntilIdle();
  203. // Verify that GetCharacteristic can retrieve characteristics again by ID,
  204. // and that the same Characteristics come back.
  205. EXPECT_EQ(4u, service->GetCharacteristics().size());
  206. std::string char_id1 = service->GetCharacteristics()[0]->GetIdentifier();
  207. std::string char_id2 = service->GetCharacteristics()[1]->GetIdentifier();
  208. std::string char_id3 = service->GetCharacteristics()[2]->GetIdentifier();
  209. std::string char_id4 = service->GetCharacteristics()[3]->GetIdentifier();
  210. BluetoothUUID char_uuid1 = service->GetCharacteristics()[0]->GetUUID();
  211. BluetoothUUID char_uuid2 = service->GetCharacteristics()[1]->GetUUID();
  212. BluetoothUUID char_uuid3 = service->GetCharacteristics()[2]->GetUUID();
  213. BluetoothUUID char_uuid4 = service->GetCharacteristics()[3]->GetUUID();
  214. EXPECT_EQ(char_uuid1, service->GetCharacteristic(char_id1)->GetUUID());
  215. EXPECT_EQ(char_uuid2, service->GetCharacteristic(char_id2)->GetUUID());
  216. EXPECT_EQ(char_uuid3, service->GetCharacteristic(char_id3)->GetUUID());
  217. EXPECT_EQ(char_uuid4, service->GetCharacteristic(char_id4)->GetUUID());
  218. // GetCharacteristics & GetCharacteristic return the same object for the same
  219. // ID:
  220. EXPECT_EQ(service->GetCharacteristics()[0],
  221. service->GetCharacteristic(char_id1));
  222. EXPECT_EQ(service->GetCharacteristic(char_id1),
  223. service->GetCharacteristic(char_id1));
  224. }
  225. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
  226. #define MAYBE_GetCharacteristicsByUUID GetCharacteristicsByUUID
  227. #else
  228. #define MAYBE_GetCharacteristicsByUUID DISABLED_GetCharacteristicsByUUID
  229. #endif
  230. #if BUILDFLAG(IS_WIN)
  231. TEST_P(BluetoothRemoteGattServiceTestWinrt, GetCharacteristicsByUUID) {
  232. #else
  233. TEST_F(BluetoothRemoteGattServiceTest, MAYBE_GetCharacteristicsByUUID) {
  234. #endif
  235. if (!PlatformSupportsLowEnergy()) {
  236. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  237. return;
  238. }
  239. InitWithFakeAdapter();
  240. StartLowEnergyDiscoverySession();
  241. BluetoothDevice* device = SimulateLowEnergyDevice(3);
  242. device->CreateGattConnection(
  243. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  244. SimulateGattConnection(device);
  245. base::RunLoop().RunUntilIdle();
  246. // Simulate two primary GATT services.
  247. SimulateGattServicesDiscovered(
  248. device,
  249. std::vector<std::string>({kTestUUIDGenericAccess, kTestUUIDHeartRate}));
  250. base::RunLoop().RunUntilIdle();
  251. BluetoothRemoteGattService* service1 = device->GetGattServices()[0];
  252. BluetoothRemoteGattService* service2 = device->GetGattServices()[1];
  253. SimulateGattCharacteristic(service1, kTestUUIDDeviceName,
  254. /* properties */ 0);
  255. // 2 duplicate UUIDs creating 2 instances.
  256. SimulateGattCharacteristic(service2, kTestUUIDHeartRateMeasurement,
  257. /* properties */ 0);
  258. SimulateGattCharacteristic(service2, kTestUUIDHeartRateMeasurement,
  259. /* properties */ 0);
  260. base::RunLoop().RunUntilIdle();
  261. {
  262. std::vector<BluetoothRemoteGattCharacteristic*> characteristics =
  263. service1->GetCharacteristicsByUUID(BluetoothUUID(kTestUUIDDeviceName));
  264. EXPECT_EQ(1u, characteristics.size());
  265. EXPECT_EQ(kTestUUIDDeviceName,
  266. characteristics[0]->GetUUID().canonical_value());
  267. }
  268. {
  269. std::vector<BluetoothRemoteGattCharacteristic*> characteristics =
  270. service2->GetCharacteristicsByUUID(
  271. BluetoothUUID(kTestUUIDHeartRateMeasurement));
  272. EXPECT_EQ(2u, characteristics.size());
  273. EXPECT_EQ(kTestUUIDHeartRateMeasurement,
  274. characteristics[0]->GetUUID().canonical_value());
  275. EXPECT_EQ(kTestUUIDHeartRateMeasurement,
  276. characteristics[1]->GetUUID().canonical_value());
  277. EXPECT_NE(characteristics[0]->GetIdentifier(),
  278. characteristics[1]->GetIdentifier());
  279. }
  280. BluetoothUUID characteristic_uuid_not_exist_in_setup(
  281. "33333333-0000-1000-8000-00805f9b34fb");
  282. EXPECT_TRUE(
  283. service1->GetCharacteristicsByUUID(characteristic_uuid_not_exist_in_setup)
  284. .empty());
  285. EXPECT_TRUE(
  286. service2->GetCharacteristicsByUUID(characteristic_uuid_not_exist_in_setup)
  287. .empty());
  288. }
  289. #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
  290. #define MAYBE_GattCharacteristics_ObserversCalls \
  291. GattCharacteristics_ObserversCalls
  292. #else
  293. #define MAYBE_GattCharacteristics_ObserversCalls \
  294. DISABLED_GattCharacteristics_ObserversCalls
  295. #endif
  296. // The GattServicesRemoved event is not implemented for WinRT.
  297. TEST_F(BluetoothRemoteGattServiceTest,
  298. MAYBE_GattCharacteristics_ObserversCalls) {
  299. if (!PlatformSupportsLowEnergy()) {
  300. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  301. return;
  302. }
  303. InitWithFakeAdapter();
  304. StartLowEnergyDiscoverySession();
  305. BluetoothDevice* device = SimulateLowEnergyDevice(3);
  306. device->CreateGattConnection(
  307. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  308. SimulateGattConnection(device);
  309. base::RunLoop().RunUntilIdle();
  310. TestBluetoothAdapterObserver observer(adapter_);
  311. // Simulate a service, with several Characteristics:
  312. SimulateGattServicesDiscovered(
  313. device, std::vector<std::string>({kTestUUIDGenericAccess}));
  314. base::RunLoop().RunUntilIdle();
  315. BluetoothRemoteGattService* service = device->GetGattServices()[0];
  316. SimulateGattCharacteristic(service, kTestUUIDDeviceName, /* properties */ 0);
  317. SimulateGattCharacteristic(service, kTestUUIDAppearance,
  318. /* properties */ 0);
  319. // Duplicate UUID.
  320. SimulateGattCharacteristic(service, kTestUUIDAppearance,
  321. /* properties */ 0);
  322. SimulateGattCharacteristic(service, kTestUUIDReconnectionAddress,
  323. /* properties */ 0);
  324. // Simulate remove of characteristics one by one.
  325. EXPECT_EQ(4u, service->GetCharacteristics().size());
  326. std::string removed_char = service->GetCharacteristics()[0]->GetIdentifier();
  327. SimulateGattCharacteristicRemoved(service,
  328. service->GetCharacteristic(removed_char));
  329. EXPECT_EQ(1, observer.gatt_characteristic_removed_count());
  330. EXPECT_FALSE(service->GetCharacteristic(removed_char));
  331. EXPECT_EQ(3u, service->GetCharacteristics().size());
  332. removed_char = service->GetCharacteristics()[0]->GetIdentifier();
  333. SimulateGattCharacteristicRemoved(service,
  334. service->GetCharacteristic(removed_char));
  335. EXPECT_EQ(2, observer.gatt_characteristic_removed_count());
  336. EXPECT_FALSE(service->GetCharacteristic(removed_char));
  337. EXPECT_EQ(2u, service->GetCharacteristics().size());
  338. removed_char = service->GetCharacteristics()[0]->GetIdentifier();
  339. SimulateGattCharacteristicRemoved(service,
  340. service->GetCharacteristic(removed_char));
  341. EXPECT_EQ(3, observer.gatt_characteristic_removed_count());
  342. EXPECT_FALSE(service->GetCharacteristic(removed_char));
  343. EXPECT_EQ(1u, service->GetCharacteristics().size());
  344. removed_char = service->GetCharacteristics()[0]->GetIdentifier();
  345. SimulateGattCharacteristicRemoved(service,
  346. service->GetCharacteristic(removed_char));
  347. EXPECT_EQ(4, observer.gatt_characteristic_removed_count());
  348. EXPECT_FALSE(service->GetCharacteristic(removed_char));
  349. EXPECT_EQ(0u, service->GetCharacteristics().size());
  350. }
  351. #if BUILDFLAG(IS_MAC)
  352. #define MAYBE_SimulateGattServiceRemove SimulateGattServiceRemove
  353. #else
  354. #define MAYBE_SimulateGattServiceRemove DISABLED_SimulateGattServiceRemove
  355. #endif
  356. #if BUILDFLAG(IS_WIN)
  357. TEST_P(BluetoothRemoteGattServiceTestWinrt, SimulateGattServiceRemove) {
  358. #else
  359. TEST_F(BluetoothRemoteGattServiceTest, MAYBE_SimulateGattServiceRemove) {
  360. #endif
  361. if (!PlatformSupportsLowEnergy()) {
  362. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  363. return;
  364. }
  365. InitWithFakeAdapter();
  366. StartLowEnergyDiscoverySession();
  367. BluetoothDevice* device = SimulateLowEnergyDevice(3);
  368. device->CreateGattConnection(
  369. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  370. SimulateGattConnection(device);
  371. base::RunLoop().RunUntilIdle();
  372. TestBluetoothAdapterObserver observer(adapter_);
  373. // Simulate two primary GATT services.
  374. SimulateGattServicesDiscovered(
  375. device,
  376. std::vector<std::string>({kTestUUIDGenericAccess, kTestUUIDHeartRate}));
  377. base::RunLoop().RunUntilIdle();
  378. EXPECT_EQ(2u, device->GetGattServices().size());
  379. // Simulate remove of a primary service.
  380. BluetoothRemoteGattService* service1 = device->GetGattServices()[0];
  381. BluetoothRemoteGattService* service2 = device->GetGattServices()[1];
  382. std::string removed_service = service1->GetIdentifier();
  383. SimulateGattServiceRemoved(device->GetGattService(removed_service));
  384. base::RunLoop().RunUntilIdle();
  385. #if BUILDFLAG(IS_WIN)
  386. if (!UsesNewBleImplementation()) {
  387. // The GattServicesRemoved event is not implemented for WinRT.
  388. EXPECT_EQ(1, observer.gatt_service_removed_count());
  389. }
  390. #endif // BUILDFLAG(IS_WIN)
  391. EXPECT_EQ(1u, device->GetGattServices().size());
  392. EXPECT_FALSE(device->GetGattService(removed_service));
  393. EXPECT_EQ(device->GetGattServices()[0], service2);
  394. }
  395. #if BUILDFLAG(IS_MAC)
  396. // Tests to receive a services changed notification from macOS, while
  397. // discovering characteristics. The gatt device should scan again for services
  398. // and characteristics, before scanning for descriptors. Only after the gatt
  399. // service changed notification should be sent.
  400. // Android: This test doesn't apply to Android because there is no services
  401. // changed event that could arrive during a discovery procedure.
  402. TEST_F(BluetoothRemoteGattServiceTest,
  403. SimulateDeviceModificationWhileDiscoveringCharacteristics) {
  404. if (!PlatformSupportsLowEnergy()) {
  405. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  406. return;
  407. }
  408. InitWithFakeAdapter();
  409. StartLowEnergyDiscoverySession();
  410. BluetoothDevice* device = SimulateLowEnergyDevice(3);
  411. device->CreateGattConnection(
  412. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  413. TestBluetoothAdapterObserver observer(adapter_);
  414. // Starts first discovery process.
  415. SimulateGattConnection(device);
  416. AddServicesToDeviceMac(device, {kTestUUIDHeartRate});
  417. SimulateDidDiscoverServicesMac(device);
  418. EXPECT_EQ(1u, device->GetGattServices().size());
  419. BluetoothRemoteGattService* service = device->GetGattServices()[0];
  420. std::string characteristic_uuid1 = "11111111-0000-1000-8000-00805f9b34fb";
  421. AddCharacteristicToServiceMac(service, characteristic_uuid1,
  422. /* properties */ 0);
  423. // Now waiting for characteristic discovery.
  424. // Starts second discovery process.
  425. SimulateGattServicesChanged(device);
  426. SimulateDidDiscoverServicesMac(device);
  427. // Now waiting for the second characteristic discovery.
  428. // First system call to -[id<CBPeripheralDelegate>
  429. // peripheral:didDiscoverCharacteristicsForService:error:]
  430. SimulateDidDiscoverCharacteristicsMac(service);
  431. EXPECT_EQ(0, observer.gatt_service_changed_count());
  432. EXPECT_EQ(1u, service->GetCharacteristics().size());
  433. // Finish discovery process.
  434. std::string characteristic_uuid2 = "22222222-0000-1000-8000-00805f9b34fb";
  435. AddCharacteristicToServiceMac(service, characteristic_uuid2,
  436. /* properties */ 0);
  437. // Second system call to -[id<CBPeripheralDelegate>
  438. // peripheral:didDiscoverCharacteristicsForService:error:]
  439. SimulateDidDiscoverCharacteristicsMac(service);
  440. EXPECT_EQ(2u, service->GetCharacteristics().size());
  441. EXPECT_EQ(0, observer.gatt_service_changed_count());
  442. BluetoothRemoteGattCharacteristic* characteristic1 =
  443. service->GetCharacteristics()[0];
  444. BluetoothRemoteGattCharacteristic* characteristic2 =
  445. service->GetCharacteristics()[1];
  446. if (characteristic1->GetUUID().canonical_value() == characteristic_uuid2) {
  447. BluetoothRemoteGattCharacteristic* tmp = characteristic1;
  448. characteristic1 = characteristic2;
  449. characteristic2 = tmp;
  450. }
  451. EXPECT_EQ(characteristic_uuid1, characteristic1->GetUUID().canonical_value());
  452. EXPECT_EQ(characteristic_uuid2, characteristic2->GetUUID().canonical_value());
  453. SimulateDidDiscoverDescriptorsMac(characteristic1);
  454. SimulateDidDiscoverDescriptorsMac(characteristic2);
  455. EXPECT_EQ(1, observer.gatt_service_changed_count());
  456. }
  457. #endif // BUILDFLAG(IS_MAC)
  458. #if BUILDFLAG(IS_MAC)
  459. // Simulates to receive an extra discovery characteristic notifications from
  460. // macOS. Those notifications should be ignored.
  461. // Android: This test doesn't apply to Android because there is no services
  462. // changed event that could arrive during a discovery procedure.
  463. TEST_F(BluetoothRemoteGattServiceTest, ExtraDidDiscoverServicesCall) {
  464. if (!PlatformSupportsLowEnergy()) {
  465. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  466. return;
  467. }
  468. InitWithFakeAdapter();
  469. StartLowEnergyDiscoverySession();
  470. BluetoothDevice* device = SimulateLowEnergyDevice(3);
  471. device->CreateGattConnection(
  472. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  473. TestBluetoothAdapterObserver observer(adapter_);
  474. // Starts first discovery process.
  475. SimulateGattConnection(device);
  476. AddServicesToDeviceMac(device, {kTestUUIDHeartRate});
  477. SimulateDidDiscoverServicesMac(device);
  478. EXPECT_EQ(1u, device->GetGattServices().size());
  479. BluetoothRemoteGattService* service = device->GetGattServices()[0];
  480. std::string characteristic_uuid = "11111111-0000-1000-8000-00805f9b34fb";
  481. AddCharacteristicToServiceMac(service, characteristic_uuid,
  482. /* properties */ 0);
  483. SimulateDidDiscoverCharacteristicsMac(service);
  484. EXPECT_EQ(1u, service->GetCharacteristics().size());
  485. BluetoothRemoteGattCharacteristic* characteristic =
  486. service->GetCharacteristics()[0];
  487. std::string descriptor_uuid = "22222222-0000-1000-8000-00805f9b34fb";
  488. AddDescriptorToCharacteristicMac(characteristic, descriptor_uuid);
  489. SimulateDidDiscoverDescriptorsMac(characteristic);
  490. EXPECT_EQ(1, observer.gatt_service_changed_count());
  491. EXPECT_EQ(1u, service->GetCharacteristics().size());
  492. EXPECT_EQ(1u, characteristic->GetDescriptors().size());
  493. observer.Reset();
  494. SimulateDidDiscoverServicesMac(device); // Extra system call.
  495. SimulateGattServicesChanged(device);
  496. SimulateDidDiscoverServicesMac(device);
  497. SimulateDidDiscoverServicesMac(device); // Extra system call.
  498. SimulateDidDiscoverCharacteristicsMac(service);
  499. SimulateDidDiscoverServicesMac(device); // Extra system call.
  500. SimulateDidDiscoverDescriptorsMac(characteristic);
  501. SimulateDidDiscoverServicesMac(device); // Extra system call.
  502. EXPECT_EQ(2, observer.device_changed_count());
  503. }
  504. #endif // BUILDFLAG(IS_MAC)
  505. #if BUILDFLAG(IS_MAC)
  506. // Simulates to receive an extra discovery characteristic notifications from
  507. // macOS. Those notifications should be ignored.
  508. // Android: This test doesn't apply to Android because there is no services
  509. // changed event that could arrive during a discovery procedure.
  510. TEST_F(BluetoothRemoteGattServiceTest, ExtraDidDiscoverCharacteristicsCall) {
  511. if (!PlatformSupportsLowEnergy()) {
  512. LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
  513. return;
  514. }
  515. InitWithFakeAdapter();
  516. StartLowEnergyDiscoverySession();
  517. BluetoothDevice* device = SimulateLowEnergyDevice(3);
  518. device->CreateGattConnection(
  519. GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
  520. TestBluetoothAdapterObserver observer(adapter_);
  521. // Starts first discovery process.
  522. SimulateGattConnection(device);
  523. AddServicesToDeviceMac(device, {kTestUUIDHeartRate});
  524. SimulateDidDiscoverServicesMac(device);
  525. EXPECT_EQ(1u, device->GetGattServices().size());
  526. BluetoothRemoteGattService* service = device->GetGattServices()[0];
  527. std::string characteristic_uuid = "11111111-0000-1000-8000-00805f9b34fb";
  528. AddCharacteristicToServiceMac(service, characteristic_uuid,
  529. /* properties */ 0);
  530. SimulateDidDiscoverCharacteristicsMac(service);
  531. EXPECT_EQ(1u, service->GetCharacteristics().size());
  532. BluetoothRemoteGattCharacteristic* characteristic =
  533. service->GetCharacteristics()[0];
  534. std::string descriptor_uuid = "22222222-0000-1000-8000-00805f9b34fb";
  535. AddDescriptorToCharacteristicMac(characteristic, descriptor_uuid);
  536. SimulateDidDiscoverDescriptorsMac(characteristic);
  537. EXPECT_EQ(1, observer.gatt_service_changed_count());
  538. EXPECT_EQ(1u, service->GetCharacteristics().size());
  539. EXPECT_EQ(1u, characteristic->GetDescriptors().size());
  540. observer.Reset();
  541. SimulateDidDiscoverCharacteristicsMac(service); // Extra system call.
  542. SimulateGattServicesChanged(device);
  543. SimulateDidDiscoverCharacteristicsMac(service); // Extra system call.
  544. SimulateDidDiscoverServicesMac(device);
  545. SimulateDidDiscoverCharacteristicsMac(service);
  546. SimulateDidDiscoverCharacteristicsMac(service); // Extra system call.
  547. SimulateDidDiscoverDescriptorsMac(characteristic);
  548. SimulateDidDiscoverCharacteristicsMac(service); // Extra system call.
  549. EXPECT_EQ(2, observer.device_changed_count());
  550. }
  551. #endif // BUILDFLAG(IS_MAC)
  552. #if BUILDFLAG(IS_WIN)
  553. INSTANTIATE_TEST_SUITE_P(All,
  554. BluetoothRemoteGattServiceTestWinrt,
  555. ::testing::ValuesIn(kBluetoothTestWinrtParamAll));
  556. #endif // BUILDFLAG(IS_WIN)
  557. } // namespace device