Commit ce567f01 authored by jdoerrie's avatar jdoerrie Committed by Commit Bot

[bluetooth] Unify SimulateLowEnergyDevice for BlueZ and Win

This change aims to reduce code duplication in the implementations of
BluetoothTest::SimulateLowEnergyDevice for BlueZ and Windows. In order
to do so it adds a utility struct and method to BluetoothTestBase, that
implementations of SimulateLowEnergyDevice make use of.

Bug: 821766
Change-Id: I5283a1eb55e50d68dce2c9810994cf6c4ed80212
Reviewed-on: https://chromium-review.googlesource.com/1096675Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567047}
parent 541ffd6a
......@@ -434,4 +434,72 @@ void BluetoothTestBase::RemoveTimedOutDevices() {
adapter_->RemoveTimedOutDevices();
}
BluetoothTestBase::LowEnergyDeviceData::LowEnergyDeviceData() = default;
BluetoothTestBase::LowEnergyDeviceData::LowEnergyDeviceData(
LowEnergyDeviceData&& data) = default;
BluetoothTestBase::LowEnergyDeviceData::~LowEnergyDeviceData() = default;
BluetoothTestBase::LowEnergyDeviceData
BluetoothTestBase::GetLowEnergyDeviceData(int device_ordinal) const {
LowEnergyDeviceData device_data;
switch (device_ordinal) {
case 1:
device_data.name = kTestDeviceName;
device_data.address = kTestDeviceAddress1;
device_data.rssi = static_cast<int>(TestRSSI::LOWEST);
device_data.advertised_uuids = {BluetoothUUID(kTestUUIDGenericAccess),
BluetoothUUID(kTestUUIDGenericAttribute)};
device_data.service_data = {{BluetoothUUID(kTestUUIDHeartRate), {1}}};
device_data.manufacturer_data = {{kTestManufacturerId, {1, 2, 3, 4}}};
device_data.tx_power = static_cast<int>(TestTxPower::LOWEST);
break;
case 2:
device_data.name = kTestDeviceName;
device_data.address = kTestDeviceAddress1;
device_data.rssi = static_cast<int>(TestRSSI::LOWER);
device_data.advertised_uuids = {BluetoothUUID(kTestUUIDImmediateAlert),
BluetoothUUID(kTestUUIDLinkLoss)};
device_data.service_data = {
{BluetoothUUID(kTestUUIDHeartRate), {}},
{BluetoothUUID(kTestUUIDImmediateAlert), {0, 2}}};
device_data.manufacturer_data = {{kTestManufacturerId, {}}};
device_data.tx_power = static_cast<int>(TestTxPower::LOWER);
break;
case 3:
device_data.name = kTestDeviceNameEmpty;
device_data.address = kTestDeviceAddress1;
device_data.rssi = static_cast<int>(TestRSSI::LOW);
break;
case 4:
device_data.name = kTestDeviceNameEmpty;
device_data.address = kTestDeviceAddress2;
device_data.rssi = static_cast<int>(TestRSSI::MEDIUM);
break;
case 5:
device_data.address = kTestDeviceAddress1;
device_data.rssi = static_cast<int>(TestRSSI::HIGH);
break;
case 6:
device_data.name = kTestDeviceName;
device_data.address = kTestDeviceAddress2;
device_data.rssi = static_cast<int>(TestRSSI::LOWEST);
device_data.transport = BLUETOOTH_TRANSPORT_DUAL;
break;
case 7:
device_data.name = kTestDeviceNameU2f;
device_data.address = kTestDeviceAddress1;
device_data.rssi = static_cast<int>(TestRSSI::LOWEST);
device_data.advertised_uuids = {BluetoothUUID(kTestUUIDU2f)};
device_data.service_data = {
{BluetoothUUID(kTestUUIDU2fControlPointLength), {0, 20}}};
break;
default:
NOTREACHED();
}
return device_data;
}
} // namespace device
......@@ -163,42 +163,42 @@ class BluetoothTestBase : public testing::Test {
// |device_ordinal| selects between multiple fake device data sets to produce:
// 1: Name: kTestDeviceName
// Address: kTestDeviceAddress1
// RSSI: kTestRSSI1
// RSSI: TestRSSI::LOWEST
// Advertised UUIDs: {kTestUUIDGenericAccess, kTestUUIDGenericAttribute}
// Service Data: {kTestUUIDHeartRate: [1]}
// ManufacturerData: {kTestManufacturerId: [1, 2, 3, 4]}
// Tx Power: kTestTxPower1
// Tx Power: TestTxPower::LOWEST
// 2: Name: kTestDeviceName
// Address: kTestDeviceAddress1
// RSSI: kTestRSSI2
// RSSI: TestRSSI::LOWER
// Advertised UUIDs: {kTestUUIDImmediateAlert, kTestUUIDLinkLoss}
// Service Data: {kTestUUIDHeartRate: [],
// kTestUUIDImmediateAlert: [0, 2]}
// ManufacturerData: {kTestManufacturerId: []}
// Tx Power: kTestTxPower2
// Tx Power: TestTxPower::LOWER
// 3: Name: kTestDeviceNameEmpty
// Address: kTestDeviceAddress1
// RSSI: kTestRSSI3
// RSSI: TestRSSI::LOW
// No Advertised UUIDs
// No Service Data
// No Manufacturer Data
// No Tx Power
// 4: Name: kTestDeviceNameEmpty
// Address: kTestDeviceAddress2
// RSSI: kTestRSSI4
// RSSI: TestRSSI::MEDIUM
// No Advertised UUIDs
// No Service Data
// No Manufacturer Data
// No Tx Power
// 5: No name device
// Address: kTestDeviceAddress1
// RSSI: kTestRSSI5
// RSSI: TestRSSI::HIGH
// No Advertised UUIDs
// No Service Data
// No Tx Power
// 6: Name: kTestDeviceName
// Address: kTestDeviceAddress2
// RSSI: kTestRSSI1,
// RSSI: TestRSSI::LOWEST
// No Advertised UUIDs
// No Service Data
// No Manufacturer Data
......@@ -206,12 +206,11 @@ class BluetoothTestBase : public testing::Test {
// Supports BR/EDR and LE.
// 7: Name: kTestDeviceNameU2f
// Address: kTestDeviceAddress1
// RSSI: kTestRSSI1,
// Advertised UUIDs: {kTestUUIDU2fControlPointLength}
// RSSI: TestRSSI::LOWEST
// Advertised UUIDs: {kTestUUIDU2f}
// Service Data: {kTestUUIDU2fControlPointLength: [0, 20]}
// No Manufacturer Data
// No Tx Power
// Supports LE.
virtual BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal);
// Simulates a connected low energy device. Used before starting a low energy
......@@ -527,6 +526,28 @@ class BluetoothTestBase : public testing::Test {
void RemoveTimedOutDevices();
protected:
// Utility struct and method to return required data to simulate a LE device
// corresponding to |device_ordinal|.
struct LowEnergyDeviceData {
LowEnergyDeviceData();
LowEnergyDeviceData(LowEnergyDeviceData&& data);
~LowEnergyDeviceData();
base::Optional<std::string> name;
std::string address;
int8_t rssi = 0;
BluetoothDevice::UUIDList advertised_uuids;
BluetoothDevice::ServiceDataMap service_data;
BluetoothDevice::ManufacturerDataMap manufacturer_data;
base::Optional<int8_t> tx_power;
BluetoothTransport transport = BLUETOOTH_TRANSPORT_LE;
DISALLOW_COPY_AND_ASSIGN(LowEnergyDeviceData);
};
LowEnergyDeviceData GetLowEnergyDeviceData(int device_ordinal) const;
// A ScopedTaskEnvironment is required by some implementations that will
// PostTasks and by base::RunLoop().RunUntilIdle() use in this fixture.
base::test::ScopedTaskEnvironment scoped_task_environment_;
......
......@@ -115,52 +115,20 @@ void BluetoothTestBlueZ::InitWithFakeAdapter() {
BluetoothDevice* BluetoothTestBlueZ::SimulateLowEnergyDevice(
int device_ordinal) {
if (device_ordinal > 7 || device_ordinal < 1)
return nullptr;
LowEnergyDeviceData data = GetLowEnergyDeviceData(device_ordinal);
base::Optional<std::string> device_name = std::string(kTestDeviceName);
std::string device_address = kTestDeviceAddress1;
std::vector<std::string> service_uuids;
BluetoothTransport device_type = BLUETOOTH_TRANSPORT_LE;
for (const auto& uuid : data.advertised_uuids)
service_uuids.push_back(uuid.canonical_value());
std::map<std::string, std::vector<uint8_t>> service_data;
std::map<uint16_t, std::vector<uint8_t>> manufacturer_data;
for (const auto& service : data.service_data)
service_data.emplace(service.first.canonical_value(), service.second);
switch (device_ordinal) {
case 1:
service_uuids.push_back(kTestUUIDGenericAccess);
service_uuids.push_back(kTestUUIDGenericAttribute);
service_data[kTestUUIDHeartRate] = {0x01};
manufacturer_data[kTestManufacturerId] = {1, 2, 3, 4};
break;
case 2:
service_uuids.push_back(kTestUUIDImmediateAlert);
service_uuids.push_back(kTestUUIDLinkLoss);
service_data[kTestUUIDHeartRate] = {};
service_data[kTestUUIDImmediateAlert] = {0x00, 0x02};
manufacturer_data[kTestManufacturerId] = {};
break;
case 3:
device_name = std::string(kTestDeviceNameEmpty);
break;
case 4:
device_name = std::string(kTestDeviceNameEmpty);
device_address = kTestDeviceAddress2;
break;
case 5:
device_name = base::nullopt;
break;
case 6:
device_address = kTestDeviceAddress2;
device_type = BLUETOOTH_TRANSPORT_DUAL;
break;
case 7:
device_name.emplace(kTestDeviceNameU2f);
service_uuids.push_back(kTestUUIDU2f);
service_data[kTestUUIDU2fControlPointLength] = {0x00, 0x14};
break;
}
std::map<uint16_t, std::vector<uint8_t>> manufacturer_data(
data.manufacturer_data.begin(), data.manufacturer_data.end());
BluetoothDevice* device = adapter_->GetDevice(device_address);
BluetoothDevice* device = adapter_->GetDevice(data.address);
if (device) {
fake_bluetooth_device_client_->UpdateServiceAndManufacturerData(
GetDevicePath(device), service_uuids, service_data, manufacturer_data);
......@@ -169,11 +137,11 @@ BluetoothDevice* BluetoothTestBlueZ::SimulateLowEnergyDevice(
fake_bluetooth_device_client_->CreateTestDevice(
dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
/* name */ device_name,
/* alias */ device_name.value_or("") + "(alias)", device_address,
service_uuids, device_type, service_data, manufacturer_data);
/* name */ data.name,
/* alias */ data.name.value_or("") + "(alias)", data.address,
service_uuids, data.transport, service_data, manufacturer_data);
return adapter_->GetDevice(device_address);
return adapter_->GetDevice(data.address);
}
BluetoothDevice* BluetoothTestBlueZ::SimulateClassicDevice() {
......
......@@ -239,71 +239,20 @@ void BluetoothTestWin::StartLowEnergyDiscoverySession() {
}
BluetoothDevice* BluetoothTestWin::SimulateLowEnergyDevice(int device_ordinal) {
if (device_ordinal > 4 || device_ordinal < 1)
return nullptr;
std::string device_name = kTestDeviceName;
std::string device_address = kTestDeviceAddress1;
std::string service_uuid_1;
std::string service_uuid_2;
switch (device_ordinal) {
case 1:
service_uuid_1 = kTestUUIDGenericAccess;
service_uuid_2 = kTestUUIDGenericAttribute;
break;
case 2:
service_uuid_1 = kTestUUIDImmediateAlert;
service_uuid_2 = kTestUUIDLinkLoss;
break;
case 3:
device_name = kTestDeviceNameEmpty;
break;
case 4:
device_name = kTestDeviceNameEmpty;
device_address = kTestDeviceAddress2;
break;
}
if (BluetoothAdapterWin::UseNewBLEWinImplementation()) {
std::vector<GUID> guids;
if (!service_uuid_1.empty())
guids.push_back(CanonicalStringToGUID(service_uuid_1));
if (!service_uuid_2.empty())
guids.push_back(CanonicalStringToGUID(service_uuid_2));
auto service_uuids = Make<base::win::Vector<GUID>>(std::move(guids));
auto advertisement = Make<FakeBluetoothLEAdvertisementWinrt>(
std::move(device_name), std::move(service_uuids));
auto event_args = Make<FakeBluetoothLEAdvertisementReceivedEventArgsWinrt>(
device_address, std::move(advertisement));
static_cast<TestBluetoothAdapterWinrt*>(adapter_.get())
->watcher()
->SimulateAdvertisement(std::move(event_args));
} else {
win::BLEDevice* simulated_device = fake_bt_le_wrapper_->SimulateBLEDevice(
device_name, CanonicalStringToBLUETOOTH_ADDRESS(device_address));
if (simulated_device != nullptr) {
if (!service_uuid_1.empty()) {
fake_bt_le_wrapper_->SimulateGattService(
simulated_device, nullptr,
CanonicalStringToBTH_LE_UUID(service_uuid_1));
}
if (!service_uuid_2.empty()) {
fake_bt_le_wrapper_->SimulateGattService(
simulated_device, nullptr,
CanonicalStringToBTH_LE_UUID(service_uuid_2));
}
LowEnergyDeviceData data = GetLowEnergyDeviceData(device_ordinal);
win::BLEDevice* simulated_device = fake_bt_le_wrapper_->SimulateBLEDevice(
data.name.value_or(std::string()),
CanonicalStringToBLUETOOTH_ADDRESS(data.address));
if (simulated_device != nullptr) {
for (const auto& uuid : data.advertised_uuids) {
fake_bt_le_wrapper_->SimulateGattService(
simulated_device, nullptr,
CanonicalStringToBTH_LE_UUID(uuid.canonical_value()));
}
FinishPendingTasks();
}
for (auto* device : adapter_->GetDevices()) {
if (device->GetAddress() == device_address)
return device;
}
FinishPendingTasks();
return nullptr;
return adapter_->GetDevice(data.address);
}
void BluetoothTestWin::SimulateGattConnection(BluetoothDevice* device) {
......@@ -663,6 +612,28 @@ bool BluetoothTestWinrt::PlatformSupportsLowEnergy() {
: BluetoothTestWin::PlatformSupportsLowEnergy();
}
BluetoothDevice* BluetoothTestWinrt::SimulateLowEnergyDevice(
int device_ordinal) {
if (!GetParam() || !PlatformSupportsLowEnergy())
return BluetoothTestWin::SimulateLowEnergyDevice(device_ordinal);
LowEnergyDeviceData data = GetLowEnergyDeviceData(device_ordinal);
std::vector<GUID> guids;
for (const auto& uuid : data.advertised_uuids)
guids.push_back(CanonicalStringToGUID(uuid.canonical_value()));
auto service_uuids = Make<base::win::Vector<GUID>>(std::move(guids));
auto advertisement = Make<FakeBluetoothLEAdvertisementWinrt>(
std::move(data.name), std::move(service_uuids));
auto event_args = Make<FakeBluetoothLEAdvertisementReceivedEventArgsWinrt>(
data.address, std::move(advertisement));
static_cast<TestBluetoothAdapterWinrt*>(adapter_.get())
->watcher()
->SimulateAdvertisement(std::move(event_args));
return adapter_->GetDevice(data.address);
}
BluetoothTestWinrt::~BluetoothTestWinrt() = default;
} // namespace device
......@@ -118,6 +118,7 @@ class BluetoothTestWinrt : public BluetoothTestWin,
~BluetoothTestWinrt() override;
bool PlatformSupportsLowEnergy() override;
BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal) override;
private:
base::test::ScopedFeatureList scoped_feature_list_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment