[go: nahoru, domu]

blob: 0d56e2050dca19f2b6e8c0547758c18c0a009a5e [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/components/tether/ble_scanner.h"
#include "base/callback_forward.h"
#include "chromeos/components/tether/ble_constants.h"
#include "components/cryptauth/mock_foreground_eid_generator.h"
#include "components/cryptauth/mock_local_device_data_provider.h"
#include "components/cryptauth/proto/cryptauth_api.pb.h"
#include "components/cryptauth/remote_device_test_util.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "device/bluetooth/test/mock_bluetooth_device.h"
#include "device/bluetooth/test/mock_bluetooth_discovery_session.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
using testing::DoAll;
using testing::Eq;
using testing::Invoke;
using testing::NiceMock;
using testing::SaveArg;
using testing::Return;
namespace chromeos {
namespace tether {
namespace {
class TestBleScannerObserver final : public BleScanner::Observer {
public:
TestBleScannerObserver() {}
std::vector<std::string>& device_addresses() { return device_addresses_; }
std::vector<cryptauth::RemoteDevice>& remote_devices() {
return remote_devices_;
}
std::vector<bool>& discovery_session_state_changes() {
return discovery_session_state_changes_;
}
// BleScanner::Observer:
void OnReceivedAdvertisementFromDevice(
const cryptauth::RemoteDevice& remote_device,
device::BluetoothDevice* bluetooth_device) override {
device_addresses_.push_back(bluetooth_device->GetAddress());
remote_devices_.push_back(remote_device);
}
void OnDiscoverySessionStateChanged(bool discovery_session_active) override {
discovery_session_state_changes_.push_back(discovery_session_active);
}
private:
std::vector<std::string> device_addresses_;
std::vector<cryptauth::RemoteDevice> remote_devices_;
std::vector<bool> discovery_session_state_changes_;
};
class MockBluetoothDeviceWithServiceData : public device::MockBluetoothDevice {
public:
MockBluetoothDeviceWithServiceData(device::MockBluetoothAdapter* adapter,
const std::string& device_address,
const std::string& service_data)
: device::MockBluetoothDevice(adapter,
/* bluetooth_class */ 0,
"name",
device_address,
false,
false) {
for (size_t i = 0; i < service_data.size(); i++) {
service_data_.push_back(static_cast<uint8_t>(service_data[i]));
}
}
const std::vector<uint8_t>* service_data() { return &service_data_; }
private:
std::vector<uint8_t> service_data_;
};
const size_t kMinNumBytesInServiceData = 4;
const char kDefaultBluetoothAddress[] = "11:22:33:44:55:66";
const char fake_local_public_key[] = "fakeLocalPublicKey";
const char current_eid_data[] = "currentEidData";
const int64_t current_eid_start_ms = 1000L;
const int64_t current_eid_end_ms = 2000L;
const char adjacent_eid_data[] = "adjacentEidData";
const int64_t adjacent_eid_start_ms = 2000L;
const int64_t adjacent_eid_end_ms = 3000L;
const char fake_beacon_seed1_data[] = "fakeBeaconSeed1Data";
const int64_t fake_beacon_seed1_start_ms = current_eid_start_ms;
const int64_t fake_beacon_seed1_end_ms = current_eid_end_ms;
const char fake_beacon_seed2_data[] = "fakeBeaconSeed2Data";
const int64_t fake_beacon_seed2_start_ms = adjacent_eid_start_ms;
const int64_t fake_beacon_seed2_end_ms = adjacent_eid_end_ms;
std::unique_ptr<cryptauth::ForegroundEidGenerator::EidData>
CreateFakeBackgroundScanFilter() {
cryptauth::DataWithTimestamp current(current_eid_data, current_eid_start_ms,
current_eid_end_ms);
std::unique_ptr<cryptauth::DataWithTimestamp> adjacent =
base::MakeUnique<cryptauth::DataWithTimestamp>(
adjacent_eid_data, adjacent_eid_start_ms, adjacent_eid_end_ms);
return base::MakeUnique<cryptauth::ForegroundEidGenerator::EidData>(
current, std::move(adjacent));
}
std::vector<cryptauth::BeaconSeed> CreateFakeBeaconSeeds() {
cryptauth::BeaconSeed seed1;
seed1.set_data(fake_beacon_seed1_data);
seed1.set_start_time_millis(fake_beacon_seed1_start_ms);
seed1.set_start_time_millis(fake_beacon_seed1_end_ms);
cryptauth::BeaconSeed seed2;
seed2.set_data(fake_beacon_seed2_data);
seed2.set_start_time_millis(fake_beacon_seed2_start_ms);
seed2.set_start_time_millis(fake_beacon_seed2_end_ms);
std::vector<cryptauth::BeaconSeed> seeds = {seed1, seed2};
return seeds;
}
} // namespace
class BleScannerTest : public testing::Test {
protected:
class TestServiceDataProvider : public BleScanner::ServiceDataProvider {
public:
TestServiceDataProvider() {}
~TestServiceDataProvider() override {}
// ServiceDataProvider:
const std::vector<uint8_t>* GetServiceDataForUUID(
device::BluetoothDevice* bluetooth_device) override {
return reinterpret_cast<MockBluetoothDeviceWithServiceData*>(
bluetooth_device)
->service_data();
}
};
BleScannerTest()
: test_devices_(cryptauth::GenerateTestRemoteDevices(3)),
test_beacon_seeds_(CreateFakeBeaconSeeds()) {}
void SetUp() override {
test_service_data_provider_ = new TestServiceDataProvider();
std::unique_ptr<cryptauth::MockForegroundEidGenerator> eid_generator =
base::MakeUnique<cryptauth::MockForegroundEidGenerator>();
mock_eid_generator_ = eid_generator.get();
mock_eid_generator_->set_background_scan_filter(
CreateFakeBackgroundScanFilter());
mock_local_device_data_provider_ =
base::MakeUnique<cryptauth::MockLocalDeviceDataProvider>();
mock_local_device_data_provider_->SetPublicKey(
base::MakeUnique<std::string>(fake_local_public_key));
mock_local_device_data_provider_->SetBeaconSeeds(
base::MakeUnique<std::vector<cryptauth::BeaconSeed>>(
test_beacon_seeds_));
last_discovery_callback_.Reset();
last_discovery_error_callback_.Reset();
last_stop_callback_.Reset();
last_discovery_error_callback_.Reset();
mock_adapter_ =
base::MakeRefCounted<NiceMock<device::MockBluetoothAdapter>>();
ON_CALL(*mock_adapter_, StartDiscoverySession(_, _))
.WillByDefault(
Invoke(this, &BleScannerTest::SaveStartDiscoverySessionArgs));
ON_CALL(*mock_adapter_, IsPowered()).WillByDefault(Return(true));
mock_discovery_session_ = nullptr;
ble_scanner_ = base::WrapUnique(new BleScanner(
base::WrapUnique(test_service_data_provider_), mock_adapter_,
std::move(eid_generator), mock_local_device_data_provider_.get()));
test_observer_ = base::MakeUnique<TestBleScannerObserver>();
ble_scanner_->AddObserver(test_observer_.get());
}
void TearDown() override {
EXPECT_EQ(discovery_state_changes_so_far_,
test_observer_->discovery_session_state_changes());
}
void SaveStartDiscoverySessionArgs(
const device::BluetoothAdapter::DiscoverySessionCallback& callback,
const device::BluetoothAdapter::ErrorCallback& errback) {
last_discovery_callback_ = callback;
last_discovery_error_callback_ = errback;
}
void InvokeDiscoveryStartedCallback(bool success) {
EXPECT_FALSE(last_discovery_callback_.is_null());
EXPECT_FALSE(last_discovery_error_callback_.is_null());
// Make a copy of the callbacks and clear the instance fields. Invoke the
// copy below to ensure that if the callback results in another discovery
// attempt, the instance fields are not overwritten incorrectly.
device::BluetoothAdapter::DiscoverySessionCallback callback_copy =
last_discovery_callback_;
device::BluetoothAdapter::ErrorCallback error_callback_copy =
last_discovery_error_callback_;
last_discovery_callback_.Reset();
last_discovery_error_callback_.Reset();
if (success) {
mock_discovery_session_ = new device::MockBluetoothDiscoverySession();
ON_CALL(*mock_discovery_session_, IsActive()).WillByDefault(Return(true));
ON_CALL(*mock_discovery_session_, Stop(_, _))
.WillByDefault(Invoke(this, &BleScannerTest::MockDiscoveryStop));
callback_copy.Run(base::WrapUnique(mock_discovery_session_));
VerifyDiscoveryStatusChange(true /* discovery_session_active */);
} else {
error_callback_copy.Run();
}
}
bool IsDeviceRegistered(const std::string& device_id) {
return ble_scanner_->IsDeviceRegistered(device_id);
}
void VerifyDiscoveryStatusChange(bool discovery_session_active) {
discovery_state_changes_so_far_.push_back(discovery_session_active);
EXPECT_EQ(discovery_state_changes_so_far_,
test_observer_->discovery_session_state_changes());
}
void MockDiscoveryStop(
const base::Closure& callback,
const device::BluetoothDiscoverySession::ErrorCallback& error_callback) {
last_stop_callback_ = callback;
last_stop_error_callback_ = error_callback;
}
void InvokeStopDiscoveryCallback(bool success) {
EXPECT_FALSE(last_stop_callback_.is_null());
EXPECT_FALSE(last_stop_error_callback_.is_null());
// Make a copy of the callbacks and clear the instance fields. Invoke the
// copy below to ensure that if the callback results in another stop
// attempt, the instance fields are not overwritten incorrectly.
base::Closure callback_copy = last_stop_callback_;
device::BluetoothDiscoverySession::ErrorCallback error_callback_copy =
last_stop_error_callback_;
last_stop_callback_.Reset();
last_stop_error_callback_.Reset();
if (success) {
callback_copy.Run();
VerifyDiscoveryStatusChange(false /* discovery_session_active */);
} else {
error_callback_copy.Run();
}
}
const std::vector<cryptauth::RemoteDevice> test_devices_;
const std::vector<cryptauth::BeaconSeed> test_beacon_seeds_;
std::unique_ptr<TestBleScannerObserver> test_observer_;
TestServiceDataProvider* test_service_data_provider_;
cryptauth::MockForegroundEidGenerator* mock_eid_generator_;
std::unique_ptr<cryptauth::MockLocalDeviceDataProvider>
mock_local_device_data_provider_;
scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_adapter_;
device::MockBluetoothDiscoverySession* mock_discovery_session_;
device::BluetoothAdapter::DiscoverySessionCallback last_discovery_callback_;
device::BluetoothAdapter::ErrorCallback last_discovery_error_callback_;
base::Closure last_stop_callback_;
device::BluetoothDiscoverySession::ErrorCallback last_stop_error_callback_;
std::vector<bool> discovery_state_changes_so_far_;
std::unique_ptr<BleScanner> ble_scanner_;
private:
DISALLOW_COPY_AND_ASSIGN(BleScannerTest);
};
TEST_F(BleScannerTest, TestNoLocalBeaconSeeds) {
mock_local_device_data_provider_->SetBeaconSeeds(nullptr);
EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_FALSE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
EXPECT_EQ(0u, test_observer_->device_addresses().size());
}
TEST_F(BleScannerTest, TestNoBackgroundScanFilter) {
mock_eid_generator_->set_background_scan_filter(nullptr);
EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_FALSE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
EXPECT_EQ(0u, test_observer_->device_addresses().size());
}
TEST_F(BleScannerTest, TestDiscoverySessionFailsToStart) {
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
InvokeDiscoveryStartedCallback(false /* success */);
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
EXPECT_EQ(0u, test_observer_->device_addresses().size());
}
TEST_F(BleScannerTest, TestDiscoveryStartsButNoDevicesFound) {
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
InvokeDiscoveryStartedCallback(true /* success */);
// No devices found.
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
EXPECT_EQ(0u, test_observer_->device_addresses().size());
InvokeStopDiscoveryCallback(true /* success */);
}
TEST_F(BleScannerTest, TestDiscovery_NoServiceData) {
std::string empty_service_data = "";
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
InvokeDiscoveryStartedCallback(true /* success */);
// Device with no service data connected. Service data is required to identify
// the advertising device.
MockBluetoothDeviceWithServiceData device(
mock_adapter_.get(), kDefaultBluetoothAddress, empty_service_data);
ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
EXPECT_FALSE(mock_eid_generator_->num_identify_calls());
EXPECT_EQ(0u, test_observer_->device_addresses().size());
}
TEST_F(BleScannerTest, TestDiscovery_ServiceDataTooShort) {
std::string short_service_data = "abc";
ASSERT_TRUE(short_service_data.size() < kMinNumBytesInServiceData);
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
InvokeDiscoveryStartedCallback(true /* success */);
// Device with short service data connected. Service data of at least 4 bytes
// is required to identify the advertising device.
MockBluetoothDeviceWithServiceData device(
mock_adapter_.get(), kDefaultBluetoothAddress, short_service_data);
ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
EXPECT_FALSE(mock_eid_generator_->num_identify_calls());
EXPECT_EQ(0u, test_observer_->device_addresses().size());
}
TEST_F(BleScannerTest, TestDiscovery_LocalDeviceDataCannotBeFetched) {
std::string valid_service_data_for_other_device = "abcd";
ASSERT_TRUE(valid_service_data_for_other_device.size() >=
kMinNumBytesInServiceData);
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
InvokeDiscoveryStartedCallback(true /* success */);
// Device with valid service data connected, but the local device data
// cannot be fetched.
mock_local_device_data_provider_->SetPublicKey(nullptr);
mock_local_device_data_provider_->SetBeaconSeeds(nullptr);
MockBluetoothDeviceWithServiceData device(
mock_adapter_.get(), kDefaultBluetoothAddress,
valid_service_data_for_other_device);
ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
EXPECT_FALSE(mock_eid_generator_->num_identify_calls());
EXPECT_EQ(0u, test_observer_->device_addresses().size());
}
TEST_F(BleScannerTest, TestDiscovery_ScanSuccessfulButNoRegisteredDevice) {
std::string valid_service_data_for_other_device = "abcd";
ASSERT_TRUE(valid_service_data_for_other_device.size() >=
kMinNumBytesInServiceData);
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
InvokeDiscoveryStartedCallback(true /* success */);
// Device with valid service data connected, but there was no registered
// device corresponding to the one that just connected.
mock_local_device_data_provider_->SetPublicKey(
base::MakeUnique<std::string>(fake_local_public_key));
mock_local_device_data_provider_->SetBeaconSeeds(
base::MakeUnique<std::vector<cryptauth::BeaconSeed>>(test_beacon_seeds_));
MockBluetoothDeviceWithServiceData device(
mock_adapter_.get(), kDefaultBluetoothAddress,
valid_service_data_for_other_device);
ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
EXPECT_EQ(1, mock_eid_generator_->num_identify_calls());
EXPECT_EQ(0u, test_observer_->device_addresses().size());
}
TEST_F(BleScannerTest, TestDiscovery_Success) {
std::string valid_service_data_for_registered_device = "abcde";
ASSERT_TRUE(valid_service_data_for_registered_device.size() >=
kMinNumBytesInServiceData);
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
InvokeDiscoveryStartedCallback(true /* success */);
// Registered device connects.
MockBluetoothDeviceWithServiceData device(
mock_adapter_.get(), kDefaultBluetoothAddress,
valid_service_data_for_registered_device);
mock_eid_generator_->set_identified_device(&test_devices_[0]);
ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
EXPECT_EQ(1, mock_eid_generator_->num_identify_calls());
EXPECT_EQ(1u, test_observer_->device_addresses().size());
EXPECT_EQ(device.GetAddress(), test_observer_->device_addresses()[0]);
EXPECT_EQ(1u, test_observer_->remote_devices().size());
EXPECT_EQ(test_devices_[0], test_observer_->remote_devices()[0]);
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
EXPECT_EQ(1, mock_eid_generator_->num_identify_calls());
EXPECT_EQ(1u, test_observer_->device_addresses().size());
InvokeStopDiscoveryCallback(true /* success */);
}
TEST_F(BleScannerTest, TestDiscovery_MultipleObservers) {
TestBleScannerObserver extra_observer;
ble_scanner_->AddObserver(&extra_observer);
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
InvokeDiscoveryStartedCallback(true /* success */);
MockBluetoothDeviceWithServiceData mock_bluetooth_device(
mock_adapter_.get(), kDefaultBluetoothAddress, "fakeServiceData");
mock_eid_generator_->set_identified_device(&test_devices_[0]);
ble_scanner_->DeviceAdded(mock_adapter_.get(), &mock_bluetooth_device);
EXPECT_EQ(1u, test_observer_->device_addresses().size());
EXPECT_EQ(mock_bluetooth_device.GetAddress(),
test_observer_->device_addresses()[0]);
EXPECT_EQ(1u, test_observer_->remote_devices().size());
EXPECT_EQ(test_devices_[0], test_observer_->remote_devices()[0]);
EXPECT_EQ(1u, extra_observer.device_addresses().size());
EXPECT_EQ(mock_bluetooth_device.GetAddress(),
extra_observer.device_addresses()[0]);
EXPECT_EQ(1u, extra_observer.remote_devices().size());
EXPECT_EQ(test_devices_[0], extra_observer.remote_devices()[0]);
// Now, unregister both observers.
ble_scanner_->RemoveObserver(test_observer_.get());
ble_scanner_->RemoveObserver(&extra_observer);
// Now, simulate another scan being received. The observers should not be
// notified since they are unregistered, so they should still have a call
// count of 1.
ble_scanner_->DeviceAdded(mock_adapter_.get(), &mock_bluetooth_device);
EXPECT_EQ(1u, test_observer_->device_addresses().size());
EXPECT_EQ(1u, extra_observer.device_addresses().size());
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
// Note: Cannot use InvokeStopDiscoveryCallback() since that function
// internally verifies observer callbacks, but the observers have been
// unregistered in this case.
EXPECT_FALSE(last_stop_callback_.is_null());
last_stop_callback_.Run();
}
TEST_F(BleScannerTest, TestRegistrationLimit) {
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[1]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[1].GetDeviceId()));
// Attempt to register another device. Registration should fail since the
// maximum number of devices have already been registered.
ASSERT_EQ(2u, kMaxConcurrentAdvertisements);
EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[2]));
EXPECT_FALSE(IsDeviceRegistered(test_devices_[2].GetDeviceId()));
// Unregistering a device which is not registered should also return false.
EXPECT_FALSE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[2]));
EXPECT_FALSE(IsDeviceRegistered(test_devices_[2].GetDeviceId()));
// Unregister device 0.
EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
EXPECT_FALSE(IsDeviceRegistered(test_devices_[0].GetDeviceId()));
// Now, device 2 can be registered.
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[2]));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[2].GetDeviceId()));
// Now, unregister the devices.
EXPECT_TRUE(IsDeviceRegistered(test_devices_[1].GetDeviceId()));
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[1]));
EXPECT_FALSE(IsDeviceRegistered(test_devices_[1].GetDeviceId()));
EXPECT_TRUE(IsDeviceRegistered(test_devices_[2].GetDeviceId()));
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[2]));
EXPECT_FALSE(IsDeviceRegistered(test_devices_[2].GetDeviceId()));
}
TEST_F(BleScannerTest, TestStartAndStopCallbacks_Success) {
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
InvokeDiscoveryStartedCallback(true /* success */);
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[1]));
// Registering device 1 should not have triggered a new discovery session from
// being created since one already existed.
EXPECT_TRUE(last_discovery_callback_.is_null());
EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
// Unregistering device 0 should not have triggered a stopped session since
// a device is still registered.
EXPECT_TRUE(last_discovery_callback_.is_null());
EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
// Device 1 is the only device remaining, so unregistering it should trigger
// the session to stop.
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[1]));
EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
InvokeStopDiscoveryCallback(true /* success */);
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
}
TEST_F(BleScannerTest, TestStartAndStopCallbacks_Errors) {
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
// Fail to start discovery session.
InvokeDiscoveryStartedCallback(false /* success */);
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
// Since the previous try failed, a new one should have been attempted. Let
// that one fail as well.
InvokeDiscoveryStartedCallback(false /* success */);
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
// Now, let it succeed.
InvokeDiscoveryStartedCallback(true /* success */);
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
// Now, unregister it, but fail to stop the discovery session.
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive());
InvokeStopDiscoveryCallback(false /* success */);
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
// Since the previous try failed, a new stop should have been attempted. Let
// that one fail as well.
InvokeStopDiscoveryCallback(false /* success */);
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
// Now, let it succeed.
InvokeStopDiscoveryCallback(true /* success */);
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
}
TEST_F(BleScannerTest, TestStartAndStopCallbacks_UnregisterBeforeStarted) {
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
// Before invoking the discovery callback, unregister the device.
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive());
// Complete the start discovery successfully.
InvokeDiscoveryStartedCallback(true /* success */);
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
// Because the session should not be active (i.e., there are no registered
// devices), a stop should be triggered.
InvokeStopDiscoveryCallback(true /* success */);
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
}
TEST_F(BleScannerTest, TestStartAndStopCallbacks_UnregisterBeforeStartFails) {
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
// Before invoking the discovery callback, unregister the device.
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive());
// Fail to start discovery session.
InvokeDiscoveryStartedCallback(false /* success */);
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
// Because the session should not be active (i.e., there are no registered
// devices), a new attempt should not have occurred.
EXPECT_TRUE(last_discovery_callback_.is_null());
EXPECT_TRUE(last_discovery_error_callback_.is_null());
}
TEST_F(BleScannerTest, TestStartAndStopCallbacks_RegisterBeforeStopFails) {
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive());
// Start discovery session.
InvokeDiscoveryStartedCallback(true /* success */);
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
// Unregister device to attempt a stop.
EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
// Before the stop completes, register the device again.
EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive());
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
// Fail to stop.
InvokeStopDiscoveryCallback(false /* success */);
EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive());
// Since there is a device registered again, there should not be another
// attempt to stop.
EXPECT_TRUE(last_stop_callback_.is_null());
EXPECT_TRUE(last_stop_error_callback_.is_null());
}
} // namespace tether
} // namespace chromeos