#include "device/bluetooth/bluetooth_device.h"
#include <stddef.h>
#include <array>
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/bind.h"
#include "base/test/test_future.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_remote_gatt_service.h"
#include "device/bluetooth/public/cpp/bluetooth_address.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "device/bluetooth/test/mock_bluetooth_device.h"
#include "device/bluetooth/test/mock_pairing_delegate.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_APPLE)
#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"
#elif BUILDFLAG(IS_OHOS)
#include "arkweb/chromium_ext/device/bluetooth/test/bluetooth_test_ohos.h"
#endif
namespace device {
namespace {
using ::testing::_;
using ::testing::Return;
using ::testing::StrictMock;
int8_t ToInt8(BluetoothTest::TestRSSI rssi) {
return static_cast<int8_t>(rssi);
}
int8_t ToInt8(BluetoothTest::TestTxPower tx_power) {
return static_cast<int8_t>(tx_power);
}
#if BUILDFLAG(IS_WIN)
void ScheduleAsynchronousCancelPairing(BluetoothDevice* device) {
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, base::BindOnce(&BluetoothDevice::CancelPairing,
base::Unretained(device)));
}
void ScheduleAsynchronousRejectPairing(BluetoothDevice* device) {
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, base::BindOnce(&BluetoothDevice::RejectPairing,
base::Unretained(device)));
}
#endif
}
using UUIDSet = BluetoothDevice::UUIDSet;
using ServiceDataMap = BluetoothDevice::ServiceDataMap;
using ManufacturerDataMap = BluetoothDevice::ManufacturerDataMap;
TEST(BluetoothDeviceTest, CanonicalizeAddressFormat_AcceptsAllValidFormats) {
const auto kValidFormats = std::to_array<const char*>({
"1A:2B:3C:4D:5E:6F",
"1a:2B:3c:4D:5e:6F",
"1a:2b:3c:4d:5e:6f",
"1A-2B-3C-4D-5E-6F",
"1a-2B-3c-4D-5e-6F",
"1a-2b-3c-4d-5e-6f",
"1A2B3C4D5E6F",
"1a2B3c4D5e6F",
"1a2b3c4d5e6f",
});
for (size_t i = 0; i < std::size(kValidFormats); ++i) {
SCOPED_TRACE(std::string("Input format: '") + kValidFormats[i] + "'");
EXPECT_EQ("1A:2B:3C:4D:5E:6F",
CanonicalizeBluetoothAddress(kValidFormats[i]));
std::array<uint8_t, 6> parsed;
EXPECT_TRUE(ParseBluetoothAddress(kValidFormats[i], parsed));
EXPECT_EQ("\x1a\x2b\x3c\x4d\x5e\x6f",
std::string(parsed.begin(), parsed.end()));
}
}
TEST(BluetoothDeviceTest,
CanonicalizeAddressFormat_AcceptsAllValidFormatsBytes) {
std::array<uint8_t, 6> kValidBytes = {12, 14, 76, 200, 5, 8};
EXPECT_EQ("0C:0E:4C:C8:05:08", CanonicalizeBluetoothAddress(kValidBytes));
}
TEST(BluetoothDeviceTest, CanonicalizeAddressFormat_RejectsInvalidFormats) {
const auto kInvalidFormats = std::to_array<const char*>({
"",
"1A:2B:3C:4D:5E",
"1A:2B:3C:4D:5E:6F:70",
"1A:2B:3C:4D:5E6F",
"1A:2B-3C:4D-5E:6F",
"1A:2B:3C:4D:5E:6X",
"1:A2:B3:C4:D5:E6F",
"1A|2B|3C|4D|5E|6F",
});
for (size_t i = 0; i < std::size(kInvalidFormats); ++i) {
SCOPED_TRACE(std::string("Input format: '") + kInvalidFormats[i] + "'");
EXPECT_EQ(std::string(), CanonicalizeBluetoothAddress(kInvalidFormats[i]));
std::array<uint8_t, 6> parsed;
EXPECT_FALSE(ParseBluetoothAddress(kInvalidFormats[i], parsed));
}
}
TEST(BluetoothDeviceTest, GattConnectionErrorReentrancy) {
constexpr char kTestDeviceAddress[] = "00:11:22:33:44:55";
auto adapter = base::MakeRefCounted<MockBluetoothAdapter>();
MockBluetoothDevice device(adapter.get(),
0, "Test Device",
kTestDeviceAddress,
false,
false);
EXPECT_CALL(*adapter, GetDevice(kTestDeviceAddress))
.WillRepeatedly(Return(&device));
EXPECT_CALL(device, CreateGattConnection(_, _))
.Times(2)
.WillRepeatedly([&](BluetoothDevice::GattConnectionCallback callback,
std::optional<BluetoothUUID> service_uuid) {
device.BluetoothDevice::CreateGattConnection(std::move(callback),
service_uuid);
});
EXPECT_CALL(device, CreateGattConnectionImpl(_))
.WillOnce([&](std::optional<BluetoothUUID> service_uuid) {
device.DidConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
});
EXPECT_CALL(device, IsGattConnected())
.WillOnce(Return(false))
.WillOnce(Return(true));
device.CreateGattConnection(
base::BindLambdaForTesting(
[&](std::unique_ptr<BluetoothGattConnection> connection,
std::optional<BluetoothDevice::ConnectErrorCode> error_code) {
EXPECT_FALSE(connection);
EXPECT_EQ(error_code,
BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
device.CreateGattConnection(
base::BindLambdaForTesting(
[&](std::unique_ptr<BluetoothGattConnection> connection,
std::optional<BluetoothDevice::ConnectErrorCode>
error_code) {
EXPECT_TRUE(connection);
EXPECT_FALSE(error_code);
}),
std::nullopt);
}),
std::nullopt);
}
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DeviceIsPaired) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
EXPECT_FALSE(device->IsPaired());
ASSERT_TRUE(ConnectGatt(device));
SimulateDevicePaired(device, true);
EXPECT_TRUE(device->IsPaired());
SimulateDevicePaired(device, false);
EXPECT_FALSE(device->IsPaired());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestPinCodeCorrect) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
SimulatePairingPinCode(device, "123456");
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, RequestPinCode)
.WillOnce([](BluetoothDevice* device) {
ASSERT_NE(device, nullptr);
device->SetPinCode("123456");
});
base::RunLoop run_loop;
device->Pair(
&pairing_delegate,
base::BindLambdaForTesting(
[&](std::optional<BluetoothDevice::ConnectErrorCode> error_code) {
EXPECT_FALSE(error_code.has_value());
run_loop.Quit();
}));
run_loop.Run();
EXPECT_TRUE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestPinCodeWrong) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
SimulatePairingPinCode(device, "123456");
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, RequestPinCode)
.WillOnce([](BluetoothDevice* device) {
ASSERT_NE(device, nullptr);
device->SetPinCode("000000");
});
base::RunLoop run_loop;
device->Pair(
&pairing_delegate,
base::BindLambdaForTesting(
[&](std::optional<BluetoothDevice::ConnectErrorCode> error_code) {
EXPECT_EQ(BluetoothDevice::ERROR_FAILED, error_code);
run_loop.Quit();
}));
run_loop.Run();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestPinCodeRejectPairing) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
SimulatePairingPinCode(device, "123456");
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, RequestPinCode)
.WillOnce([](BluetoothDevice* device) {
ASSERT_NE(device, nullptr);
ScheduleAsynchronousRejectPairing(device);
});
base::RunLoop run_loop;
device->Pair(
&pairing_delegate,
base::BindLambdaForTesting(
[&](std::optional<BluetoothDevice::ConnectErrorCode> error_code) {
EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, error_code);
run_loop.Quit();
}));
run_loop.Run();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestPinCodeCancelPairing) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
SimulatePairingPinCode(device, "123456");
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, RequestPinCode)
.WillOnce([](BluetoothDevice* device) {
ASSERT_NE(device, nullptr);
ScheduleAsynchronousCancelPairing(device);
});
base::RunLoop run_loop;
device->Pair(
&pairing_delegate,
base::BindLambdaForTesting(
[&](std::optional<BluetoothDevice::ConnectErrorCode> error_code) {
EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, error_code);
run_loop.Quit();
}));
run_loop.Run();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestConfirmOnlyAccept) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
SimulateConfirmOnly(device);
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, AuthorizePairing)
.WillOnce([](BluetoothDevice* device) {
ASSERT_NE(device, nullptr);
device->ConfirmPairing();
});
base::test::TestFuture<std::optional<BluetoothDevice::ConnectErrorCode>>
error_code_future;
device->Pair(&pairing_delegate, error_code_future.GetCallback());
EXPECT_FALSE(error_code_future.Get().has_value());
EXPECT_TRUE(device->IsPaired());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestConfirmOnlyCancel) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
SimulateConfirmOnly(device);
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, AuthorizePairing)
.WillOnce([](BluetoothDevice* device) {
ASSERT_NE(device, nullptr);
ScheduleAsynchronousCancelPairing(device);
});
base::test::TestFuture<std::optional<BluetoothDevice::ConnectErrorCode>>
error_code_future;
device->Pair(&pairing_delegate, error_code_future.GetCallback());
EXPECT_EQ(error_code_future.Get(), BluetoothDevice::ERROR_AUTH_CANCELED);
EXPECT_FALSE(device->IsPaired());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestConfirmPinAccept) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
SimulateDisplayPin(device, "123456");
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, ConfirmPasskey)
.WillOnce([](BluetoothDevice* device, uint32_t passkey) {
ASSERT_NE(device, nullptr);
ASSERT_EQ(passkey, 123456u);
device->ConfirmPairing();
});
base::test::TestFuture<std::optional<BluetoothDevice::ConnectErrorCode>>
error_code_future;
device->Pair(&pairing_delegate, error_code_future.GetCallback());
EXPECT_FALSE(error_code_future.Get().has_value());
EXPECT_TRUE(device->IsPaired());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestConfirmPinCancel) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
SimulateDisplayPin(device, "123456");
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, ConfirmPasskey)
.WillOnce([](BluetoothDevice* device, uint32_t passkey) {
ASSERT_NE(device, nullptr);
ASSERT_EQ(passkey, 123456u);
ScheduleAsynchronousCancelPairing(device);
});
base::test::TestFuture<std::optional<BluetoothDevice::ConnectErrorCode>>
error_code_future;
device->Pair(&pairing_delegate, error_code_future.GetCallback());
EXPECT_EQ(error_code_future.Get(), BluetoothDevice::ERROR_AUTH_CANCELED);
EXPECT_FALSE(device->IsPaired());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestConfirmPinLeadingZeroAccept) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
SimulateDisplayPin(device, "000001");
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, ConfirmPasskey)
.WillOnce([](BluetoothDevice* device, uint32_t passkey) {
ASSERT_NE(device, nullptr);
ASSERT_EQ(passkey, 1u);
device->ConfirmPairing();
});
base::test::TestFuture<std::optional<BluetoothDevice::ConnectErrorCode>>
error_code_future;
device->Pair(&pairing_delegate, error_code_future.GetCallback());
EXPECT_FALSE(error_code_future.Get().has_value());
EXPECT_TRUE(device->IsPaired());
}
TEST_P(BluetoothTestWinrt, DevicePairRequestConfirmPinInvalid) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(device->IsPaired());
SimulateDisplayPin(device, "1000000");
StrictMock<MockPairingDelegate> pairing_delegate;
EXPECT_CALL(pairing_delegate, ConfirmPasskey).Times(0);
base::test::TestFuture<std::optional<BluetoothDevice::ConnectErrorCode>>
error_code_future;
device->Pair(&pairing_delegate, error_code_future.GetCallback());
EXPECT_EQ(error_code_future.Get(), BluetoothDevice::ERROR_AUTH_FAILED);
EXPECT_FALSE(device->IsPaired());
}
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, LowEnergyDeviceProperties) {
#else
TEST_F(BluetoothTest, LowEnergyDeviceProperties) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
if (!device) {
return;
}
ASSERT_TRUE(device);
#if !BUILDFLAG(IS_WIN)
EXPECT_EQ(0x1F00u, device->GetBluetoothClass());
#endif
EXPECT_EQ(kTestDeviceAddress1, device->GetAddress());
EXPECT_EQ(BluetoothDevice::VENDOR_ID_UNKNOWN, device->GetVendorIDSource());
EXPECT_EQ(0, device->GetVendorID());
EXPECT_EQ(0, device->GetProductID());
EXPECT_EQ(0, device->GetDeviceID());
EXPECT_EQ(base::UTF8ToUTF16(kTestDeviceName), device->GetNameForDisplay());
EXPECT_FALSE(device->IsPaired());
UUIDSet uuids = device->GetUUIDs();
EXPECT_TRUE(base::Contains(uuids, BluetoothUUID(kTestUUIDGenericAccess)));
EXPECT_TRUE(base::Contains(uuids, BluetoothUUID(kTestUUIDGenericAttribute)));
}
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, LowEnergyDeviceNameDelayed) {
#else
TEST_F(BluetoothTest, DISABLED_LowEnergyDeviceNameDelayed) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
if (!device) {
return;
}
ASSERT_TRUE(device);
EXPECT_TRUE(!device->GetName().has_value() || device->GetName()->empty());
SimulateLowEnergyDevice(1);
EXPECT_EQ(base::UTF8ToUTF16(kTestDeviceName), device->GetNameForDisplay());
}
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, LowEnergyDeviceNoUUIDs) {
#else
TEST_F(BluetoothTest, LowEnergyDeviceNoUUIDs) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
if (!device) {
return;
}
ASSERT_TRUE(device);
UUIDSet uuids = device->GetUUIDs();
EXPECT_EQ(0u, uuids.size());
}
#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || \
BUILDFLAG(IS_ANDROID)
#define MAYBE_GetServiceDataUUIDs_GetServiceDataForUUID \
GetServiceDataUUIDs_GetServiceDataForUUID
#else
#define MAYBE_GetServiceDataUUIDs_GetServiceDataForUUID \
DISABLED_GetServiceDataUUIDs_GetServiceDataForUUID
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GetServiceDataUUIDs_GetServiceDataForUUID) {
#else
TEST_F(BluetoothTest, MAYBE_GetServiceDataUUIDs_GetServiceDataForUUID) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
#if !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
StartLowEnergyDiscoverySession();
#endif
BluetoothDevice* device1 = SimulateLowEnergyDevice(4);
EXPECT_FALSE(device1->GetAdvertisingDataFlags().has_value());
EXPECT_TRUE(device1->GetServiceData().empty());
EXPECT_TRUE(device1->GetServiceDataUUIDs().empty());
EXPECT_TRUE(device1->GetManufacturerData().empty());
BluetoothDevice* device2 = SimulateLowEnergyDevice(1);
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device2->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x04, device2->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(ServiceDataMap({{BluetoothUUID(kTestUUIDHeartRate), {1}}}),
device2->GetServiceData());
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDHeartRate)}),
device2->GetServiceDataUUIDs());
EXPECT_EQ(std::vector<uint8_t>({1}),
*device2->GetServiceDataForUUID(BluetoothUUID(kTestUUIDHeartRate)));
EXPECT_EQ(std::vector<uint8_t>({1, 2, 3, 4}),
*device2->GetManufacturerDataForID(kTestManufacturerId));
SimulateLowEnergyDevice(3);
#if (BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) && \
!defined(USE_CAST_BLUETOOTH_ADAPTER)
EXPECT_EQ(ServiceDataMap({{BluetoothUUID(kTestUUIDHeartRate), {1}}}),
device2->GetServiceData());
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDHeartRate)}),
device2->GetServiceDataUUIDs());
EXPECT_EQ(std::vector<uint8_t>({1}),
*device2->GetServiceDataForUUID(BluetoothUUID(kTestUUIDHeartRate)));
#else
EXPECT_FALSE(device2->GetAdvertisingDataFlags().has_value());
EXPECT_TRUE(device2->GetServiceData().empty());
EXPECT_TRUE(device2->GetServiceDataUUIDs().empty());
EXPECT_TRUE(device2->GetManufacturerData().empty());
EXPECT_EQ(nullptr,
device2->GetServiceDataForUUID(BluetoothUUID(kTestUUIDHeartRate)));
#endif
SimulateLowEnergyDevice(2);
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device2->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x05, device2->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(ServiceDataMap(
{{BluetoothUUID(kTestUUIDHeartRate), std::vector<uint8_t>({})},
{BluetoothUUID(kTestUUIDImmediateAlert), {0, 2}}}),
device2->GetServiceData());
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDHeartRate),
BluetoothUUID(kTestUUIDImmediateAlert)}),
device2->GetServiceDataUUIDs());
EXPECT_EQ(std::vector<uint8_t>({}),
*device2->GetServiceDataForUUID(BluetoothUUID(kTestUUIDHeartRate)));
EXPECT_EQ(std::vector<uint8_t>({}),
*device2->GetManufacturerDataForID(kTestManufacturerId));
EXPECT_EQ(
std::vector<uint8_t>({0, 2}),
*device2->GetServiceDataForUUID(BluetoothUUID(kTestUUIDImmediateAlert)));
#if !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
discovery_sessions_[0]->Stop(GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(adapter_->IsDiscovering());
ASSERT_FALSE(discovery_sessions_[0]->IsActive());
EXPECT_FALSE(device2->GetAdvertisingDataFlags().has_value());
EXPECT_TRUE(device2->GetServiceData().empty());
EXPECT_TRUE(device2->GetServiceDataUUIDs().empty());
EXPECT_EQ(nullptr,
device2->GetServiceDataForUUID(BluetoothUUID(kTestUUIDHeartRate)));
EXPECT_EQ(nullptr, device2->GetServiceDataForUUID(
BluetoothUUID(kTestUUIDImmediateAlert)));
#endif
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_AdvertisementData_Discovery AdvertisementData_Discovery
#else
#define MAYBE_AdvertisementData_Discovery DISABLED_AdvertisementData_Discovery
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, AdvertisementData_Discovery) {
#else
TEST_F(BluetoothTest, MAYBE_AdvertisementData_Discovery) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
EXPECT_EQ(0, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOWEST), device->GetInquiryRSSI().value());
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x04, device->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute)}),
device->GetUUIDs());
EXPECT_EQ(ServiceDataMap({{BluetoothUUID(kTestUUIDHeartRate), {1}}}),
device->GetServiceData());
EXPECT_EQ(ManufacturerDataMap({{kTestManufacturerId, {1, 2, 3, 4}}}),
device->GetManufacturerData());
EXPECT_EQ(ToInt8(TestTxPower::LOWEST), device->GetInquiryTxPower().value());
SimulateLowEnergyDevice(3);
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOW), device->GetInquiryRSSI().value());
EXPECT_FALSE(device->GetAdvertisingDataFlags().has_value());
EXPECT_TRUE(device->GetUUIDs().empty());
EXPECT_TRUE(device->GetServiceData().empty());
EXPECT_TRUE(device->GetManufacturerData().empty());
EXPECT_FALSE(device->GetInquiryTxPower());
SimulateLowEnergyDevice(2);
EXPECT_EQ(2, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOWER), device->GetInquiryRSSI().value());
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x05, device->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDImmediateAlert),
BluetoothUUID(kTestUUIDLinkLoss)}),
device->GetUUIDs());
EXPECT_EQ(ServiceDataMap(
{{BluetoothUUID(kTestUUIDHeartRate), std::vector<uint8_t>({})},
{BluetoothUUID(kTestUUIDImmediateAlert), {0, 2}}}),
device->GetServiceData());
EXPECT_EQ(ManufacturerDataMap({{kTestManufacturerId, {}}}),
device->GetManufacturerData());
EXPECT_EQ(ToInt8(TestTxPower::LOWER), device->GetInquiryTxPower().value());
discovery_sessions_[0]->Stop(GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(adapter_->IsDiscovering());
ASSERT_FALSE(discovery_sessions_[0]->IsActive());
EXPECT_EQ(3, observer.device_changed_count());
EXPECT_FALSE(device->GetInquiryRSSI());
EXPECT_FALSE(device->GetAdvertisingDataFlags().has_value());
EXPECT_TRUE(device->GetUUIDs().empty());
EXPECT_TRUE(device->GetServiceData().empty());
EXPECT_TRUE(device->GetManufacturerData().empty());
EXPECT_FALSE(device->GetInquiryTxPower());
StartLowEnergyDiscoverySession();
device = SimulateLowEnergyDevice(1);
EXPECT_EQ(4, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOWEST), device->GetInquiryRSSI().value());
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x04, device->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute)}),
device->GetUUIDs());
EXPECT_EQ(ServiceDataMap({{BluetoothUUID(kTestUUIDHeartRate), {1}}}),
device->GetServiceData());
EXPECT_EQ(ManufacturerDataMap({{kTestManufacturerId, {1, 2, 3, 4}}}),
device->GetManufacturerData());
EXPECT_EQ(ToInt8(TestTxPower::LOWEST), device->GetInquiryTxPower().value());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
#define MAYBE_DeviceAdvertisementReceived DeviceAdvertisementReceived
#else
#define MAYBE_DeviceAdvertisementReceived DISABLED_DeviceAdvertisementReceived
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DeviceAdvertisementReceived) {
#else
TEST_F(BluetoothTest, MAYBE_DeviceAdvertisementReceived) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
StartLowEnergyDiscoverySession();
SimulateLowEnergyDevice(1);
ASSERT_EQ(1, observer.device_advertisement_raw_received_count());
EXPECT_EQ(kTestDeviceName, observer.last_device_name().value_or(""));
EXPECT_EQ(kTestDeviceName, observer.last_advertisement_name().value_or(""));
EXPECT_EQ(static_cast<int>(TestRSSI::LOWEST),
observer.last_rssi().value_or(-1));
EXPECT_EQ(static_cast<int>(TestTxPower::LOWEST),
observer.last_tx_power().value_or(-1));
const device::BluetoothDevice::UUIDList kTestAdvertisedUUIDs = {
BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute)};
EXPECT_EQ(kTestAdvertisedUUIDs, observer.last_advertised_uuids());
const device::BluetoothDevice::ServiceDataMap kTestServiceDataMap = {
{BluetoothUUID(kTestUUIDHeartRate), {1}}};
EXPECT_EQ(kTestServiceDataMap, observer.last_service_data_map());
const device::BluetoothDevice::ManufacturerDataMap kTestManufacturerDataMap =
{{kTestManufacturerId, {1, 2, 3, 4}}};
EXPECT_EQ(kTestManufacturerDataMap, observer.last_manufacturer_data_map());
SimulateLowEnergyDevice(2);
EXPECT_EQ(2, observer.device_advertisement_raw_received_count());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetUUIDs_Connection GetUUIDs_Connection
#else
#define MAYBE_GetUUIDs_Connection DISABLED_GetUUIDs_Connection
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GetUUIDs_Connection) {
#else
TEST_F(BluetoothTest, MAYBE_GetUUIDs_Connection) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
discovery_sessions_[0]->Stop(GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
ASSERT_TRUE(ConnectGatt(device));
ASSERT_TRUE(device->IsConnected());
EXPECT_TRUE(device->GetUUIDs().empty());
observer.Reset();
std::vector<std::string> services;
services.push_back(kTestUUIDGenericAccess);
SimulateGattServicesDiscovered(device, services);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess)}),
device->GetUUIDs());
#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
observer.Reset();
SimulateGattServicesChanged(device);
ASSERT_FALSE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_TRUE(device->GetUUIDs().empty());
SimulateGattServicesDiscovered(device, {} );
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, observer.device_changed_count());
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess)}),
device->GetUUIDs());
#endif
observer.Reset();
gatt_connections_[0]->Disconnect();
SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(device->IsGattConnected());
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_TRUE(device->GetUUIDs().empty());
}
#if BUILDFLAG(IS_APPLE)
TEST_F(BluetoothTest, TwoPendingServiceDiscoveryRequests) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_FALSE(device->IsGattServicesDiscoveryComplete());
observer.Reset();
SimulateGattServicesChanged(device);
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_FALSE(device->IsGattServicesDiscoveryComplete());
observer.Reset();
AddServicesToDeviceMac(device, {kTestUUIDHeartRate});
SimulateDidDiscoverServicesMac(device);
EXPECT_EQ(0, observer.device_changed_count());
EXPECT_FALSE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(gatt_characteristic_discovery_attempts_, 0);
SimulateGattServicesDiscovered(
device, std::vector<std::string>({kTestUUIDImmediateAlert}));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(gatt_characteristic_discovery_attempts_, 2);
EXPECT_EQ(2u, device->GetGattServices().size());
}
TEST_F(BluetoothTest, ExtraDidDiscoverServicesCall) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_FALSE(device->IsGattServicesDiscoveryComplete());
observer.Reset();
SimulateGattServicesDiscovered(
device, std::vector<std::string>({kTestUUIDHeartRate}));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(gatt_characteristic_discovery_attempts_, 1);
EXPECT_EQ(1u, device->GetGattServices().size());
AddServicesToDeviceMac(device, {kTestUUIDImmediateAlert});
SimulateDidDiscoverServicesMac(device);
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(1u, device->GetGattServices().size());
}
#endif
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_AdvertisementData_DiscoveryDuringConnection \
AdvertisementData_DiscoveryDuringConnection
#else
#define MAYBE_AdvertisementData_DiscoveryDuringConnection \
DISABLED_AdvertisementData_DiscoveryDuringConnection
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, AdvertisementData_DiscoveryDuringConnection) {
#else
TEST_F(BluetoothTest, MAYBE_AdvertisementData_DiscoveryDuringConnection) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute)}),
device->GetUUIDs());
discovery_sessions_[0]->Stop(GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(adapter_->IsDiscovering());
ASSERT_FALSE(discovery_sessions_[0]->IsActive());
ASSERT_EQ(0u, device->GetUUIDs().size());
discovery_sessions_.clear();
ASSERT_TRUE(ConnectGatt(device));
ASSERT_TRUE(device->IsConnected());
observer.Reset();
StartLowEnergyDiscoverySession();
ASSERT_TRUE(adapter_->IsDiscovering());
ASSERT_TRUE(discovery_sessions_[0]->IsActive());
device = SimulateLowEnergyDevice(1);
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOWEST), device->GetInquiryRSSI().value());
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute)}),
device->GetUUIDs());
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x04, device->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(ServiceDataMap({{BluetoothUUID(kTestUUIDHeartRate), {1}}}),
device->GetServiceData());
EXPECT_EQ(ToInt8(TestTxPower::LOWEST), device->GetInquiryTxPower().value());
std::vector<std::string> services;
services.push_back(kTestUUIDHeartRate);
SimulateGattServicesDiscovered(device, services);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, observer.device_changed_count());
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute),
BluetoothUUID(kTestUUIDHeartRate)}),
device->GetUUIDs());
device = SimulateLowEnergyDevice(2);
EXPECT_EQ(3, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOWER), device->GetInquiryRSSI().value());
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x05, device->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDLinkLoss),
BluetoothUUID(kTestUUIDImmediateAlert),
BluetoothUUID(kTestUUIDHeartRate)}),
device->GetUUIDs());
EXPECT_EQ(ServiceDataMap(
{{BluetoothUUID(kTestUUIDHeartRate), std::vector<uint8_t>({})},
{BluetoothUUID(kTestUUIDImmediateAlert), {0, 2}}}),
device->GetServiceData());
EXPECT_EQ(ToInt8(TestTxPower::LOWER), device->GetInquiryTxPower().value());
discovery_sessions_[0]->Stop(GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(adapter_->IsDiscovering());
ASSERT_FALSE(discovery_sessions_[0]->IsActive());
EXPECT_EQ(4, observer.device_changed_count());
EXPECT_FALSE(device->GetInquiryRSSI());
EXPECT_FALSE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDHeartRate)}), device->GetUUIDs());
EXPECT_EQ(ServiceDataMap(), device->GetServiceData());
EXPECT_FALSE(device->GetInquiryTxPower());
gatt_connections_[0]->Disconnect();
SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(device->IsGattConnected());
EXPECT_EQ(5, observer.device_changed_count());
EXPECT_TRUE(device->GetUUIDs().empty());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_AdvertisementData_ConnectionDuringDiscovery \
AdvertisementData_ConnectionDuringDiscovery
#else
#define MAYBE_AdvertisementData_ConnectionDuringDiscovery \
DISABLED_AdvertisementData_ConnectionDuringDiscovery
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, AdvertisementData_ConnectionDuringDiscovery) {
#else
TEST_F(BluetoothTest, MAYBE_AdvertisementData_ConnectionDuringDiscovery) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
StartLowEnergyDiscoverySession();
ASSERT_TRUE(adapter_->IsDiscovering());
ASSERT_TRUE(discovery_sessions_[0]->IsActive());
BluetoothDevice* device = SimulateLowEnergyDevice(1);
EXPECT_EQ(0, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOWEST), device->GetInquiryRSSI().value());
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x04, device->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute)}),
device->GetUUIDs());
EXPECT_EQ(ServiceDataMap({{BluetoothUUID(kTestUUIDHeartRate), {1}}}),
device->GetServiceData());
EXPECT_EQ(ToInt8(TestTxPower::LOWEST), device->GetInquiryTxPower().value());
ASSERT_TRUE(ConnectGatt(device));
ASSERT_TRUE(device->IsConnected());
observer.Reset();
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute)}),
device->GetUUIDs());
device = SimulateLowEnergyDevice(2);
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOWER), device->GetInquiryRSSI().value());
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x05, device->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDLinkLoss),
BluetoothUUID(kTestUUIDImmediateAlert)}),
device->GetUUIDs());
EXPECT_EQ(ServiceDataMap(
{{BluetoothUUID(kTestUUIDHeartRate), std::vector<uint8_t>({})},
{BluetoothUUID(kTestUUIDImmediateAlert), {0, 2}}}),
device->GetServiceData());
EXPECT_EQ(ToInt8(TestTxPower::LOWER), device->GetInquiryTxPower().value());
std::vector<std::string> services;
services.push_back(kTestUUIDHeartRate);
SimulateGattServicesDiscovered(device, services);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, observer.device_changed_count());
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDLinkLoss),
BluetoothUUID(kTestUUIDImmediateAlert),
BluetoothUUID(kTestUUIDHeartRate)}),
device->GetUUIDs());
gatt_connections_[0]->Disconnect();
SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(device->IsGattConnected());
EXPECT_EQ(3, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOWER), device->GetInquiryRSSI().value());
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x05, device->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDLinkLoss),
BluetoothUUID(kTestUUIDImmediateAlert)}),
device->GetUUIDs());
EXPECT_EQ(ServiceDataMap(
{{BluetoothUUID(kTestUUIDHeartRate), std::vector<uint8_t>({})},
{BluetoothUUID(kTestUUIDImmediateAlert), {0, 2}}}),
device->GetServiceData());
EXPECT_EQ(ToInt8(TestTxPower::LOWER), device->GetInquiryTxPower().value());
device = SimulateLowEnergyDevice(1);
EXPECT_EQ(4, observer.device_changed_count());
EXPECT_EQ(ToInt8(TestRSSI::LOWEST), device->GetInquiryRSSI().value());
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
EXPECT_EQ(0x04, device->GetAdvertisingDataFlags().value());
#endif
EXPECT_EQ(UUIDSet({BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute)}),
device->GetUUIDs());
EXPECT_EQ(ServiceDataMap({{BluetoothUUID(kTestUUIDHeartRate), {1}}}),
device->GetServiceData());
EXPECT_EQ(ToInt8(TestTxPower::LOWEST), device->GetInquiryTxPower().value());
discovery_sessions_[0]->Stop(GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(5, observer.device_changed_count());
EXPECT_FALSE(device->GetInquiryRSSI());
EXPECT_FALSE(device->GetAdvertisingDataFlags().has_value());
EXPECT_TRUE(device->GetUUIDs().empty());
EXPECT_TRUE(device->GetServiceData().empty());
EXPECT_FALSE(device->GetInquiryTxPower());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_APPLE) || \
BUILDFLAG(IS_LINUX)
#define MAYBE_GetName_NullName GetName_NullName
#else
#define MAYBE_GetName_NullName DISABLED_GetName_NullName
#endif
TEST_F(BluetoothTest, MAYBE_GetName_NullName) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
#if !BUILDFLAG(IS_CHROMEOS)
StartLowEnergyDiscoverySession();
#endif
BluetoothDevice* device = SimulateLowEnergyDevice(5);
EXPECT_FALSE(device->GetName());
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_APPLE)
EXPECT_EQ(device->GetNameForDisplay(),
u"Unknown or Unsupported Device (01:00:00:90:1E:BE)");
#endif
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_CreateGattConnection CreateGattConnection
#else
#define MAYBE_CreateGattConnection DISABLED_CreateGattConnection
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, CreateGattConnection) {
#else
TEST_F(BluetoothTest, MAYBE_CreateGattConnection) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
ASSERT_EQ(1u, gatt_connections_.size());
EXPECT_TRUE(device->IsGattConnected());
EXPECT_TRUE(gatt_connections_[0]->IsConnected());
#if BUILDFLAG(IS_WIN)
if (!UsesNewGattSessionHandling() &&
UncachedGattDiscoveryForGattConnection()) {
EXPECT_EQ(gatt_discovery_attempts_with_uncached_mode(), 1);
} else {
EXPECT_EQ(gatt_discovery_attempts_with_uncached_mode(), 0);
}
#endif
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DisconnectionNotifiesDeviceChanged \
DisconnectionNotifiesDeviceChanged
#else
#define MAYBE_DisconnectionNotifiesDeviceChanged \
DISABLED_DisconnectionNotifiesDeviceChanged
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DisconnectionNotifiesDeviceChanged) {
#else
TEST_F(BluetoothTest, MAYBE_DisconnectionNotifiesDeviceChanged) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_TRUE(device->IsConnected());
EXPECT_TRUE(device->IsGattConnected());
SimulateDeviceBreaksConnection(device);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, observer.device_changed_count());
EXPECT_FALSE(device->IsConnected());
EXPECT_FALSE(device->IsGattConnected());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection BluetoothGattConnection
#else
#define MAYBE_BluetoothGattConnection DISABLED_BluetoothGattConnection
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, BluetoothGattConnection) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
std::string device_address = device->GetAddress();
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
ASSERT_EQ(1u, gatt_connections_.size());
EXPECT_TRUE(device->IsGattConnected());
EXPECT_TRUE(gatt_connections_[0]->IsConnected());
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(0, gatt_connection_attempts_);
ASSERT_EQ(3u, gatt_connections_.size());
EXPECT_EQ(device_address, gatt_connections_[0]->GetDeviceAddress());
EXPECT_TRUE(gatt_connections_[0]->IsConnected());
EXPECT_TRUE(gatt_connections_[1]->IsConnected());
EXPECT_TRUE(gatt_connections_[2]->IsConnected());
gatt_connections_[0]->Disconnect();
gatt_connections_.pop_back();
EXPECT_FALSE(gatt_connections_[0]->IsConnected());
EXPECT_TRUE(gatt_connections_[1]->IsConnected());
EXPECT_TRUE(device->IsGattConnected());
EXPECT_EQ(0, gatt_disconnection_attempts_);
gatt_disconnection_attempts_ = 0;
DeleteDevice(device);
EXPECT_EQ(1, gatt_disconnection_attempts_);
EXPECT_FALSE(gatt_connections_[0]->IsConnected());
EXPECT_FALSE(gatt_connections_[1]->IsConnected());
EXPECT_EQ(device_address, gatt_connections_[0]->GetDeviceAddress());
EXPECT_EQ(device_address, gatt_connections_[1]->GetDeviceAddress());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_ConnectWithMultipleOSConnections \
BluetoothGattConnection_ConnectWithMultipleOSConnections
#else
#define MAYBE_BluetoothGattConnection_ConnectWithMultipleOSConnections \
DISABLED_BluetoothGattConnection_ConnectWithMultipleOSConnections
#endif
TEST_F(BluetoothTest,
MAYBE_BluetoothGattConnection_ConnectWithMultipleOSConnections) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
TestBluetoothAdapterObserver observer(adapter_);
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(
ConnectGatt(device, std::nullopt,
base::BindLambdaForTesting([this](BluetoothDevice* device) {
SimulateGattConnection(device);
SimulateGattConnection(device);
})));
EXPECT_EQ(1, gatt_discovery_attempts_);
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_EQ(1, gatt_connection_attempts_);
EXPECT_TRUE(gatt_connections_[0]->IsConnected());
SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(gatt_connections_[0]->IsConnected());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_AlreadyConnected \
BluetoothGattConnection_AlreadyConnected
#else
#define MAYBE_BluetoothGattConnection_AlreadyConnected \
DISABLED_BluetoothGattConnection_AlreadyConnected
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, BluetoothGattConnection_AlreadyConnected) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_AlreadyConnected) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_TRUE(gatt_connections_[0]->IsConnected());
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(0, gatt_connection_attempts_);
EXPECT_TRUE(gatt_connections_[1]->IsConnected());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected \
BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected
#else
#define MAYBE_BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected \
DISABLED_BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt,
BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected) {
#else
TEST_F(BluetoothTest,
MAYBE_BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ASSERT_TRUE(ConnectGatt(device));
gatt_connections_[0]->Disconnect();
SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_FALSE(gatt_connections_[0]->IsConnected())
<< "The disconnected connection shouldn't become connected when another "
"connection is created.";
EXPECT_TRUE(gatt_connections_[1]->IsConnected());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_DisconnectWhenObjectsDestroyed \
BluetoothGattConnection_DisconnectWhenObjectsDestroyed
#else
#define MAYBE_BluetoothGattConnection_DisconnectWhenObjectsDestroyed \
DISABLED_BluetoothGattConnection_DisconnectWhenObjectsDestroyed
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt,
BluetoothGattConnection_DisconnectWhenObjectsDestroyed) {
#else
TEST_F(BluetoothTest,
MAYBE_BluetoothGattConnection_DisconnectWhenObjectsDestroyed) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ASSERT_TRUE(
ConnectGatt(device,
std::nullopt,
base::BindLambdaForTesting([this](BluetoothDevice* device) {
ConnectGatt(device);
})));
EXPECT_EQ(2u, gatt_connections_.size());
ResetEventCounts();
gatt_connections_.clear();
EXPECT_EQ(1, gatt_disconnection_attempts_);
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_DisconnectInProgress \
BluetoothGattConnection_DisconnectInProgress
#else
#define MAYBE_BluetoothGattConnection_DisconnectInProgress \
DISABLED_BluetoothGattConnection_DisconnectInProgress
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, BluetoothGattConnection_DisconnectInProgress) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_DisconnectInProgress) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ASSERT_TRUE(
ConnectGatt(device,
std::nullopt,
base::BindLambdaForTesting([this](BluetoothDevice* device) {
ConnectGatt(device);
})));
EXPECT_EQ(2u, gatt_connections_.size());
ResetEventCounts();
for (const auto& connection : gatt_connections_)
connection->Disconnect();
EXPECT_EQ(1, gatt_disconnection_attempts_);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(0, gatt_connection_attempts_);
EXPECT_FALSE(gatt_connections_.front()->IsConnected());
EXPECT_TRUE(gatt_connections_.back()->IsConnected());
SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle();
for (const auto& connection : gatt_connections_)
EXPECT_FALSE(connection->IsConnected());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_SimulateDisconnect \
BluetoothGattConnection_SimulateDisconnect
#else
#define MAYBE_BluetoothGattConnection_SimulateDisconnect \
DISABLED_BluetoothGattConnection_SimulateDisconnect
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, BluetoothGattConnection_SimulateDisconnect) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_SimulateDisconnect) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
EXPECT_FALSE(
ConnectGatt(device,
std::nullopt,
base::BindLambdaForTesting([this](BluetoothDevice* device) {
SimulateGattDisconnection(device);
})));
EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_code_);
for (const auto& connection : gatt_connections_)
EXPECT_FALSE(connection->IsConnected());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_DisconnectGatt_SimulateConnect \
BluetoothGattConnection_DisconnectGatt_SimulateConnect
#else
#define MAYBE_BluetoothGattConnection_DisconnectGatt_SimulateConnect \
DISABLED_BluetoothGattConnection_DisconnectGatt_SimulateConnect
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt,
BluetoothGattConnection_DisconnectGatt_SimulateConnect) {
#else
TEST_F(BluetoothTest,
MAYBE_BluetoothGattConnection_DisconnectGatt_SimulateConnect) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
EXPECT_TRUE(
ConnectGatt(device,
std::nullopt,
base::BindLambdaForTesting([this](BluetoothDevice* device) {
#if !BUILDFLAG(IS_WIN)
device->DisconnectGatt();
#endif
SimulateGattConnection(device);
})));
#if !BUILDFLAG(IS_WIN)
EXPECT_EQ(1, gatt_disconnection_attempts_);
#endif
EXPECT_EQ(1, gatt_connection_attempts_);
EXPECT_TRUE(gatt_connections_.back()->IsConnected());
ResetEventCounts();
SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle();
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_DisconnectGatt_SimulateDisconnect \
BluetoothGattConnection_DisconnectGatt_SimulateDisconnect
#else
#define MAYBE_BluetoothGattConnection_DisconnectGatt_SimulateDisconnect \
DISABLED_BluetoothGattConnection_DisconnectGatt_SimulateDisconnect
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt,
BluetoothGattConnection_DisconnectGatt_SimulateDisconnect) {
#else
TEST_F(BluetoothTest,
MAYBE_BluetoothGattConnection_DisconnectGatt_SimulateDisconnect) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_FALSE(
ConnectGatt(device,
std::nullopt,
base::BindLambdaForTesting([this](BluetoothDevice* device) {
device->DisconnectGatt();
SimulateGattDisconnection(device);
})));
EXPECT_EQ(1, gatt_connection_attempts_);
EXPECT_EQ(
#if BUILDFLAG(IS_ANDROID)
2,
#else
1,
#endif
gatt_disconnection_attempts_);
EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_code_);
for (const auto& connection : gatt_connections_)
EXPECT_FALSE(connection->IsConnected());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_DisconnectGatt_Cleanup \
BluetoothGattConnection_DisconnectGatt_Cleanup
#else
#define MAYBE_BluetoothGattConnection_DisconnectGatt_Cleanup \
DISABLED_BluetoothGattConnection_DisconnectGatt_Cleanup
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, BluetoothGattConnection_DisconnectGatt_Cleanup) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_DisconnectGatt_Cleanup) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
EXPECT_FALSE(device->IsConnected());
ResetEventCounts();
TestBluetoothAdapterObserver observer(adapter_);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_TRUE(device->IsConnected());
SimulateGattServicesDiscovered(
device,
std::vector<std::string>({kTestUUIDGenericAccess, kTestUUIDHeartRate}));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(2u, device->GetGattServices().size());
EXPECT_EQ(1, observer.gatt_services_discovered_count());
device->DisconnectGatt();
SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsConnected());
EXPECT_FALSE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(0u, device->GetGattServices().size());
ASSERT_TRUE(ConnectGatt(device));
EXPECT_TRUE(device->IsConnected());
SimulateGattServicesDiscovered(
device, std::vector<std::string>({kTestUUIDGenericAttribute}));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(1u, device->GetGattServices().size());
EXPECT_EQ(2, observer.gatt_services_discovered_count());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_BluetoothGattConnection_ErrorAfterConnection \
BluetoothGattConnection_ErrorAfterConnection
#else
#define MAYBE_BluetoothGattConnection_ErrorAfterConnection \
DISABLED_BluetoothGattConnection_ErrorAfterConnection
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, BluetoothGattConnection_ErrorAfterConnection) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_ErrorAfterConnection) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
EXPECT_FALSE(ConnectGatt(
device,
std::nullopt,
base::BindLambdaForTesting([this](BluetoothDevice* device) {
SimulateGattConnectionError(device, BluetoothDevice::ERROR_AUTH_FAILED);
SimulateGattConnectionError(device, BluetoothDevice::ERROR_FAILED);
})));
EXPECT_EQ(1, gatt_connection_attempts_);
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN)
EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_code_);
#else
EXPECT_EQ(BluetoothDevice::ERROR_AUTH_FAILED, last_connect_error_code_);
#endif
for (const auto& connection : gatt_connections_)
EXPECT_FALSE(connection->IsConnected());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
#define MAYBE_GattServices_ObserversCalls GattServices_ObserversCalls
#else
#define MAYBE_GattServices_ObserversCalls DISABLED_GattServices_ObserversCalls
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GattServices_ObserversCalls) {
#else
TEST_F(BluetoothTest, MAYBE_GattServices_ObserversCalls) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
TestBluetoothAdapterObserver observer(adapter_);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
SimulateGattServicesDiscovered(
device,
std::vector<std::string>({kTestUUIDGenericAccess, kTestUUIDHeartRate}));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, observer.gatt_services_discovered_count());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
#define MAYBE_GattServicesDiscovered_Success GattServicesDiscovered_Success
#else
#define MAYBE_GattServicesDiscovered_Success \
DISABLED_GattServicesDiscovered_Success
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GattServicesDiscovered_Success) {
#else
TEST_F(BluetoothTest, MAYBE_GattServicesDiscovered_Success) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
TestBluetoothAdapterObserver observer(adapter_);
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
EXPECT_EQ(0, observer.gatt_services_discovered_count());
SimulateGattServicesDiscovered(
device,
std::vector<std::string>({kTestUUIDGenericAccess, kTestUUIDHeartRate}));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(1, observer.gatt_services_discovered_count());
EXPECT_EQ(2u, device->GetGattServices().size());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN)
#define MAYBE_GattServicesDiscovered_AfterDeleted \
GattServicesDiscovered_AfterDeleted
#else
#define MAYBE_GattServicesDiscovered_AfterDeleted \
DISABLED_GattServicesDiscovered_AfterDeleted
#endif
TEST_F(BluetoothTest, MAYBE_GattServicesDiscovered_AfterDeleted) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
RememberDeviceForSubsequentAction(device);
DeleteDevice(device);
SimulateGattServicesDiscovered(
nullptr ,
std::vector<std::string>({kTestUUIDGenericAccess, kTestUUIDHeartRate}));
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN)
#define MAYBE_GattServicesDiscoveredError_AfterDeleted \
GattServicesDiscoveredError_AfterDeleted
#else
#define MAYBE_GattServicesDiscoveredError_AfterDeleted \
DISABLED_GattServicesDiscoveredError_AfterDeleted
#endif
TEST_F(BluetoothTest, MAYBE_GattServicesDiscoveredError_AfterDeleted) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
RememberDeviceForSubsequentAction(device);
DeleteDevice(device);
SimulateGattServicesDiscoveryError(nullptr );
base::RunLoop().RunUntilIdle();
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GattServicesDiscovered_AfterDisconnection \
GattServicesDiscovered_AfterDisconnection
#else
#define MAYBE_GattServicesDiscovered_AfterDisconnection \
DISABLED_GattServicesDiscovered_AfterDisconnection
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GattServicesDiscovered_AfterDisconnection) {
#else
TEST_F(BluetoothTest, MAYBE_GattServicesDiscovered_AfterDisconnection) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
SimulateDeviceBreaksConnection(device);
base::RunLoop().RunUntilIdle();
SimulateGattServicesDiscovered(
device,
std::vector<std::string>({kTestUUIDGenericAccess, kTestUUIDHeartRate}));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(0u, device->GetGattServices().size());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GattServicesDiscoveredError_AfterDisconnection \
GattServicesDiscoveredError_AfterDisconnection
#else
#define MAYBE_GattServicesDiscoveredError_AfterDisconnection \
DISABLED_GattServicesDiscoveredError_AfterDisconnection
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GattServicesDiscoveredError_AfterDisconnection) {
#else
TEST_F(BluetoothTest, MAYBE_GattServicesDiscoveredError_AfterDisconnection) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle();
SimulateGattServicesDiscoveryError(device);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(0u, device->GetGattServices().size());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetGattServices_and_GetGattService \
GetGattServices_and_GetGattService
#else
#define MAYBE_GetGattServices_and_GetGattService \
DISABLED_GetGattServices_and_GetGattService
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GetGattServices_and_GetGattService) {
#else
TEST_F(BluetoothTest, MAYBE_GetGattServices_and_GetGattService) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
SimulateGattServicesDiscovered(
device,
std::vector<std::string>(
{kTestUUIDGenericAccess, kTestUUIDHeartRate, kTestUUIDHeartRate}));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, device->GetGattServices().size());
std::string service_id1 = device->GetGattServices()[0]->GetIdentifier();
std::string service_id2 = device->GetGattServices()[1]->GetIdentifier();
std::string service_id3 = device->GetGattServices()[2]->GetIdentifier();
EXPECT_TRUE(device->GetGattService(service_id1));
EXPECT_TRUE(device->GetGattService(service_id2));
EXPECT_TRUE(device->GetGattService(service_id3));
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetGattServices_FindNone GetGattServices_FindNone
#else
#define MAYBE_GetGattServices_FindNone DISABLED_GetGattServices_FindNone
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GetGattServices_FindNone) {
#else
TEST_F(BluetoothTest, MAYBE_GetGattServices_FindNone) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
SimulateGattServicesDiscovered(device, {} );
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, device->GetGattServices().size());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetGattServices_DiscoveryError GetGattServices_DiscoveryError
#else
#define MAYBE_GetGattServices_DiscoveryError \
DISABLED_GetGattServices_DiscoveryError
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GetGattServices_DiscoveryError) {
#else
TEST_F(BluetoothTest, MAYBE_GetGattServices_DiscoveryError) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
SimulateGattServicesDiscoveryError(device);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, device->GetGattServices().size());
}
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GattServicesDiscovered_SomeServicesBlocked) {
#else
TEST_F(BluetoothTest, DISABLED_GattServicesDiscovered_SomeServicesBlocked) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
TestBluetoothAdapterObserver observer(adapter_);
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(1, gatt_discovery_attempts_);
EXPECT_EQ(0, observer.gatt_services_discovered_count());
SimulateGattServicesDiscovered(
device,
{kTestUUIDGenericAccess, kTestUUIDHeartRate},
{kTestUUIDU2f});
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(1, observer.gatt_services_discovered_count());
EXPECT_EQ(3u, device->GetGattServices().size());
}
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
TEST_F(BluetoothTest, GetDeviceTransportType) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
EXPECT_EQ(BLUETOOTH_TRANSPORT_LE, device->GetType());
#if !defined(USE_CAST_BLUETOOTH_ADAPTER)
BluetoothDevice* device2 = SimulateLowEnergyDevice(6);
EXPECT_EQ(BLUETOOTH_TRANSPORT_DUAL, device2->GetType());
BluetoothDevice* device3 = SimulateClassicDevice();
EXPECT_EQ(BLUETOOTH_TRANSPORT_CLASSIC, device3->GetType());
#endif
}
#endif
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetPrimaryServices GetPrimaryServices
#else
#define MAYBE_GetPrimaryServices DISABLED_GetPrimaryServices
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GetPrimaryServices) {
#else
TEST_F(BluetoothTest, MAYBE_GetPrimaryServices) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
EXPECT_FALSE(device->IsConnected());
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_TRUE(device->IsGattConnected());
SimulateGattServicesDiscovered(
device, {kTestUUIDGenericAccess, kTestUUIDHeartRate, kTestUUIDHeartRate});
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
EXPECT_EQ(3u, device->GetPrimaryServices().size());
}
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetPrimaryServicesByUUID GetPrimaryServicesByUUID
#else
#define MAYBE_GetPrimaryServicesByUUID DISABLED_GetPrimaryServicesByUUID
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GetPrimaryServicesByUUID) {
#else
TEST_F(BluetoothTest, MAYBE_GetPrimaryServicesByUUID) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
EXPECT_FALSE(device->IsConnected());
ResetEventCounts();
ASSERT_TRUE(ConnectGatt(device));
EXPECT_TRUE(device->IsGattConnected());
SimulateGattServicesDiscovered(
device, {kTestUUIDGenericAccess, kTestUUIDHeartRate, kTestUUIDHeartRate});
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
{
const BluetoothUUID unique_service_uuid(kTestUUIDGenericAccess);
std::vector<BluetoothRemoteGattService*> services =
device->GetPrimaryServicesByUUID(unique_service_uuid);
EXPECT_EQ(1u, services.size());
EXPECT_EQ(unique_service_uuid, services[0]->GetUUID());
}
{
const BluetoothUUID duplicate_service_uuid(kTestUUIDHeartRate);
std::vector<BluetoothRemoteGattService*> services =
device->GetPrimaryServicesByUUID(duplicate_service_uuid);
EXPECT_EQ(2u, services.size());
EXPECT_EQ(duplicate_service_uuid, services[0]->GetUUID());
EXPECT_EQ(duplicate_service_uuid, services[1]->GetUUID());
EXPECT_TRUE(
device
->GetPrimaryServicesByUUID(BluetoothUUID(kTestUUIDGenericAttribute))
.empty());
EXPECT_NE(services[0]->GetIdentifier(), services[1]->GetIdentifier());
}
}
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, GattConnectedNameChange) {
#else
TEST_F(BluetoothTest, DISABLED_GattConnectedNameChange) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_TRUE(!device->GetName() || device->GetName()->empty());
TestBluetoothAdapterObserver observer(adapter_);
SimulateGattNameChange(device, kTestDeviceName);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_EQ(base::UTF8ToUTF16(kTestDeviceName), device->GetNameForDisplay());
}
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, FalseStatusChangedTest) {
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(3);
EXPECT_FALSE(device->IsConnected());
device->CreateGattConnection(
GetGattConnectionCallback(Call::NOT_EXPECTED, Result::FAILURE));
SimulateStatusChangeToDisconnect(device);
base::RunLoop().RunUntilIdle();
}
#endif
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ServiceSpecificDiscovery ServiceSpecificDiscovery
#else
#define MAYBE_ServiceSpecificDiscovery DISABLED_ServiceSpecificDiscovery
#endif
#if !BUILDFLAG(IS_WIN)
TEST_F(BluetoothTest, MAYBE_ServiceSpecificDiscovery) {
#else
TEST_P(BluetoothTestWinrt, ServiceSpecificDiscovery) {
#endif
if (!PlatformSupportsLowEnergy()) {
GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
ASSERT_TRUE(ConnectGatt(device, BluetoothUUID(kTestUUIDGenericAccess)));
EXPECT_TRUE(device->IsGattConnected());
SimulateGattServicesDiscovered(device, {kTestUUIDGenericAccess});
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, gatt_connection_attempts_);
EXPECT_EQ(1, gatt_discovery_attempts_);
#if !BUILDFLAG(IS_WIN)
ASSERT_FALSE(device->supports_service_specific_discovery());
EXPECT_FALSE(GetTargetGattService(device).has_value());
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
#else
ASSERT_TRUE(device->supports_service_specific_discovery());
std::optional<BluetoothUUID> service_uuid = GetTargetGattService(device);
ASSERT_TRUE(service_uuid.has_value());
EXPECT_EQ(*service_uuid, BluetoothUUID(kTestUUIDGenericAccess));
EXPECT_FALSE(device->IsGattServicesDiscoveryComplete());
ASSERT_TRUE(ConnectGatt(device, BluetoothUUID(kTestUUIDGenericAccess)));
EXPECT_EQ(1, gatt_connection_attempts_);
EXPECT_EQ(1, gatt_discovery_attempts_);
ASSERT_TRUE(ConnectGatt(device));
EXPECT_EQ(2, gatt_discovery_attempts_);
SimulateGattServicesDiscovered(device, {kTestUUIDGenericAccess});
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
ASSERT_TRUE(ConnectGatt(device, BluetoothUUID(kTestUUIDGenericAccess)));
EXPECT_EQ(2, gatt_discovery_attempts_);
#endif
}
}