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() { ...@@ -434,4 +434,72 @@ void BluetoothTestBase::RemoveTimedOutDevices() {
adapter_->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 } // namespace device
...@@ -163,42 +163,42 @@ class BluetoothTestBase : public testing::Test { ...@@ -163,42 +163,42 @@ class BluetoothTestBase : public testing::Test {
// |device_ordinal| selects between multiple fake device data sets to produce: // |device_ordinal| selects between multiple fake device data sets to produce:
// 1: Name: kTestDeviceName // 1: Name: kTestDeviceName
// Address: kTestDeviceAddress1 // Address: kTestDeviceAddress1
// RSSI: kTestRSSI1 // RSSI: TestRSSI::LOWEST
// Advertised UUIDs: {kTestUUIDGenericAccess, kTestUUIDGenericAttribute} // Advertised UUIDs: {kTestUUIDGenericAccess, kTestUUIDGenericAttribute}
// Service Data: {kTestUUIDHeartRate: [1]} // Service Data: {kTestUUIDHeartRate: [1]}
// ManufacturerData: {kTestManufacturerId: [1, 2, 3, 4]} // ManufacturerData: {kTestManufacturerId: [1, 2, 3, 4]}
// Tx Power: kTestTxPower1 // Tx Power: TestTxPower::LOWEST
// 2: Name: kTestDeviceName // 2: Name: kTestDeviceName
// Address: kTestDeviceAddress1 // Address: kTestDeviceAddress1
// RSSI: kTestRSSI2 // RSSI: TestRSSI::LOWER
// Advertised UUIDs: {kTestUUIDImmediateAlert, kTestUUIDLinkLoss} // Advertised UUIDs: {kTestUUIDImmediateAlert, kTestUUIDLinkLoss}
// Service Data: {kTestUUIDHeartRate: [], // Service Data: {kTestUUIDHeartRate: [],
// kTestUUIDImmediateAlert: [0, 2]} // kTestUUIDImmediateAlert: [0, 2]}
// ManufacturerData: {kTestManufacturerId: []} // ManufacturerData: {kTestManufacturerId: []}
// Tx Power: kTestTxPower2 // Tx Power: TestTxPower::LOWER
// 3: Name: kTestDeviceNameEmpty // 3: Name: kTestDeviceNameEmpty
// Address: kTestDeviceAddress1 // Address: kTestDeviceAddress1
// RSSI: kTestRSSI3 // RSSI: TestRSSI::LOW
// No Advertised UUIDs // No Advertised UUIDs
// No Service Data // No Service Data
// No Manufacturer Data // No Manufacturer Data
// No Tx Power // No Tx Power
// 4: Name: kTestDeviceNameEmpty // 4: Name: kTestDeviceNameEmpty
// Address: kTestDeviceAddress2 // Address: kTestDeviceAddress2
// RSSI: kTestRSSI4 // RSSI: TestRSSI::MEDIUM
// No Advertised UUIDs // No Advertised UUIDs
// No Service Data // No Service Data
// No Manufacturer Data // No Manufacturer Data
// No Tx Power // No Tx Power
// 5: No name device // 5: No name device
// Address: kTestDeviceAddress1 // Address: kTestDeviceAddress1
// RSSI: kTestRSSI5 // RSSI: TestRSSI::HIGH
// No Advertised UUIDs // No Advertised UUIDs
// No Service Data // No Service Data
// No Tx Power // No Tx Power
// 6: Name: kTestDeviceName // 6: Name: kTestDeviceName
// Address: kTestDeviceAddress2 // Address: kTestDeviceAddress2
// RSSI: kTestRSSI1, // RSSI: TestRSSI::LOWEST
// No Advertised UUIDs // No Advertised UUIDs
// No Service Data // No Service Data
// No Manufacturer Data // No Manufacturer Data
...@@ -206,12 +206,11 @@ class BluetoothTestBase : public testing::Test { ...@@ -206,12 +206,11 @@ class BluetoothTestBase : public testing::Test {
// Supports BR/EDR and LE. // Supports BR/EDR and LE.
// 7: Name: kTestDeviceNameU2f // 7: Name: kTestDeviceNameU2f
// Address: kTestDeviceAddress1 // Address: kTestDeviceAddress1
// RSSI: kTestRSSI1, // RSSI: TestRSSI::LOWEST
// Advertised UUIDs: {kTestUUIDU2fControlPointLength} // Advertised UUIDs: {kTestUUIDU2f}
// Service Data: {kTestUUIDU2fControlPointLength: [0, 20]} // Service Data: {kTestUUIDU2fControlPointLength: [0, 20]}
// No Manufacturer Data // No Manufacturer Data
// No Tx Power // No Tx Power
// Supports LE.
virtual BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal); virtual BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal);
// Simulates a connected low energy device. Used before starting a low energy // Simulates a connected low energy device. Used before starting a low energy
...@@ -527,6 +526,28 @@ class BluetoothTestBase : public testing::Test { ...@@ -527,6 +526,28 @@ class BluetoothTestBase : public testing::Test {
void RemoveTimedOutDevices(); 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 // A ScopedTaskEnvironment is required by some implementations that will
// PostTasks and by base::RunLoop().RunUntilIdle() use in this fixture. // PostTasks and by base::RunLoop().RunUntilIdle() use in this fixture.
base::test::ScopedTaskEnvironment scoped_task_environment_; base::test::ScopedTaskEnvironment scoped_task_environment_;
......
...@@ -115,52 +115,20 @@ void BluetoothTestBlueZ::InitWithFakeAdapter() { ...@@ -115,52 +115,20 @@ void BluetoothTestBlueZ::InitWithFakeAdapter() {
BluetoothDevice* BluetoothTestBlueZ::SimulateLowEnergyDevice( BluetoothDevice* BluetoothTestBlueZ::SimulateLowEnergyDevice(
int device_ordinal) { int device_ordinal) {
if (device_ordinal > 7 || device_ordinal < 1) LowEnergyDeviceData data = GetLowEnergyDeviceData(device_ordinal);
return nullptr;
base::Optional<std::string> device_name = std::string(kTestDeviceName);
std::string device_address = kTestDeviceAddress1;
std::vector<std::string> service_uuids; 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<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) { std::map<uint16_t, std::vector<uint8_t>> manufacturer_data(
case 1: data.manufacturer_data.begin(), data.manufacturer_data.end());
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;
}
BluetoothDevice* device = adapter_->GetDevice(device_address); BluetoothDevice* device = adapter_->GetDevice(data.address);
if (device) { if (device) {
fake_bluetooth_device_client_->UpdateServiceAndManufacturerData( fake_bluetooth_device_client_->UpdateServiceAndManufacturerData(
GetDevicePath(device), service_uuids, service_data, manufacturer_data); GetDevicePath(device), service_uuids, service_data, manufacturer_data);
...@@ -169,11 +137,11 @@ BluetoothDevice* BluetoothTestBlueZ::SimulateLowEnergyDevice( ...@@ -169,11 +137,11 @@ BluetoothDevice* BluetoothTestBlueZ::SimulateLowEnergyDevice(
fake_bluetooth_device_client_->CreateTestDevice( fake_bluetooth_device_client_->CreateTestDevice(
dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
/* name */ device_name, /* name */ data.name,
/* alias */ device_name.value_or("") + "(alias)", device_address, /* alias */ data.name.value_or("") + "(alias)", data.address,
service_uuids, device_type, service_data, manufacturer_data); service_uuids, data.transport, service_data, manufacturer_data);
return adapter_->GetDevice(device_address); return adapter_->GetDevice(data.address);
} }
BluetoothDevice* BluetoothTestBlueZ::SimulateClassicDevice() { BluetoothDevice* BluetoothTestBlueZ::SimulateClassicDevice() {
......
...@@ -239,71 +239,20 @@ void BluetoothTestWin::StartLowEnergyDiscoverySession() { ...@@ -239,71 +239,20 @@ void BluetoothTestWin::StartLowEnergyDiscoverySession() {
} }
BluetoothDevice* BluetoothTestWin::SimulateLowEnergyDevice(int device_ordinal) { BluetoothDevice* BluetoothTestWin::SimulateLowEnergyDevice(int device_ordinal) {
if (device_ordinal > 4 || device_ordinal < 1) LowEnergyDeviceData data = GetLowEnergyDeviceData(device_ordinal);
return nullptr; win::BLEDevice* simulated_device = fake_bt_le_wrapper_->SimulateBLEDevice(
data.name.value_or(std::string()),
std::string device_name = kTestDeviceName; CanonicalStringToBLUETOOTH_ADDRESS(data.address));
std::string device_address = kTestDeviceAddress1; if (simulated_device != nullptr) {
std::string service_uuid_1; for (const auto& uuid : data.advertised_uuids) {
std::string service_uuid_2; fake_bt_le_wrapper_->SimulateGattService(
simulated_device, nullptr,
switch (device_ordinal) { CanonicalStringToBTH_LE_UUID(uuid.canonical_value()));
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));
}
} }
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) { void BluetoothTestWin::SimulateGattConnection(BluetoothDevice* device) {
...@@ -663,6 +612,28 @@ bool BluetoothTestWinrt::PlatformSupportsLowEnergy() { ...@@ -663,6 +612,28 @@ bool BluetoothTestWinrt::PlatformSupportsLowEnergy() {
: BluetoothTestWin::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; BluetoothTestWinrt::~BluetoothTestWinrt() = default;
} // namespace device } // namespace device
...@@ -118,6 +118,7 @@ class BluetoothTestWinrt : public BluetoothTestWin, ...@@ -118,6 +118,7 @@ class BluetoothTestWinrt : public BluetoothTestWin,
~BluetoothTestWinrt() override; ~BluetoothTestWinrt() override;
bool PlatformSupportsLowEnergy() override; bool PlatformSupportsLowEnergy() override;
BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal) override;
private: private:
base::test::ScopedFeatureList scoped_feature_list_; 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