#include "device/bluetooth/bluetooth_adapter.h"
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <utility>
#include <vector>
#include "base/barrier_closure.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluetooth_gatt_service.h"
#include "device/bluetooth/bluetooth_local_gatt_characteristic.h"
#include "device/bluetooth/bluetooth_local_gatt_descriptor.h"
#include "device/bluetooth/bluetooth_local_gatt_service.h"
#include "device/bluetooth/test/bluetooth_test.h"
#include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "device/bluetooth/test/test_bluetooth_advertisement_observer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_ANDROID)
#include "device/bluetooth/test/bluetooth_test_android.h"
#elif BUILDFLAG(IS_APPLE)
#include "device/bluetooth/test/bluetooth_test_mac.h"
#elif BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#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
#if BUILDFLAG(IS_CHROMEOS)
#include "device/bluetooth/bluetooth_low_energy_scan_filter.h"
#include "device/bluetooth/bluetooth_low_energy_scan_session.h"
#endif
BluetoothDevice;
namespace device {
void AddDeviceFilterWithUUID(BluetoothDiscoveryFilter* filter,
BluetoothUUID uuid) { … }
namespace {
class TestBluetoothAdapter final : public BluetoothAdapter { … };
class TestPairingDelegate : public BluetoothDevice::PairingDelegate { … };
bool ServiceSetsEqual(
std::vector<BluetoothLocalGattService*> services,
std::initializer_list<BluetoothLocalGattService*> services_to_check) { … }
}
class BluetoothAdapterTest : public testing::Test { … };
TEST_F(BluetoothAdapterTest, NoDefaultPairingDelegate) { … }
TEST_F(BluetoothAdapterTest, OneDefaultPairingDelegate) { … }
TEST_F(BluetoothAdapterTest, SamePriorityDelegates) { … }
TEST_F(BluetoothAdapterTest, HighestPriorityDelegate) { … }
TEST_F(BluetoothAdapterTest, UnregisterDelegate) { … }
TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterEmpty) { … }
TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterRegular) { … }
TEST_F(BluetoothAdapterTest, TestQueueingLogic) { … }
TEST_F(BluetoothAdapterTest, ShortCircuitUpdateTest) { … }
TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterRssi) { … }
TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterTransport) { … }
TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterAllFields) { … }
TEST_F(BluetoothAdapterTest, StartDiscoverySession_Destroy) { … }
TEST_F(BluetoothAdapterTest, StartDiscoverySessionError_Destroy) { … }
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_ConstructDefaultAdapter …
#else
#define MAYBE_ConstructDefaultAdapter …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, ConstructDefaultAdapter) {
#else
TEST_F(BluetoothTest, MAYBE_ConstructDefaultAdapter) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ConstructWithoutDefaultAdapter …
#else
#define MAYBE_ConstructWithoutDefaultAdapter …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, ConstructWithoutDefaultAdapter) {
#else
TEST_F(BluetoothTest, MAYBE_ConstructWithoutDefaultAdapter) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ConstructFakeAdapter …
#else
#define MAYBE_ConstructFakeAdapter …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, ConstructFakeAdapter) {
#else
TEST_F(BluetoothTest, MAYBE_ConstructFakeAdapter) { … }
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, ConstructFakeAdapterWithoutRadio) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitFakeAdapterWithoutRadio();
EXPECT_EQ(adapter_->GetAddress(), kTestAdapterAddress);
EXPECT_EQ(adapter_->GetName(), kTestAdapterName);
EXPECT_TRUE(adapter_->IsPresent());
EXPECT_FALSE(adapter_->CanPower());
EXPECT_FALSE(adapter_->IsPowered());
EXPECT_FALSE(adapter_->IsDiscoverable());
EXPECT_FALSE(adapter_->IsDiscovering());
}
TEST_P(BluetoothTestWinrt, ConstructFakeAdapterWithoutPowerControl) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitFakeAdapterWithRadioAccessDenied();
EXPECT_EQ(adapter_->GetAddress(), kTestAdapterAddress);
EXPECT_EQ(adapter_->GetName(), kTestAdapterName);
EXPECT_TRUE(adapter_->IsPresent());
EXPECT_FALSE(adapter_->CanPower());
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_FALSE(adapter_->IsDiscoverable());
EXPECT_FALSE(adapter_->IsDiscovering());
}
#endif
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_DiscoverySession …
#else
#define MAYBE_DiscoverySession …
#endif
TEST_F(BluetoothTest, MAYBE_DiscoverySession) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(BluetoothTest, AdapterIllegalStateBeforeStartScan) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
ForceIllegalStateException();
StartLowEnergyDiscoverySessionExpectedToFail();
EXPECT_EQ(0, callback_count_);
EXPECT_EQ(1, error_callback_count_);
EXPECT_FALSE(adapter_->IsDiscovering());
}
#endif
#if BUILDFLAG(IS_ANDROID)
TEST_F(BluetoothTest, AdapterIllegalStateBeforeStopScan) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
EXPECT_EQ(1, callback_count_);
EXPECT_EQ(0, error_callback_count_);
EXPECT_TRUE(adapter_->IsDiscovering());
ForceIllegalStateException();
discovery_sessions_[0]->Stop(GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
EXPECT_FALSE(adapter_->IsDiscovering());
}
#endif
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_NoPermissions …
#else
#define MAYBE_NoPermissions …
#endif
TEST_F(BluetoothTest, MAYBE_NoPermissions) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(BluetoothTest, NoLocationServices) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
SimulateLocationServicesOff();
StartLowEnergyDiscoverySessionExpectedToFail();
EXPECT_EQ(0, callback_count_);
EXPECT_EQ(1, error_callback_count_);
}
#endif
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DiscoverLowEnergyDevice …
#else
#define MAYBE_DiscoverLowEnergyDevice …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverLowEnergyDevice) {
#else
TEST_F(BluetoothTest, MAYBE_DiscoverLowEnergyDevice) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DiscoverLowEnergyDeviceTwice …
#else
#define MAYBE_DiscoverLowEnergyDeviceTwice …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverLowEnergyDeviceTwice) {
#else
TEST_F(BluetoothTest, MAYBE_DiscoverLowEnergyDeviceTwice) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DiscoverLowEnergyDeviceWithUpdatedUUIDs …
#else
#define MAYBE_DiscoverLowEnergyDeviceWithUpdatedUUIDs …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverLowEnergyDeviceWithUpdatedUUIDs) {
#else
TEST_F(BluetoothTest, MAYBE_DiscoverLowEnergyDeviceWithUpdatedUUIDs) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DiscoverMultipleLowEnergyDevices …
#else
#define MAYBE_DiscoverMultipleLowEnergyDevices …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverMultipleLowEnergyDevices) {
#else
TEST_F(BluetoothTest, MAYBE_DiscoverMultipleLowEnergyDevices) { … }
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, SimulateAdapterPoweredOffAndOn) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
ASSERT_TRUE(adapter_->IsPresent());
ASSERT_TRUE(adapter_->IsPowered());
EXPECT_EQ(0, observer.powered_changed_count());
SimulateAdapterPoweredOff();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(adapter_->IsPowered());
EXPECT_EQ(1, observer.powered_changed_count());
EXPECT_FALSE(observer.last_powered());
SimulateAdapterPoweredOn();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_EQ(2, observer.powered_changed_count());
EXPECT_TRUE(observer.last_powered());
}
TEST_P(BluetoothTestWinrt, SimulateDuplicateStateChanged) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
ASSERT_TRUE(adapter_->IsPresent());
ASSERT_TRUE(adapter_->IsPowered());
EXPECT_EQ(0, observer.powered_changed_count());
SimulateSpuriousRadioStateChangedEvent();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_EQ(0, observer.powered_changed_count());
SimulateAdapterPoweredOff();
SimulateSpuriousRadioStateChangedEvent();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(adapter_->IsPowered());
EXPECT_EQ(1, observer.powered_changed_count());
EXPECT_FALSE(observer.last_powered());
SimulateAdapterPoweredOn();
SimulateSpuriousRadioStateChangedEvent();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_EQ(2, observer.powered_changed_count());
EXPECT_TRUE(observer.last_powered());
}
TEST_P(BluetoothTestWinrt, SimulateAdapterPoweredOnAndOffWithoutRadio) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitFakeAdapterWithoutRadio();
TestBluetoothAdapterObserver observer(adapter_);
ASSERT_TRUE(adapter_->IsPresent());
ASSERT_FALSE(adapter_->IsPowered());
EXPECT_EQ(0, observer.powered_changed_count());
SimulateAdapterPoweredOn();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_EQ(1, observer.powered_changed_count());
EXPECT_TRUE(observer.last_powered());
SimulateAdapterPoweredOff();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(adapter_->IsPowered());
EXPECT_EQ(2, observer.powered_changed_count());
EXPECT_FALSE(observer.last_powered());
}
TEST_P(BluetoothTestWinrt, SimulateAdapterPowerFailure) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
ASSERT_TRUE(adapter_->IsPresent());
ASSERT_TRUE(adapter_->IsPowered());
adapter_->SetPowered(false, GetCallback(Call::NOT_EXPECTED),
GetErrorCallback(Call::EXPECTED));
SimulateAdapterPowerFailure();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(adapter_->IsPowered());
}
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter) {
#else
#if BUILDFLAG(IS_IOS)
#define MAYBE_TogglePowerFakeAdapter …
#else
#define MAYBE_TogglePowerFakeAdapter …
#endif
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_TogglePowerFakeAdapter_Twice …
#else
#define MAYBE_TogglePowerFakeAdapter_Twice …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter_Twice) {
#else
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter_Twice) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_TogglePowerFakeAdapter_WithinCallback_On_Off …
#else
#define MAYBE_TogglePowerFakeAdapter_WithinCallback_On_Off …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter_WithinCallback_On_Off) {
#else
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter_WithinCallback_On_Off) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_TogglePowerFakeAdapter_WithinCallback_Off_On …
#else
#define MAYBE_TogglePowerFakeAdapter_WithinCallback_Off_On …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter_WithinCallback_Off_On) {
#else
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter_WithinCallback_Off_On) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_TogglePowerFakeAdapter_DestroyWithPending …
#else
#define MAYBE_TogglePowerFakeAdapter_DestroyWithPending …
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter_DestroyWithPending) {
#else
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter_DestroyWithPending) { … }
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_TogglePowerBeforeScan …
#else
#define MAYBE_TogglePowerBeforeScan …
#endif
TEST_F(BluetoothTest, MAYBE_TogglePowerBeforeScan) { … }
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverySessionFailure) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
EXPECT_FALSE(adapter_->IsDiscovering());
StartLowEnergyDiscoverySession();
EXPECT_EQ(1, callback_count_);
EXPECT_EQ(0, error_callback_count_);
EXPECT_TRUE(adapter_->IsDiscovering());
EXPECT_EQ(1, observer.discovering_changed_count());
EXPECT_TRUE(observer.last_discovering());
ASSERT_EQ((size_t)1, discovery_sessions_.size());
EXPECT_TRUE(discovery_sessions_[0]->IsActive());
SimulateLowEnergyDiscoveryFailure();
EXPECT_FALSE(adapter_->IsDiscovering());
EXPECT_FALSE(discovery_sessions_[0]->IsActive());
EXPECT_EQ(2, observer.discovering_changed_count());
EXPECT_FALSE(observer.last_discovering());
}
#endif
#if BUILDFLAG(IS_MAC)
#define MAYBE_TurnOffAdapterWithConnectedDevice …
#else
#define MAYBE_TurnOffAdapterWithConnectedDevice …
#endif
TEST_F(BluetoothTest, MAYBE_TurnOffAdapterWithConnectedDevice) { … }
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, RegisterAdvertisement) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
advertisement_data->set_manufacturer_data(
BluetoothAdvertisement::ManufacturerData());
InitWithFakeAdapter();
adapter_->RegisterAdvertisement(
std::move(advertisement_data),
GetCreateAdvertisementCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
ASSERT_FALSE(pending_advertisements.empty());
SimulateAdvertisementStarted(pending_advertisements[0]);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}
TEST_P(BluetoothTestWinrt, FailRegisterAdvertisement) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
advertisement_data->set_manufacturer_data(
BluetoothAdvertisement::ManufacturerData());
InitWithFakeAdapter();
adapter_->RegisterAdvertisement(
std::move(advertisement_data),
GetCreateAdvertisementCallback(Call::NOT_EXPECTED),
GetAdvertisementErrorCallback(Call::EXPECTED));
auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
ASSERT_FALSE(pending_advertisements.empty());
SimulateAdvertisementError(pending_advertisements[0],
BluetoothAdvertisement::ERROR_ADAPTER_POWERED_OFF);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(BluetoothAdvertisement::ERROR_ADAPTER_POWERED_OFF,
last_advertisement_error_code_);
EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}
TEST_P(BluetoothTestWinrt, RegisterAndUnregisterAdvertisement) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
advertisement_data->set_manufacturer_data(
BluetoothAdvertisement::ManufacturerData());
InitWithFakeAdapter();
adapter_->RegisterAdvertisement(
std::move(advertisement_data),
GetCreateAdvertisementCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
ASSERT_FALSE(pending_advertisements.empty());
auto* advertisement = pending_advertisements[0];
SimulateAdvertisementStarted(advertisement);
base::RunLoop().RunUntilIdle();
TestBluetoothAdvertisementObserver observer(advertisement);
advertisement->Unregister(GetCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
SimulateAdvertisementStopped(advertisement);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(observer.released());
EXPECT_EQ(1u, observer.released_count());
EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}
TEST_P(BluetoothTestWinrt, FailUnregisterAdvertisement) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
advertisement_data->set_manufacturer_data(
BluetoothAdvertisement::ManufacturerData());
InitWithFakeAdapter();
adapter_->RegisterAdvertisement(
std::move(advertisement_data),
GetCreateAdvertisementCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
ASSERT_FALSE(pending_advertisements.empty());
auto* advertisement = pending_advertisements[0];
SimulateAdvertisementStarted(advertisement);
base::RunLoop().RunUntilIdle();
TestBluetoothAdvertisementObserver observer(advertisement);
advertisement->Unregister(GetCallback(Call::NOT_EXPECTED),
GetAdvertisementErrorCallback(Call::EXPECTED));
SimulateAdvertisementError(advertisement,
BluetoothAdvertisement::ERROR_RESET_ADVERTISING);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(observer.released());
EXPECT_EQ(0u, observer.released_count());
EXPECT_EQ(BluetoothAdvertisement::ERROR_RESET_ADVERTISING,
last_advertisement_error_code_);
EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}
TEST_P(BluetoothTestWinrt, RegisterAdvertisementWithInvalidData) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
advertisement_data->set_service_data(BluetoothAdvertisement::ServiceData());
InitWithFakeAdapter();
adapter_->RegisterAdvertisement(
std::move(advertisement_data),
GetCreateAdvertisementCallback(Call::NOT_EXPECTED),
GetAdvertisementErrorCallback(Call::EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(BluetoothAdvertisement::ERROR_STARTING_ADVERTISEMENT,
last_advertisement_error_code_);
EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}
TEST_P(BluetoothTestWinrt, RegisterMultipleAdvertisements) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
constexpr size_t kNumAdvertisements = 10u;
for (size_t i = 0; i < kNumAdvertisements; ++i) {
auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
advertisement_data->set_manufacturer_data(
BluetoothAdvertisement::ManufacturerData());
adapter_->RegisterAdvertisement(
std::move(advertisement_data),
GetCreateAdvertisementCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
}
base::RunLoop().RunUntilIdle();
auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
ASSERT_EQ(kNumAdvertisements, pending_advertisements.size());
for (size_t i = 0; i < kNumAdvertisements; ++i)
SimulateAdvertisementStarted(pending_advertisements[i]);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}
TEST_P(BluetoothTestWinrt, UnregisterAdvertisementWhilePendingUnregister) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
advertisement_data->set_manufacturer_data(
BluetoothAdvertisement::ManufacturerData());
adapter_->RegisterAdvertisement(
std::move(advertisement_data),
GetCreateAdvertisementCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
ASSERT_EQ(1u, pending_advertisements.size());
auto* advertisement = pending_advertisements[0];
SimulateAdvertisementStarted(advertisement);
base::RunLoop().RunUntilIdle();
TestBluetoothAdvertisementObserver observer(advertisement);
advertisement->Unregister(GetCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
advertisement->Unregister(GetCallback(Call::NOT_EXPECTED),
GetAdvertisementErrorCallback(Call::EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(observer.released());
EXPECT_EQ(0u, observer.released_count());
EXPECT_EQ(BluetoothAdvertisement::ERROR_RESET_ADVERTISING,
last_advertisement_error_code_);
SimulateAdvertisementStopped(advertisement);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(observer.released());
EXPECT_EQ(1u, observer.released_count());
EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}
TEST_P(BluetoothTestWinrt, DoubleUnregisterAdvertisement) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
advertisement_data->set_manufacturer_data(
BluetoothAdvertisement::ManufacturerData());
adapter_->RegisterAdvertisement(
std::move(advertisement_data),
GetCreateAdvertisementCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
ASSERT_EQ(1u, pending_advertisements.size());
auto* advertisement = pending_advertisements[0];
SimulateAdvertisementStarted(advertisement);
base::RunLoop().RunUntilIdle();
TestBluetoothAdvertisementObserver observer(advertisement);
advertisement->Unregister(GetCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
SimulateAdvertisementStopped(advertisement);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(observer.released());
EXPECT_EQ(1u, observer.released_count());
advertisement->Unregister(GetCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
SimulateAdvertisementStopped(advertisement);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(observer.released());
EXPECT_EQ(1u, observer.released_count());
EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}
TEST_P(BluetoothTestWinrt, SimulateAdvertisementStoppedByOS) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
advertisement_data->set_manufacturer_data(
BluetoothAdvertisement::ManufacturerData());
adapter_->RegisterAdvertisement(
std::move(advertisement_data),
GetCreateAdvertisementCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
ASSERT_EQ(1u, pending_advertisements.size());
auto* advertisement = pending_advertisements[0];
SimulateAdvertisementStarted(advertisement);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
TestBluetoothAdvertisementObserver observer(advertisement);
SimulateAdvertisementStopped(advertisement);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(observer.released());
EXPECT_EQ(1u, observer.released_count());
advertisement->Unregister(GetCallback(Call::EXPECTED),
GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(observer.released());
EXPECT_EQ(1u, observer.released_count());
}
#endif
#if (BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) && \
!defined(USE_CAST_BLUETOOTH_ADAPTER)
#define MAYBE_RegisterLocalGattServices …
#else
#define MAYBE_RegisterLocalGattServices …
#endif
TEST_F(BluetoothTest, MAYBE_RegisterLocalGattServices) { … }
#if (BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) && \
!defined(USE_CAST_BLUETOOTH_ADAPTER)
#define MAYBE_RegisterMultipleServices …
#else
#define MAYBE_RegisterMultipleServices …
#endif
TEST_F(BluetoothTest, MAYBE_RegisterMultipleServices) { … }
#if (BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) && \
!defined(USE_CAST_BLUETOOTH_ADAPTER)
#define MAYBE_DeleteServices …
#else
#define MAYBE_DeleteServices …
#endif
TEST_F(BluetoothTest, MAYBE_DeleteServices) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_EnsureUpdatedTimestamps …
#else
#define MAYBE_EnsureUpdatedTimestamps …
#endif
TEST_F(BluetoothTest, MAYBE_EnsureUpdatedTimestamps) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoveOutdatedDevices …
#else
#define MAYBE_RemoveOutdatedDevices …
#endif
TEST_F(BluetoothTest, MAYBE_RemoveOutdatedDevices) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoveOutdatedDeviceGattConnect …
#else
#define MAYBE_RemoveOutdatedDeviceGattConnect …
#endif
TEST_F(BluetoothTest, MAYBE_RemoveOutdatedDeviceGattConnect) { … }
#if BUILDFLAG(IS_APPLE)
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceWithNoFilter) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
discovery_filter);
EXPECT_EQ(2u, result.size());
for (const auto& pair : result) {
EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
EXPECT_TRUE(pair.second.empty());
}
EXPECT_EQ(BluetoothDevice::UUIDSet({BluetoothUUID(kTestUUIDGenericAccess)}),
RetrieveConnectedPeripheralServiceUUIDs());
EXPECT_EQ(2, observer.device_added_count());
EXPECT_EQ(2u, adapter_->GetDevices().size());
}
#endif
#if BUILDFLAG(IS_APPLE)
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceWithFilter) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
BluetoothUUID heart_service_uuid = BluetoothUUID(kTestUUIDHeartRate);
AddDeviceFilterWithUUID(&discovery_filter, heart_service_uuid);
std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
discovery_filter);
EXPECT_EQ(1u, result.size());
for (const auto& pair : result) {
EXPECT_EQ(kTestDeviceAddress2, pair.first->GetAddress());
EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}), pair.second);
}
EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}),
RetrieveConnectedPeripheralServiceUUIDs());
EXPECT_EQ(1, observer.device_added_count());
EXPECT_EQ(1u, adapter_->GetDevices().size());
}
#endif
#if BUILDFLAG(IS_APPLE)
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceWithWrongFilter) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
AddDeviceFilterWithUUID(&discovery_filter, BluetoothUUID(kTestUUIDLinkLoss));
std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
discovery_filter);
EXPECT_TRUE(result.empty());
EXPECT_EQ(
BluetoothDevice::UUIDSet({device::BluetoothUUID(kTestUUIDLinkLoss)}),
RetrieveConnectedPeripheralServiceUUIDs());
EXPECT_EQ(0, observer.device_added_count());
EXPECT_EQ(0u, adapter_->GetDevices().size());
}
#endif
#if BUILDFLAG(IS_APPLE)
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceWithTwoFilters) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
BluetoothUUID heart_service_uuid = BluetoothUUID(kTestUUIDHeartRate);
AddDeviceFilterWithUUID(&discovery_filter, heart_service_uuid);
BluetoothUUID generic_service_uuid = BluetoothUUID(kTestUUIDGenericAccess);
AddDeviceFilterWithUUID(&discovery_filter, generic_service_uuid);
std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
discovery_filter);
EXPECT_EQ(2u, result.size());
for (const auto& pair : result) {
EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
if (pair.first->GetAddress() == kTestDeviceAddress2) {
EXPECT_EQ(
BluetoothDevice::UUIDSet({heart_service_uuid, generic_service_uuid}),
pair.second);
} else if (pair.first->GetAddress() == kTestDeviceAddress1) {
EXPECT_EQ(BluetoothDevice::UUIDSet({generic_service_uuid}), pair.second);
} else {
EXPECT_TRUE(false);
}
}
EXPECT_EQ(
BluetoothDevice::UUIDSet({generic_service_uuid, heart_service_uuid}),
RetrieveConnectedPeripheralServiceUUIDs());
EXPECT_EQ(2, observer.device_added_count());
EXPECT_EQ(2u, adapter_->GetDevices().size());
}
#endif
#if BUILDFLAG(IS_APPLE)
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceTwice) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
BluetoothUUID heart_service_uuid = BluetoothUUID(kTestUUIDHeartRate);
AddDeviceFilterWithUUID(&discovery_filter, heart_service_uuid);
std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
discovery_filter);
EXPECT_EQ(1u, result.size());
for (const auto& pair : result) {
EXPECT_EQ(kTestDeviceAddress2, pair.first->GetAddress());
EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}), pair.second);
}
EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}),
RetrieveConnectedPeripheralServiceUUIDs());
EXPECT_EQ(1, observer.device_added_count());
EXPECT_EQ(1u, adapter_->GetDevices().size());
observer.Reset();
ResetRetrieveConnectedPeripheralServiceUUIDs();
result = adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
discovery_filter);
EXPECT_EQ(1u, result.size());
for (const auto& pair : result) {
EXPECT_EQ(kTestDeviceAddress2, pair.first->GetAddress());
EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}), pair.second);
}
EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}),
RetrieveConnectedPeripheralServiceUUIDs());
EXPECT_EQ(0, observer.device_added_count());
EXPECT_EQ(1u, adapter_->GetDevices().size());
}
#endif
#if BUILDFLAG(IS_WIN)
INSTANTIATE_TEST_SUITE_P(All,
BluetoothTestWinrt,
::testing::ValuesIn(kBluetoothTestWinrtParam));
#endif
}