#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/debug/dump_without_crashing.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/current_thread.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/bind.h"
#include "base/test/mock_callback.h"
#include "base/test/repeating_test_future.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluez/bluetooth_adapter_bluez.h"
#include "device/bluetooth/bluez/bluetooth_device_bluez.h"
#include "device/bluetooth/bluez/bluetooth_pairing_bluez.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_admin_policy_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_battery_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
#include "device/bluetooth/test/mock_pairing_delegate.h"
#include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
#include "chromeos/constants/chromeos_features.h"
#include "device/bluetooth/bluetooth_low_energy_scan_filter.h"
#include "device/bluetooth/bluetooth_low_energy_scan_session.h"
#include "device/bluetooth/chromeos/bluetooth_utils.h"
#include "device/bluetooth/dbus/fake_bluetooth_advertisement_monitor_manager_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "services/data_decoder/public/mojom/ble_scan_parser.mojom.h"
#endif
namespace {
BluetoothAdapter;
BluetoothAdapterFactory;
BluetoothDevice;
BatteryInfo;
BatteryType;
BluetoothDeviceType;
BluetoothDiscoveryFilter;
BluetoothDiscoverySession;
BluetoothUUID;
MockPairingDelegate;
TestBluetoothAdapterObserver;
_;
StrictMock;
#if BUILDFLAG(IS_CHROMEOS)
constexpr int16_t kBackgroundScanningDeviceFoundRSSIThreshold = -80;
constexpr int16_t kBackgroundScanningDeviceLostRSSIThreshold = -100;
constexpr base::TimeDelta kBackgroundScanningDeviceFoundTimeout =
base::Seconds(1);
constexpr base::TimeDelta kBackgroundScanningDeviceLostTimeout =
base::Seconds(5);
constexpr uint8_t kBackgroundScanningFilterPatternValue[] = {0x2c, 0xfe, 0xfc,
0x12, 0x8e};
std::unique_ptr<device::BluetoothLowEnergyScanFilter>
CreateLowEnergyScanFilter() {
auto pattern_value =
std::vector<uint8_t>(std::begin(kBackgroundScanningFilterPatternValue),
std::end(kBackgroundScanningFilterPatternValue));
device::BluetoothLowEnergyScanFilter::Pattern pattern(
0,
device::BluetoothLowEnergyScanFilter::AdvertisementDataType::kServiceData,
std::move(pattern_value));
return device::BluetoothLowEnergyScanFilter::Create(
kBackgroundScanningDeviceFoundRSSIThreshold,
kBackgroundScanningDeviceLostRSSIThreshold,
kBackgroundScanningDeviceFoundTimeout,
kBackgroundScanningDeviceLostTimeout, {pattern},
std::nullopt);
}
bluez::FakeBluetoothAdvertisementMonitorApplicationServiceProvider*
GetAdvertisementMonitorApplicationManger() {
return static_cast<bluez::FakeBluetoothAdvertisementMonitorManagerClient*>(
bluez::BluezDBusManager::Get()
->GetBluetoothAdvertisementMonitorManagerClient())
->application_provider();
}
#endif
void ScheduleAsynchronousCancelPairing(BluetoothDevice* device) { … }
void ScheduleAsynchronousRejectPairing(BluetoothDevice* device) { … }
}
namespace bluez {
namespace {
bool* dump_without_crashing_flag;
extern "C" void HandleDumpWithoutCrashing() { … }
void SaveConnectionInfo(BluetoothDevice::ConnectionInfo* out,
const BluetoothDevice::ConnectionInfo& conn_info) { … }
int GetDeviceIndexByAddress(const BluetoothAdapter::DeviceList& devices,
const char* address) { … }
#if BUILDFLAG(IS_CHROMEOS)
class FakeBleScanParserImpl : public data_decoder::mojom::BleScanParser {
public:
FakeBleScanParserImpl() = default;
FakeBleScanParserImpl(const FakeBleScanParserImpl&) = delete;
FakeBleScanParserImpl& operator=(const FakeBleScanParserImpl&) = delete;
~FakeBleScanParserImpl() override = default;
void Parse(const std::vector<uint8_t>& advertisement_data,
ParseCallback callback) override {
std::move(callback).Run(nullptr);
}
};
#endif
MockDBusErrorCallback;
class FakeBluetoothProfileServiceProviderDelegate
: public bluez::BluetoothProfileServiceProvider::Delegate { … };
#if BUILDFLAG(IS_CHROMEOS)
class FakeBluetoothLowEnergyScanSessionDelegate
: public device::BluetoothLowEnergyScanSession::Delegate {
public:
FakeBluetoothLowEnergyScanSessionDelegate() = default;
void OnSessionStarted(
device::BluetoothLowEnergyScanSession* scan_session,
std::optional<device::BluetoothLowEnergyScanSession::ErrorCode>
error_code) override {
sessions_started_.push_back(std::make_pair(scan_session, error_code));
}
void OnDeviceFound(device::BluetoothLowEnergyScanSession* scan_session,
device::BluetoothDevice* device) override {
devices_found_.push_back(std::make_pair(scan_session, device));
}
void OnDeviceLost(device::BluetoothLowEnergyScanSession* scan_session,
device::BluetoothDevice* device) override {
devices_lost_.push_back(std::make_pair(scan_session, device));
}
void OnSessionInvalidated(
device::BluetoothLowEnergyScanSession* scan_session) override {
sessions_invalidated_.push_back(scan_session);
}
const std::vector<std::pair<
device::BluetoothLowEnergyScanSession*,
std::optional<device::BluetoothLowEnergyScanSession::ErrorCode>>>&
sessions_started() const {
return sessions_started_;
}
const std::vector<std::pair<device::BluetoothLowEnergyScanSession*,
device::BluetoothDevice*>>&
devices_found() const {
return devices_found_;
}
const std::vector<std::pair<device::BluetoothLowEnergyScanSession*,
device::BluetoothDevice*>>&
devices_lost() const {
return devices_lost_;
}
const std::vector<
raw_ptr<device::BluetoothLowEnergyScanSession, VectorExperimental>>&
sessions_invalidated() const {
return sessions_invalidated_;
}
base::WeakPtr<FakeBluetoothLowEnergyScanSessionDelegate> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
private:
std::vector<std::pair<
device::BluetoothLowEnergyScanSession*,
std::optional<device::BluetoothLowEnergyScanSession::ErrorCode>>>
sessions_started_;
std::vector<std::pair<device::BluetoothLowEnergyScanSession*,
device::BluetoothDevice*>>
devices_found_;
std::vector<std::pair<device::BluetoothLowEnergyScanSession*,
device::BluetoothDevice*>>
devices_lost_;
std::vector<
raw_ptr<device::BluetoothLowEnergyScanSession, VectorExperimental>>
sessions_invalidated_;
base::WeakPtrFactory<FakeBluetoothLowEnergyScanSessionDelegate>
weak_ptr_factory_{this};
};
#endif
}
class BluetoothBlueZTest : public testing::Test { … };
class BluetoothBlueZTestP : public BluetoothBlueZTest,
public testing::WithParamInterface<bool> { … };
#if BUILDFLAG(IS_CHROMEOS)
INSTANTIATE_TEST_SUITE_P(All,
BluetoothBlueZTestP,
testing::Bool());
#else
INSTANTIATE_TEST_SUITE_P(…);
#endif
const char BluetoothBlueZTest::kGapUuid[] = …;
const char BluetoothBlueZTest::kGattUuid[] = …;
const char BluetoothBlueZTest::kPnpUuid[] = …;
const char BluetoothBlueZTest::kHeadsetUuid[] = …;
TEST_F(BluetoothBlueZTest, AlreadyPresent) { … }
TEST_F(BluetoothBlueZTest, BecomePresent) { … }
TEST_F(BluetoothBlueZTest, BecomeNotPresent) { … }
TEST_F(BluetoothBlueZTest, SecondAdapter) { … }
TEST_F(BluetoothBlueZTest, BecomePowered) { … }
TEST_F(BluetoothBlueZTest, BecomeNotPowered) { … }
TEST_F(BluetoothBlueZTest, SetPoweredWhenNotPresent) { … }
TEST_F(BluetoothBlueZTest, ChangeAdapterName) { … }
TEST_F(BluetoothBlueZTest, ChangeAdapterNameWhenNotPresent) { … }
TEST_F(BluetoothBlueZTest, GetUUIDs) { … }
TEST_F(BluetoothBlueZTest, BecomeDiscoverable) { … }
TEST_F(BluetoothBlueZTest, BecomeNotDiscoverable) { … }
TEST_F(BluetoothBlueZTest, SetDiscoverableWhenNotPresent) { … }
TEST_F(BluetoothBlueZTest, StopDiscovery) { … }
TEST_F(BluetoothBlueZTest, Discovery) { … }
TEST_F(BluetoothBlueZTest, PoweredAndDiscovering) { … }
TEST_F(BluetoothBlueZTest, StopAndStartDiscoverySimultaneously) { … }
TEST_F(BluetoothBlueZTest, MultipleDiscoverySessions) { … }
TEST_F(BluetoothBlueZTest, UnexpectedChangesDuringMultipleDiscoverySessions) { … }
TEST_F(BluetoothBlueZTest, InvalidatedDiscoverySessions) { … }
TEST_F(BluetoothBlueZTest, StartDiscoverySession) { … }
TEST_F(BluetoothBlueZTest, SetDiscoveryFilterBeforeStartDiscovery) { … }
TEST_F(BluetoothBlueZTest, SetDiscoveryFilterBeforeStartDiscoveryFail) { … }
TEST_F(BluetoothBlueZTest, SetDiscoveryFilterBeforeStartDiscoveryMultiple) { … }
TEST_F(BluetoothBlueZTest, SetDiscoveryFilterMergingTest) { … }
TEST_F(BluetoothBlueZTest, DeviceProperties) { … }
TEST_F(BluetoothBlueZTest, DeviceAddressType) { … }
TEST_F(BluetoothBlueZTest, DeviceClassChanged) { … }
TEST_F(BluetoothBlueZTest, DeviceAppearance) { … }
TEST_F(BluetoothBlueZTest, DeviceTypebyAppearanceNotBluetoothClass) { … }
TEST_F(BluetoothBlueZTest, DeviceNameChanged) { … }
TEST_F(BluetoothBlueZTest, DeviceAddressChanged) { … }
#if BUILDFLAG(IS_CHROMEOS)
TEST_F(BluetoothBlueZTest, DeviceBondedChanged) {
GetAdapter();
BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
ASSERT_EQ(2U, devices.size());
int idx = GetDeviceIndexByAddress(
devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
ASSERT_NE(-1, idx);
ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
devices[idx]->GetAddress());
ASSERT_EQ(true, devices[idx]->IsBonded());
TestBluetoothAdapterObserver observer(adapter_);
bluez::FakeBluetoothDeviceClient::Properties* properties =
fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
properties->bonded.ReplaceValue(false);
EXPECT_EQ(1, observer.device_changed_count());
EXPECT_EQ(1, observer.device_bonded_changed_count());
EXPECT_FALSE(observer.device_new_bonded_status());
EXPECT_EQ(devices[idx], observer.last_device());
properties->bonded.ReplaceValue(true);
EXPECT_EQ(2, observer.device_changed_count());
EXPECT_EQ(2, observer.device_bonded_changed_count());
EXPECT_TRUE(observer.device_new_bonded_status());
EXPECT_EQ(devices[idx], observer.last_device());
}
#endif
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
TEST_F(BluetoothBlueZTest, DevicePairedChanged) { … }
TEST_F(BluetoothBlueZTest, DeviceMTUChanged) { … }
TEST_F(BluetoothBlueZTest, DeviceAdvertisementReceived_LowEnergyDeviceAdded) { … }
TEST_F(BluetoothBlueZTest, DeviceAdvertisementReceived_PropertyChanged) { … }
TEST_F(BluetoothBlueZTest, DeviceConnectedStateChanged) { … }
#endif
TEST_F(BluetoothBlueZTest, DeviceUuidsChanged) { … }
TEST_F(BluetoothBlueZTest, DeviceInquiryRSSIInvalidated) { … }
TEST_F(BluetoothBlueZTest, DeviceInquiryTxPowerInvalidated) { … }
TEST_F(BluetoothBlueZTest, ForgetDevice) { … }
TEST_P(BluetoothBlueZTestP, ForgetUnpairedDevice) { … }
TEST_P(BluetoothBlueZTestP, ConnectPairedDevice) { … }
TEST_P(BluetoothBlueZTestP, ConnectUnpairableDevice) { … }
TEST_P(BluetoothBlueZTestP, ConnectConnectedDevice) { … }
TEST_P(BluetoothBlueZTestP, ConnectDeviceFails) { … }
TEST_P(BluetoothBlueZTestP, RemoveDeviceDuringConnection) { … }
TEST_P(BluetoothBlueZTestP, DisconnectDevice) { … }
TEST_F(BluetoothBlueZTest, DisconnectUnconnectedDevice) { … }
TEST_F(BluetoothBlueZTest, PairTrustedDevice) { … }
TEST_F(BluetoothBlueZTest, PairAlreadyPairedDevice) { … }
TEST_P(BluetoothBlueZTestP, PairLegacyAutopair) { … }
TEST_P(BluetoothBlueZTestP, PairDisplayPinCode) { … }
TEST_P(BluetoothBlueZTestP, PairDisplayPasskey) { … }
TEST_P(BluetoothBlueZTestP, PairRequestPinCode) { … }
TEST_P(BluetoothBlueZTestP, PairConfirmPasskey) { … }
TEST_P(BluetoothBlueZTestP, PairRequestPasskey) { … }
TEST_P(BluetoothBlueZTestP, PairJustWorks) { … }
TEST_P(BluetoothBlueZTestP, PairUnpairableDeviceFails) { … }
TEST_P(BluetoothBlueZTestP, PairingFails) { … }
TEST_P(BluetoothBlueZTestP, PairingFailsAtConnection) { … }
TEST_P(BluetoothBlueZTestP, PairingRejectedAtPinCode) { … }
TEST_P(BluetoothBlueZTestP, PairingCancelledAtPinCode) { … }
TEST_P(BluetoothBlueZTestP, PairingRejectedAtPasskey) { … }
TEST_P(BluetoothBlueZTestP, PairingCancelledAtPasskey) { … }
TEST_P(BluetoothBlueZTestP, PairingRejectedAtConfirmation) { … }
TEST_P(BluetoothBlueZTestP, PairingCancelledAtConfirmation) { … }
TEST_P(BluetoothBlueZTestP, PairingCancelledInFlight) { … }
TEST_F(BluetoothBlueZTest, IncomingPairRequestPinCode) { … }
TEST_F(BluetoothBlueZTest, IncomingPairConfirmPasskey) { … }
TEST_F(BluetoothBlueZTest, IncomingPairRequestPasskey) { … }
TEST_F(BluetoothBlueZTest, IncomingPairJustWorks) { … }
TEST_F(BluetoothBlueZTest, IncomingPairRequestPinCodeWithoutDelegate) { … }
TEST_F(BluetoothBlueZTest, IncomingPairConfirmPasskeyWithoutDelegate) { … }
TEST_F(BluetoothBlueZTest, IncomingPairRequestPasskeyWithoutDelegate) { … }
TEST_F(BluetoothBlueZTest, IncomingPairJustWorksWithoutDelegate) { … }
TEST_F(BluetoothBlueZTest, RemovePairingDelegateDuringPairing) { … }
TEST_F(BluetoothBlueZTest, DeviceId) { … }
TEST_F(BluetoothBlueZTest, GetConnectionInfoForDisconnectedDevice) { … }
TEST_P(BluetoothBlueZTestP, GetConnectionInfoForConnectedDevice) { … }
TEST_F(BluetoothBlueZTest, GetDiscoverableTimeout) { … }
TEST_F(BluetoothBlueZTest, Shutdown) { … }
TEST_F(BluetoothBlueZTest, StartDiscovery_DiscoveringStopped_StartAgain) { … }
TEST_F(BluetoothBlueZTest, Shutdown_OnStartDiscovery) { … }
TEST_F(BluetoothBlueZTest, Shutdown_OnStartDiscoveryError) { … }
TEST_F(BluetoothBlueZTest, StartDiscoveryError_ThenStartAgain) { … }
TEST_F(BluetoothBlueZTest, ManufacturerDataChanged) { … }
TEST_F(BluetoothBlueZTest, AdvertisingDataFlagsChanged) { … }
TEST_F(BluetoothBlueZTest, SetConnectionLatency) { … }
#if BUILDFLAG(IS_CHROMEOS)
TEST_F(BluetoothBlueZTest, AdminPolicyEvents) {
GetAdapter();
dbus::ObjectPath device_path =
dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath);
fake_bluetooth_device_client_->CreateDevice(
dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
device_path);
BluetoothDevice* device =
adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
EXPECT_TRUE(device);
EXPECT_FALSE(device->IsBlockedByPolicy());
fake_bluetooth_admin_policy_client_->CreateAdminPolicy(
device_path,
true);
EXPECT_TRUE(device->IsBlockedByPolicy());
fake_bluetooth_admin_policy_client_->ChangeAdminPolicy(
device_path,
false);
EXPECT_FALSE(device->IsBlockedByPolicy());
fake_bluetooth_admin_policy_client_->ChangeAdminPolicy(
device_path,
true);
EXPECT_TRUE(device->IsBlockedByPolicy());
fake_bluetooth_admin_policy_client_->RemoveAdminPolicy(device_path);
EXPECT_FALSE(device->IsBlockedByPolicy());
}
TEST_F(BluetoothBlueZTest, AdminPolicyInitBeforeDevice) {
GetAdapter();
dbus::ObjectPath device_path =
dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath);
fake_bluetooth_admin_policy_client_->CreateAdminPolicy(
device_path,
true);
fake_bluetooth_device_client_->CreateDevice(
dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
device_path);
BluetoothDevice* device =
adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
EXPECT_TRUE(device);
EXPECT_TRUE(device->IsBlockedByPolicy());
}
#endif
TEST_F(BluetoothBlueZTest, BatteryEvents) { … }
TEST_F(BluetoothBlueZTest, DeviceUUIDsCombinedFromServiceAndAdvertisement) { … }
#if BUILDFLAG(IS_CHROMEOS)
TEST_F(BluetoothBlueZTest, StartLowEnergyScanSessionAdapterPresent) {
GetAdapter();
FakeBluetoothAdvertisementMonitorApplicationServiceProvider*
application_manager = GetAdvertisementMonitorApplicationManger();
auto filter = CreateLowEnergyScanFilter();
FakeBluetoothLowEnergyScanSessionDelegate delegate;
auto background_scan_session = adapter_->StartLowEnergyScanSession(
std::move(filter), delegate.GetWeakPtr());
ASSERT_EQ(1u, application_manager->AdvertisementMonitorsCount());
background_scan_session.reset();
ASSERT_EQ(0u, application_manager->AdvertisementMonitorsCount());
}
TEST_F(BluetoothBlueZTest, StartLowEnergyScanSessionAdapterAddedLater) {
fake_bluetooth_adapter_client_->SetPresent(false);
GetAdapter();
ASSERT_FALSE(adapter_->IsPresent());
FakeBluetoothAdvertisementMonitorApplicationServiceProvider*
application_manager = GetAdvertisementMonitorApplicationManger();
auto filter = CreateLowEnergyScanFilter();
FakeBluetoothLowEnergyScanSessionDelegate delegate;
auto background_scan_session = adapter_->StartLowEnergyScanSession(
std::move(filter), delegate.GetWeakPtr());
ASSERT_EQ(0u, application_manager->AdvertisementMonitorsCount());
fake_bluetooth_adapter_client_->SetPresent(true);
EXPECT_TRUE(adapter_->IsPresent());
ASSERT_EQ(1u, application_manager->AdvertisementMonitorsCount());
background_scan_session.reset();
ASSERT_EQ(0u, application_manager->AdvertisementMonitorsCount());
}
TEST_F(BluetoothBlueZTest, StartLowEnergyScanSessionAdapterBecomeNotPresent) {
GetAdapter();
ASSERT_TRUE(adapter_->IsPresent());
fake_bluetooth_adapter_client_->SetPresent(false);
FakeBluetoothAdvertisementMonitorApplicationServiceProvider*
application_manager = GetAdvertisementMonitorApplicationManger();
auto filter = CreateLowEnergyScanFilter();
FakeBluetoothLowEnergyScanSessionDelegate delegate;
auto background_scan_session = adapter_->StartLowEnergyScanSession(
std::move(filter), delegate.GetWeakPtr());
ASSERT_EQ(0u, application_manager->AdvertisementMonitorsCount());
fake_bluetooth_adapter_client_->SetPresent(true);
ASSERT_EQ(1u, application_manager->AdvertisementMonitorsCount());
}
TEST_F(BluetoothBlueZTest, BluetoothLowEnergyScanSessionBlueZDeviceFound) {
GetAdapter();
ASSERT_TRUE(adapter_->IsPresent());
FakeBluetoothAdvertisementMonitorApplicationServiceProvider*
application_manager = GetAdvertisementMonitorApplicationManger();
FakeBluetoothLowEnergyScanSessionDelegate delegate;
auto background_scan_session = adapter_->StartLowEnergyScanSession(
CreateLowEnergyScanFilter(), delegate.GetWeakPtr());
EXPECT_EQ(1u, application_manager->AdvertisementMonitorsCount());
FakeBluetoothAdvertisementMonitorServiceProvider* advertisement_monitor =
application_manager->GetLastAddedAdvertisementMonitorServiceProvider();
ASSERT_TRUE(advertisement_monitor);
advertisement_monitor->delegate()->OnDeviceFound(
dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
EXPECT_EQ(1u, delegate.devices_found().size());
std::pair<device::BluetoothLowEnergyScanSession*, device::BluetoothDevice*>
devices_found_pair = delegate.devices_found()[0];
EXPECT_EQ(background_scan_session.get(), devices_found_pair.first);
EXPECT_EQ(adapter_->GetDevice(
bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress),
devices_found_pair.second);
}
TEST_F(BluetoothBlueZTest, BluetoothLowEnergyScanSessionBlueZDeviceNULL) {
GetAdapter();
ASSERT_TRUE(adapter_->IsPresent());
FakeBluetoothAdvertisementMonitorApplicationServiceProvider*
application_manager = GetAdvertisementMonitorApplicationManger();
FakeBluetoothLowEnergyScanSessionDelegate delegate;
auto background_scan_session = adapter_->StartLowEnergyScanSession(
CreateLowEnergyScanFilter(), delegate.GetWeakPtr());
EXPECT_EQ(1u, application_manager->AdvertisementMonitorsCount());
FakeBluetoothAdvertisementMonitorServiceProvider* advertisement_monitor =
application_manager->GetLastAddedAdvertisementMonitorServiceProvider();
ASSERT_TRUE(advertisement_monitor);
bool did_dump_without_crashing = false;
dump_without_crashing_flag = &did_dump_without_crashing;
base::debug::SetDumpWithoutCrashingFunction(&HandleDumpWithoutCrashing);
advertisement_monitor->delegate()->OnDeviceFound(dbus::ObjectPath(""));
EXPECT_TRUE(did_dump_without_crashing);
base::debug::SetDumpWithoutCrashingFunction(nullptr);
}
TEST_F(BluetoothBlueZTest, BluetoothLowEnergyScanSessionBlueZDeviceLost) {
GetAdapter();
ASSERT_TRUE(adapter_->IsPresent());
FakeBluetoothAdvertisementMonitorApplicationServiceProvider*
application_manager = GetAdvertisementMonitorApplicationManger();
FakeBluetoothLowEnergyScanSessionDelegate delegate;
auto background_scan_session = adapter_->StartLowEnergyScanSession(
CreateLowEnergyScanFilter(), delegate.GetWeakPtr());
EXPECT_EQ(1u, application_manager->AdvertisementMonitorsCount());
FakeBluetoothAdvertisementMonitorServiceProvider* advertisement_monitor =
application_manager->GetLastAddedAdvertisementMonitorServiceProvider();
ASSERT_TRUE(advertisement_monitor);
advertisement_monitor->delegate()->OnDeviceLost(
dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
EXPECT_EQ(1u, delegate.devices_lost().size());
std::pair<device::BluetoothLowEnergyScanSession*, device::BluetoothDevice*>
devices_lost_pair = delegate.devices_lost()[0];
EXPECT_EQ(background_scan_session.get(), devices_lost_pair.first);
EXPECT_EQ(adapter_->GetDevice(
bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress),
devices_lost_pair.second);
}
TEST_F(BluetoothBlueZTest,
BluetoothLowEnergyScanSessionBlueZStartThenInvalidate) {
GetAdapter();
ASSERT_TRUE(adapter_->IsPresent());
FakeBluetoothAdvertisementMonitorApplicationServiceProvider*
application_manager = GetAdvertisementMonitorApplicationManger();
FakeBluetoothLowEnergyScanSessionDelegate delegate;
auto background_scan_session = adapter_->StartLowEnergyScanSession(
CreateLowEnergyScanFilter(), delegate.GetWeakPtr());
EXPECT_EQ(1u, application_manager->AdvertisementMonitorsCount());
FakeBluetoothAdvertisementMonitorServiceProvider* advertisement_monitor =
application_manager->GetLastAddedAdvertisementMonitorServiceProvider();
ASSERT_TRUE(advertisement_monitor);
advertisement_monitor->delegate()->OnActivate();
EXPECT_EQ(1u, delegate.sessions_started().size());
std::pair<device::BluetoothLowEnergyScanSession*,
std::optional<device::BluetoothLowEnergyScanSession::ErrorCode>>
session_started_pair = delegate.sessions_started()[0];
EXPECT_EQ(background_scan_session.get(), session_started_pair.first);
EXPECT_FALSE(session_started_pair.second.has_value());
advertisement_monitor->delegate()->OnRelease();
EXPECT_EQ(1u, delegate.sessions_invalidated().size());
EXPECT_EQ(background_scan_session.get(),
delegate.sessions_invalidated().front());
}
TEST_F(BluetoothBlueZTest, BluetoothLowEnergyScanSessionBlueZFailsToStart) {
GetAdapter();
ASSERT_TRUE(adapter_->IsPresent());
FakeBluetoothAdvertisementMonitorApplicationServiceProvider*
application_manager = GetAdvertisementMonitorApplicationManger();
FakeBluetoothLowEnergyScanSessionDelegate delegate;
auto background_scan_session = adapter_->StartLowEnergyScanSession(
CreateLowEnergyScanFilter(), delegate.GetWeakPtr());
EXPECT_EQ(1u, application_manager->AdvertisementMonitorsCount());
FakeBluetoothAdvertisementMonitorServiceProvider* advertisement_monitor =
application_manager->GetLastAddedAdvertisementMonitorServiceProvider();
ASSERT_TRUE(advertisement_monitor);
advertisement_monitor->delegate()->OnRelease();
EXPECT_EQ(1u, delegate.sessions_started().size());
std::pair<device::BluetoothLowEnergyScanSession*,
std::optional<device::BluetoothLowEnergyScanSession::ErrorCode>>
session_started_pair = delegate.sessions_started()[0];
EXPECT_EQ(background_scan_session.get(), session_started_pair.first);
EXPECT_TRUE(session_started_pair.second.has_value());
}
TEST_F(BluetoothBlueZTest,
LowEnergyScanSession_HardwareOffloadingNotSupported) {
GetAdapter();
ASSERT_TRUE(adapter_->IsPresent());
EXPECT_EQ(adapter_->GetLowEnergyScanSessionHardwareOffloadingStatus(),
BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus::
kNotSupported);
}
TEST_F(BluetoothBlueZTest, LowEnergyScanSession_HardwareOffloadingSupport) {
GetAdapter();
ASSERT_TRUE(adapter_->IsPresent());
TestBluetoothAdapterObserver observer(adapter_);
BluetoothAdapterBlueZ* adapter_bluez =
static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
FakeBluetoothAdvertisementMonitorManagerClient* client =
static_cast<bluez::FakeBluetoothAdvertisementMonitorManagerClient*>(
bluez::BluezDBusManager::Get()
->GetBluetoothAdvertisementMonitorManagerClient());
client->RemoveProperties();
EXPECT_EQ(adapter_->GetLowEnergyScanSessionHardwareOffloadingStatus(),
BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus::
kUndetermined);
EXPECT_EQ(observer.last_low_energy_scan_session_hardware_offloading_status(),
BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus::
kUndetermined);
client->InitializeProperties();
BluetoothAdvertisementMonitorManagerClient::Properties* properties =
client->GetProperties(adapter_bluez->object_path());
ASSERT_TRUE(properties);
properties->supported_features.ReplaceValue(
{bluetooth_advertisement_monitor_manager::
kSupportedFeaturesControllerPatterns});
EXPECT_EQ(adapter_->GetLowEnergyScanSessionHardwareOffloadingStatus(),
BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus::
kSupported);
EXPECT_EQ(observer.last_low_energy_scan_session_hardware_offloading_status(),
BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus::
kSupported);
properties->supported_features.ReplaceValue({});
EXPECT_EQ(adapter_->GetLowEnergyScanSessionHardwareOffloadingStatus(),
BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus::
kNotSupported);
EXPECT_EQ(observer.last_low_energy_scan_session_hardware_offloading_status(),
BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus::
kNotSupported);
client->RemoveProperties();
EXPECT_EQ(adapter_->GetLowEnergyScanSessionHardwareOffloadingStatus(),
BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus::
kUndetermined);
}
TEST_F(BluetoothBlueZTest, IsExtendedAdvertisementsAvailable) {
GetAdapter();
BluetoothAdapterBlueZ* adapter_bluez =
static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
FakeBluetoothLEAdvertisingManagerClient* client =
static_cast<bluez::FakeBluetoothLEAdvertisingManagerClient*>(
bluez::BluezDBusManager::Get()
->GetBluetoothLEAdvertisingManagerClient());
BluetoothLEAdvertisingManagerClient::Properties* properties =
client->GetProperties(adapter_bluez->object_path());
ASSERT_TRUE(properties);
std::vector<std::string> supported_features = {};
properties->supported_features.ReplaceValue(supported_features);
EXPECT_FALSE(adapter_bluez->IsExtendedAdvertisementsAvailable());
supported_features.push_back(std::string(
bluetooth_advertising_manager::kSupportedFeaturesHardwareOffload));
properties->supported_features.ReplaceValue(supported_features);
EXPECT_TRUE(adapter_bluez->IsExtendedAdvertisementsAvailable());
}
TEST_F(BluetoothBlueZTest, GetSupportedRoles) {
std::vector<std::string> adapter_roles;
GetAdapter();
ASSERT_TRUE(adapter_->GetSupportedRoles().empty());
adapter_roles.push_back("unknown-role");
fake_bluetooth_adapter_client_->SetRoles(adapter_roles);
ASSERT_TRUE(adapter_->GetSupportedRoles().empty());
adapter_roles.push_back("central");
fake_bluetooth_adapter_client_->SetRoles(adapter_roles);
EXPECT_EQ(1u, adapter_->GetSupportedRoles().size());
ASSERT_TRUE(base::Contains(adapter_->GetSupportedRoles(),
BluetoothAdapter::BluetoothRole::kCentral));
adapter_roles.push_back("peripheral");
fake_bluetooth_adapter_client_->SetRoles(adapter_roles);
EXPECT_EQ(2u, adapter_->GetSupportedRoles().size());
ASSERT_TRUE(base::Contains(adapter_->GetSupportedRoles(),
BluetoothAdapter::BluetoothRole::kPeripheral));
adapter_roles.push_back("central-peripheral");
fake_bluetooth_adapter_client_->SetRoles(adapter_roles);
EXPECT_EQ(3u, adapter_->GetSupportedRoles().size());
ASSERT_TRUE(
base::Contains(adapter_->GetSupportedRoles(),
BluetoothAdapter::BluetoothRole::kCentralPeripheral));
}
#endif
}