123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606 |
- // Copyright 2015 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "base/logging.h"
- #include "base/run_loop.h"
- #include "build/build_config.h"
- #include "device/bluetooth/bluetooth_gatt_service.h"
- #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
- #include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #if BUILDFLAG(IS_ANDROID)
- #include "device/bluetooth/test/bluetooth_test_android.h"
- #elif BUILDFLAG(IS_MAC)
- #include "device/bluetooth/test/bluetooth_test_mac.h"
- #elif BUILDFLAG(IS_WIN)
- #include "device/bluetooth/test/bluetooth_test_win.h"
- #elif defined(USE_CAST_BLUETOOTH_ADAPTER)
- #include "device/bluetooth/test/bluetooth_test_cast.h"
- #elif BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
- #include "device/bluetooth/test/bluetooth_test_bluez.h"
- #elif BUILDFLAG(IS_FUCHSIA)
- #include "device/bluetooth/test/bluetooth_test_fuchsia.h"
- #endif
- namespace device {
- class BluetoothRemoteGattServiceTest : public BluetoothTest {};
- #if BUILDFLAG(IS_WIN)
- class BluetoothRemoteGattServiceTestWinrt : public BluetoothTestWinrt {};
- #endif
- // Android is excluded because it fires a single discovery event per device.
- #if BUILDFLAG(IS_MAC)
- #define MAYBE_IsDiscoveryComplete IsDiscoveryComplete
- #else
- #define MAYBE_IsDiscoveryComplete DISABLED_IsDiscoveryComplete
- #endif
- #if BUILDFLAG(IS_WIN)
- TEST_P(BluetoothRemoteGattServiceTestWinrt, IsDiscoveryComplete) {
- #else
- TEST_F(BluetoothRemoteGattServiceTest, MAYBE_IsDiscoveryComplete) {
- #endif
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(1);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- SimulateGattConnection(device);
- base::RunLoop().RunUntilIdle();
- SimulateGattServicesDiscovered(
- device, std::vector<std::string>(
- {kTestUUIDGenericAccess, kTestUUIDGenericAccess}));
- base::RunLoop().RunUntilIdle();
- BluetoothRemoteGattService* service = device->GetGattServices()[0];
- EXPECT_TRUE(service->IsDiscoveryComplete());
- }
- #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
- #define MAYBE_GetIdentifier GetIdentifier
- #else
- #define MAYBE_GetIdentifier DISABLED_GetIdentifier
- #endif
- #if BUILDFLAG(IS_WIN)
- TEST_P(BluetoothRemoteGattServiceTestWinrt, GetIdentifier) {
- #else
- TEST_F(BluetoothRemoteGattServiceTest, MAYBE_GetIdentifier) {
- #endif
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- // 2 devices to verify unique IDs across them.
- BluetoothDevice* device1 = SimulateLowEnergyDevice(3);
- BluetoothDevice* device2 = SimulateLowEnergyDevice(4);
- device1->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- device2->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- SimulateGattConnection(device1);
- SimulateGattConnection(device2);
- base::RunLoop().RunUntilIdle();
- // 2 duplicate UUIDs creating 2 service instances on each device.
- SimulateGattServicesDiscovered(
- device1, std::vector<std::string>(
- {kTestUUIDGenericAccess, kTestUUIDGenericAccess}));
- SimulateGattServicesDiscovered(
- device2, std::vector<std::string>(
- {kTestUUIDGenericAccess, kTestUUIDGenericAccess}));
- base::RunLoop().RunUntilIdle();
- BluetoothRemoteGattService* service1 = device1->GetGattServices()[0];
- BluetoothRemoteGattService* service2 = device1->GetGattServices()[1];
- BluetoothRemoteGattService* service3 = device2->GetGattServices()[0];
- BluetoothRemoteGattService* service4 = device2->GetGattServices()[1];
- // All IDs are unique, even though they have the same UUID.
- EXPECT_NE(service1->GetIdentifier(), service2->GetIdentifier());
- EXPECT_NE(service1->GetIdentifier(), service3->GetIdentifier());
- EXPECT_NE(service1->GetIdentifier(), service4->GetIdentifier());
- EXPECT_NE(service2->GetIdentifier(), service3->GetIdentifier());
- EXPECT_NE(service2->GetIdentifier(), service4->GetIdentifier());
- EXPECT_NE(service3->GetIdentifier(), service4->GetIdentifier());
- }
- #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
- #define MAYBE_GetUUID GetUUID
- #else
- #define MAYBE_GetUUID DISABLED_GetUUID
- #endif
- #if BUILDFLAG(IS_WIN)
- TEST_P(BluetoothRemoteGattServiceTestWinrt, GetUUID) {
- #else
- TEST_F(BluetoothRemoteGattServiceTest, MAYBE_GetUUID) {
- #endif
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(3);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- SimulateGattConnection(device);
- base::RunLoop().RunUntilIdle();
- // Create multiple instances with the same UUID.
- BluetoothUUID uuid(kTestUUIDGenericAccess);
- std::vector<std::string> services;
- services.push_back(uuid.canonical_value());
- services.push_back(uuid.canonical_value());
- SimulateGattServicesDiscovered(device, services);
- base::RunLoop().RunUntilIdle();
- // Each has the same UUID.
- EXPECT_EQ(uuid, device->GetGattServices()[0]->GetUUID());
- EXPECT_EQ(uuid, device->GetGattServices()[1]->GetUUID());
- }
- #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
- #define MAYBE_GetCharacteristics_FindNone GetCharacteristics_FindNone
- #else
- #define MAYBE_GetCharacteristics_FindNone DISABLED_GetCharacteristics_FindNone
- #endif
- #if BUILDFLAG(IS_WIN)
- TEST_P(BluetoothRemoteGattServiceTestWinrt, GetCharacteristics_FindNone) {
- #else
- TEST_F(BluetoothRemoteGattServiceTest, MAYBE_GetCharacteristics_FindNone) {
- #endif
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(3);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- SimulateGattConnection(device);
- base::RunLoop().RunUntilIdle();
- // Simulate a service, with no Characteristics:
- SimulateGattServicesDiscovered(
- device, std::vector<std::string>({kTestUUIDGenericAccess}));
- base::RunLoop().RunUntilIdle();
- BluetoothRemoteGattService* service = device->GetGattServices()[0];
- EXPECT_EQ(0u, service->GetCharacteristics().size());
- }
- #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
- #define MAYBE_GetCharacteristics_and_GetCharacteristic \
- GetCharacteristics_and_GetCharacteristic
- #else
- #define MAYBE_GetCharacteristics_and_GetCharacteristic \
- DISABLED_GetCharacteristics_and_GetCharacteristic
- #endif
- #if BUILDFLAG(IS_WIN)
- TEST_P(BluetoothRemoteGattServiceTestWinrt,
- GetCharacteristics_and_GetCharacteristic) {
- #else
- TEST_F(BluetoothRemoteGattServiceTest,
- MAYBE_GetCharacteristics_and_GetCharacteristic) {
- #endif
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(3);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- SimulateGattConnection(device);
- base::RunLoop().RunUntilIdle();
- // Simulate a service, with several Characteristics:
- SimulateGattServicesDiscovered(
- device, std::vector<std::string>({kTestUUIDGenericAccess}));
- base::RunLoop().RunUntilIdle();
- BluetoothRemoteGattService* service = device->GetGattServices()[0];
- SimulateGattCharacteristic(service, kTestUUIDDeviceName, /* properties */ 0);
- SimulateGattCharacteristic(service, kTestUUIDAppearance,
- /* properties */ 0);
- // Duplicate UUID.
- SimulateGattCharacteristic(service, kTestUUIDAppearance,
- /* properties */ 0);
- SimulateGattCharacteristic(service, kTestUUIDReconnectionAddress,
- /* properties */ 0);
- base::RunLoop().RunUntilIdle();
- // Verify that GetCharacteristic can retrieve characteristics again by ID,
- // and that the same Characteristics come back.
- EXPECT_EQ(4u, service->GetCharacteristics().size());
- std::string char_id1 = service->GetCharacteristics()[0]->GetIdentifier();
- std::string char_id2 = service->GetCharacteristics()[1]->GetIdentifier();
- std::string char_id3 = service->GetCharacteristics()[2]->GetIdentifier();
- std::string char_id4 = service->GetCharacteristics()[3]->GetIdentifier();
- BluetoothUUID char_uuid1 = service->GetCharacteristics()[0]->GetUUID();
- BluetoothUUID char_uuid2 = service->GetCharacteristics()[1]->GetUUID();
- BluetoothUUID char_uuid3 = service->GetCharacteristics()[2]->GetUUID();
- BluetoothUUID char_uuid4 = service->GetCharacteristics()[3]->GetUUID();
- EXPECT_EQ(char_uuid1, service->GetCharacteristic(char_id1)->GetUUID());
- EXPECT_EQ(char_uuid2, service->GetCharacteristic(char_id2)->GetUUID());
- EXPECT_EQ(char_uuid3, service->GetCharacteristic(char_id3)->GetUUID());
- EXPECT_EQ(char_uuid4, service->GetCharacteristic(char_id4)->GetUUID());
- // GetCharacteristics & GetCharacteristic return the same object for the same
- // ID:
- EXPECT_EQ(service->GetCharacteristics()[0],
- service->GetCharacteristic(char_id1));
- EXPECT_EQ(service->GetCharacteristic(char_id1),
- service->GetCharacteristic(char_id1));
- }
- #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
- #define MAYBE_GetCharacteristicsByUUID GetCharacteristicsByUUID
- #else
- #define MAYBE_GetCharacteristicsByUUID DISABLED_GetCharacteristicsByUUID
- #endif
- #if BUILDFLAG(IS_WIN)
- TEST_P(BluetoothRemoteGattServiceTestWinrt, GetCharacteristicsByUUID) {
- #else
- TEST_F(BluetoothRemoteGattServiceTest, MAYBE_GetCharacteristicsByUUID) {
- #endif
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(3);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- SimulateGattConnection(device);
- base::RunLoop().RunUntilIdle();
- // Simulate two primary GATT services.
- SimulateGattServicesDiscovered(
- device,
- std::vector<std::string>({kTestUUIDGenericAccess, kTestUUIDHeartRate}));
- base::RunLoop().RunUntilIdle();
- BluetoothRemoteGattService* service1 = device->GetGattServices()[0];
- BluetoothRemoteGattService* service2 = device->GetGattServices()[1];
- SimulateGattCharacteristic(service1, kTestUUIDDeviceName,
- /* properties */ 0);
- // 2 duplicate UUIDs creating 2 instances.
- SimulateGattCharacteristic(service2, kTestUUIDHeartRateMeasurement,
- /* properties */ 0);
- SimulateGattCharacteristic(service2, kTestUUIDHeartRateMeasurement,
- /* properties */ 0);
- base::RunLoop().RunUntilIdle();
- {
- std::vector<BluetoothRemoteGattCharacteristic*> characteristics =
- service1->GetCharacteristicsByUUID(BluetoothUUID(kTestUUIDDeviceName));
- EXPECT_EQ(1u, characteristics.size());
- EXPECT_EQ(kTestUUIDDeviceName,
- characteristics[0]->GetUUID().canonical_value());
- }
- {
- std::vector<BluetoothRemoteGattCharacteristic*> characteristics =
- service2->GetCharacteristicsByUUID(
- BluetoothUUID(kTestUUIDHeartRateMeasurement));
- EXPECT_EQ(2u, characteristics.size());
- EXPECT_EQ(kTestUUIDHeartRateMeasurement,
- characteristics[0]->GetUUID().canonical_value());
- EXPECT_EQ(kTestUUIDHeartRateMeasurement,
- characteristics[1]->GetUUID().canonical_value());
- EXPECT_NE(characteristics[0]->GetIdentifier(),
- characteristics[1]->GetIdentifier());
- }
- BluetoothUUID characteristic_uuid_not_exist_in_setup(
- "33333333-0000-1000-8000-00805f9b34fb");
- EXPECT_TRUE(
- service1->GetCharacteristicsByUUID(characteristic_uuid_not_exist_in_setup)
- .empty());
- EXPECT_TRUE(
- service2->GetCharacteristicsByUUID(characteristic_uuid_not_exist_in_setup)
- .empty());
- }
- #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
- #define MAYBE_GattCharacteristics_ObserversCalls \
- GattCharacteristics_ObserversCalls
- #else
- #define MAYBE_GattCharacteristics_ObserversCalls \
- DISABLED_GattCharacteristics_ObserversCalls
- #endif
- // The GattServicesRemoved event is not implemented for WinRT.
- TEST_F(BluetoothRemoteGattServiceTest,
- MAYBE_GattCharacteristics_ObserversCalls) {
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(3);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- SimulateGattConnection(device);
- base::RunLoop().RunUntilIdle();
- TestBluetoothAdapterObserver observer(adapter_);
- // Simulate a service, with several Characteristics:
- SimulateGattServicesDiscovered(
- device, std::vector<std::string>({kTestUUIDGenericAccess}));
- base::RunLoop().RunUntilIdle();
- BluetoothRemoteGattService* service = device->GetGattServices()[0];
- SimulateGattCharacteristic(service, kTestUUIDDeviceName, /* properties */ 0);
- SimulateGattCharacteristic(service, kTestUUIDAppearance,
- /* properties */ 0);
- // Duplicate UUID.
- SimulateGattCharacteristic(service, kTestUUIDAppearance,
- /* properties */ 0);
- SimulateGattCharacteristic(service, kTestUUIDReconnectionAddress,
- /* properties */ 0);
- // Simulate remove of characteristics one by one.
- EXPECT_EQ(4u, service->GetCharacteristics().size());
- std::string removed_char = service->GetCharacteristics()[0]->GetIdentifier();
- SimulateGattCharacteristicRemoved(service,
- service->GetCharacteristic(removed_char));
- EXPECT_EQ(1, observer.gatt_characteristic_removed_count());
- EXPECT_FALSE(service->GetCharacteristic(removed_char));
- EXPECT_EQ(3u, service->GetCharacteristics().size());
- removed_char = service->GetCharacteristics()[0]->GetIdentifier();
- SimulateGattCharacteristicRemoved(service,
- service->GetCharacteristic(removed_char));
- EXPECT_EQ(2, observer.gatt_characteristic_removed_count());
- EXPECT_FALSE(service->GetCharacteristic(removed_char));
- EXPECT_EQ(2u, service->GetCharacteristics().size());
- removed_char = service->GetCharacteristics()[0]->GetIdentifier();
- SimulateGattCharacteristicRemoved(service,
- service->GetCharacteristic(removed_char));
- EXPECT_EQ(3, observer.gatt_characteristic_removed_count());
- EXPECT_FALSE(service->GetCharacteristic(removed_char));
- EXPECT_EQ(1u, service->GetCharacteristics().size());
- removed_char = service->GetCharacteristics()[0]->GetIdentifier();
- SimulateGattCharacteristicRemoved(service,
- service->GetCharacteristic(removed_char));
- EXPECT_EQ(4, observer.gatt_characteristic_removed_count());
- EXPECT_FALSE(service->GetCharacteristic(removed_char));
- EXPECT_EQ(0u, service->GetCharacteristics().size());
- }
- #if BUILDFLAG(IS_MAC)
- #define MAYBE_SimulateGattServiceRemove SimulateGattServiceRemove
- #else
- #define MAYBE_SimulateGattServiceRemove DISABLED_SimulateGattServiceRemove
- #endif
- #if BUILDFLAG(IS_WIN)
- TEST_P(BluetoothRemoteGattServiceTestWinrt, SimulateGattServiceRemove) {
- #else
- TEST_F(BluetoothRemoteGattServiceTest, MAYBE_SimulateGattServiceRemove) {
- #endif
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(3);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- SimulateGattConnection(device);
- base::RunLoop().RunUntilIdle();
- TestBluetoothAdapterObserver observer(adapter_);
- // Simulate two primary GATT services.
- SimulateGattServicesDiscovered(
- device,
- std::vector<std::string>({kTestUUIDGenericAccess, kTestUUIDHeartRate}));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, device->GetGattServices().size());
- // Simulate remove of a primary service.
- BluetoothRemoteGattService* service1 = device->GetGattServices()[0];
- BluetoothRemoteGattService* service2 = device->GetGattServices()[1];
- std::string removed_service = service1->GetIdentifier();
- SimulateGattServiceRemoved(device->GetGattService(removed_service));
- base::RunLoop().RunUntilIdle();
- #if BUILDFLAG(IS_WIN)
- if (!UsesNewBleImplementation()) {
- // The GattServicesRemoved event is not implemented for WinRT.
- EXPECT_EQ(1, observer.gatt_service_removed_count());
- }
- #endif // BUILDFLAG(IS_WIN)
- EXPECT_EQ(1u, device->GetGattServices().size());
- EXPECT_FALSE(device->GetGattService(removed_service));
- EXPECT_EQ(device->GetGattServices()[0], service2);
- }
- #if BUILDFLAG(IS_MAC)
- // Tests to receive a services changed notification from macOS, while
- // discovering characteristics. The gatt device should scan again for services
- // and characteristics, before scanning for descriptors. Only after the gatt
- // service changed notification should be sent.
- // Android: This test doesn't apply to Android because there is no services
- // changed event that could arrive during a discovery procedure.
- TEST_F(BluetoothRemoteGattServiceTest,
- SimulateDeviceModificationWhileDiscoveringCharacteristics) {
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(3);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- TestBluetoothAdapterObserver observer(adapter_);
- // Starts first discovery process.
- SimulateGattConnection(device);
- AddServicesToDeviceMac(device, {kTestUUIDHeartRate});
- SimulateDidDiscoverServicesMac(device);
- EXPECT_EQ(1u, device->GetGattServices().size());
- BluetoothRemoteGattService* service = device->GetGattServices()[0];
- std::string characteristic_uuid1 = "11111111-0000-1000-8000-00805f9b34fb";
- AddCharacteristicToServiceMac(service, characteristic_uuid1,
- /* properties */ 0);
- // Now waiting for characteristic discovery.
- // Starts second discovery process.
- SimulateGattServicesChanged(device);
- SimulateDidDiscoverServicesMac(device);
- // Now waiting for the second characteristic discovery.
- // First system call to -[id<CBPeripheralDelegate>
- // peripheral:didDiscoverCharacteristicsForService:error:]
- SimulateDidDiscoverCharacteristicsMac(service);
- EXPECT_EQ(0, observer.gatt_service_changed_count());
- EXPECT_EQ(1u, service->GetCharacteristics().size());
- // Finish discovery process.
- std::string characteristic_uuid2 = "22222222-0000-1000-8000-00805f9b34fb";
- AddCharacteristicToServiceMac(service, characteristic_uuid2,
- /* properties */ 0);
- // Second system call to -[id<CBPeripheralDelegate>
- // peripheral:didDiscoverCharacteristicsForService:error:]
- SimulateDidDiscoverCharacteristicsMac(service);
- EXPECT_EQ(2u, service->GetCharacteristics().size());
- EXPECT_EQ(0, observer.gatt_service_changed_count());
- BluetoothRemoteGattCharacteristic* characteristic1 =
- service->GetCharacteristics()[0];
- BluetoothRemoteGattCharacteristic* characteristic2 =
- service->GetCharacteristics()[1];
- if (characteristic1->GetUUID().canonical_value() == characteristic_uuid2) {
- BluetoothRemoteGattCharacteristic* tmp = characteristic1;
- characteristic1 = characteristic2;
- characteristic2 = tmp;
- }
- EXPECT_EQ(characteristic_uuid1, characteristic1->GetUUID().canonical_value());
- EXPECT_EQ(characteristic_uuid2, characteristic2->GetUUID().canonical_value());
- SimulateDidDiscoverDescriptorsMac(characteristic1);
- SimulateDidDiscoverDescriptorsMac(characteristic2);
- EXPECT_EQ(1, observer.gatt_service_changed_count());
- }
- #endif // BUILDFLAG(IS_MAC)
- #if BUILDFLAG(IS_MAC)
- // Simulates to receive an extra discovery characteristic notifications from
- // macOS. Those notifications should be ignored.
- // Android: This test doesn't apply to Android because there is no services
- // changed event that could arrive during a discovery procedure.
- TEST_F(BluetoothRemoteGattServiceTest, ExtraDidDiscoverServicesCall) {
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(3);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- TestBluetoothAdapterObserver observer(adapter_);
- // Starts first discovery process.
- SimulateGattConnection(device);
- AddServicesToDeviceMac(device, {kTestUUIDHeartRate});
- SimulateDidDiscoverServicesMac(device);
- EXPECT_EQ(1u, device->GetGattServices().size());
- BluetoothRemoteGattService* service = device->GetGattServices()[0];
- std::string characteristic_uuid = "11111111-0000-1000-8000-00805f9b34fb";
- AddCharacteristicToServiceMac(service, characteristic_uuid,
- /* properties */ 0);
- SimulateDidDiscoverCharacteristicsMac(service);
- EXPECT_EQ(1u, service->GetCharacteristics().size());
- BluetoothRemoteGattCharacteristic* characteristic =
- service->GetCharacteristics()[0];
- std::string descriptor_uuid = "22222222-0000-1000-8000-00805f9b34fb";
- AddDescriptorToCharacteristicMac(characteristic, descriptor_uuid);
- SimulateDidDiscoverDescriptorsMac(characteristic);
- EXPECT_EQ(1, observer.gatt_service_changed_count());
- EXPECT_EQ(1u, service->GetCharacteristics().size());
- EXPECT_EQ(1u, characteristic->GetDescriptors().size());
- observer.Reset();
- SimulateDidDiscoverServicesMac(device); // Extra system call.
- SimulateGattServicesChanged(device);
- SimulateDidDiscoverServicesMac(device);
- SimulateDidDiscoverServicesMac(device); // Extra system call.
- SimulateDidDiscoverCharacteristicsMac(service);
- SimulateDidDiscoverServicesMac(device); // Extra system call.
- SimulateDidDiscoverDescriptorsMac(characteristic);
- SimulateDidDiscoverServicesMac(device); // Extra system call.
- EXPECT_EQ(2, observer.device_changed_count());
- }
- #endif // BUILDFLAG(IS_MAC)
- #if BUILDFLAG(IS_MAC)
- // Simulates to receive an extra discovery characteristic notifications from
- // macOS. Those notifications should be ignored.
- // Android: This test doesn't apply to Android because there is no services
- // changed event that could arrive during a discovery procedure.
- TEST_F(BluetoothRemoteGattServiceTest, ExtraDidDiscoverCharacteristicsCall) {
- if (!PlatformSupportsLowEnergy()) {
- LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
- return;
- }
- InitWithFakeAdapter();
- StartLowEnergyDiscoverySession();
- BluetoothDevice* device = SimulateLowEnergyDevice(3);
- device->CreateGattConnection(
- GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
- TestBluetoothAdapterObserver observer(adapter_);
- // Starts first discovery process.
- SimulateGattConnection(device);
- AddServicesToDeviceMac(device, {kTestUUIDHeartRate});
- SimulateDidDiscoverServicesMac(device);
- EXPECT_EQ(1u, device->GetGattServices().size());
- BluetoothRemoteGattService* service = device->GetGattServices()[0];
- std::string characteristic_uuid = "11111111-0000-1000-8000-00805f9b34fb";
- AddCharacteristicToServiceMac(service, characteristic_uuid,
- /* properties */ 0);
- SimulateDidDiscoverCharacteristicsMac(service);
- EXPECT_EQ(1u, service->GetCharacteristics().size());
- BluetoothRemoteGattCharacteristic* characteristic =
- service->GetCharacteristics()[0];
- std::string descriptor_uuid = "22222222-0000-1000-8000-00805f9b34fb";
- AddDescriptorToCharacteristicMac(characteristic, descriptor_uuid);
- SimulateDidDiscoverDescriptorsMac(characteristic);
- EXPECT_EQ(1, observer.gatt_service_changed_count());
- EXPECT_EQ(1u, service->GetCharacteristics().size());
- EXPECT_EQ(1u, characteristic->GetDescriptors().size());
- observer.Reset();
- SimulateDidDiscoverCharacteristicsMac(service); // Extra system call.
- SimulateGattServicesChanged(device);
- SimulateDidDiscoverCharacteristicsMac(service); // Extra system call.
- SimulateDidDiscoverServicesMac(device);
- SimulateDidDiscoverCharacteristicsMac(service);
- SimulateDidDiscoverCharacteristicsMac(service); // Extra system call.
- SimulateDidDiscoverDescriptorsMac(characteristic);
- SimulateDidDiscoverCharacteristicsMac(service); // Extra system call.
- EXPECT_EQ(2, observer.device_changed_count());
- }
- #endif // BUILDFLAG(IS_MAC)
- #if BUILDFLAG(IS_WIN)
- INSTANTIATE_TEST_SUITE_P(All,
- BluetoothRemoteGattServiceTestWinrt,
- ::testing::ValuesIn(kBluetoothTestWinrtParamAll));
- #endif // BUILDFLAG(IS_WIN)
- } // namespace device
|