| Index: chromeos/components/tether/ble_scanner_unittest.cc
|
| diff --git a/chromeos/components/tether/ble_scanner_unittest.cc b/chromeos/components/tether/ble_scanner_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b2b9bbcae487761f48d68f518fe43f33e41d39a4
|
| --- /dev/null
|
| +++ b/chromeos/components/tether/ble_scanner_unittest.cc
|
| @@ -0,0 +1,620 @@
|
| +// 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/logging.h"
|
| +#include "chromeos/components/tether/ble_constants.h"
|
| +#include "chromeos/components/tether/mock_local_device_data_provider.h"
|
| +#include "components/cryptauth/mock_eid_generator.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 MockBleScannerObserver : public BleScanner::Observer {
|
| + public:
|
| + MockBleScannerObserver() {}
|
| +
|
| + void OnReceivedAdvertisementFromDevice(
|
| + const device::BluetoothDevice* bluetooth_device,
|
| + cryptauth::RemoteDevice remote_device) override {
|
| + bluetooth_devices_.push_back(bluetooth_device);
|
| + remote_devices_.push_back(remote_device);
|
| + }
|
| +
|
| + int GetNumCalls() { return static_cast<int>(bluetooth_devices_.size()); }
|
| +
|
| + std::vector<const device::BluetoothDevice*>& bluetooth_devices() {
|
| + return bluetooth_devices_;
|
| + }
|
| +
|
| + std::vector<cryptauth::RemoteDevice>& remote_devices() {
|
| + return remote_devices_;
|
| + }
|
| +
|
| + private:
|
| + std::vector<const device::BluetoothDevice*> bluetooth_devices_;
|
| + std::vector<cryptauth::RemoteDevice> remote_devices_;
|
| +};
|
| +
|
| +class MockBluetoothDeviceWithServiceData : public device::MockBluetoothDevice {
|
| + public:
|
| + MockBluetoothDeviceWithServiceData(device::MockBluetoothAdapter* adapter,
|
| + const std::string& service_data)
|
| + : device::MockBluetoothDevice(adapter,
|
| + /* bluetooth_class */ 0,
|
| + "name",
|
| + "11:22:33:44:55:66",
|
| + 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 int kExpectedDiscoveryRSSI = -90;
|
| +const size_t kMinNumBytesInServiceData = 4;
|
| +
|
| +const std::string fake_local_public_key = "fakeLocalPublicKey";
|
| +
|
| +const std::string current_eid_data = "currentEidData";
|
| +const int64_t current_eid_start_ms = 1000L;
|
| +const int64_t current_eid_end_ms = 2000L;
|
| +
|
| +const std::string adjacent_eid_data = "adjacentEidData";
|
| +const int64_t adjacent_eid_start_ms = 2000L;
|
| +const int64_t adjacent_eid_end_ms = 3000L;
|
| +
|
| +const std::string 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 std::string 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::EidGenerator::EidData>
|
| +CreateFakeBackgroundScanFilter() {
|
| + cryptauth::EidGenerator::DataWithTimestamp current(
|
| + current_eid_data, current_eid_start_ms, current_eid_end_ms);
|
| +
|
| + std::unique_ptr<cryptauth::EidGenerator::DataWithTimestamp> adjacent =
|
| + base::MakeUnique<cryptauth::EidGenerator::DataWithTimestamp>(
|
| + adjacent_eid_data, adjacent_eid_start_ms, adjacent_eid_end_ms);
|
| +
|
| + return base::MakeUnique<cryptauth::EidGenerator::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 TestDelegate : public BleScanner::Delegate {
|
| + public:
|
| + TestDelegate()
|
| + : is_bluetooth_adapter_available_(true),
|
| + last_get_adapter_callback_(nullptr) {}
|
| +
|
| + ~TestDelegate() override {}
|
| +
|
| + bool IsBluetoothAdapterAvailable() const override {
|
| + return is_bluetooth_adapter_available_;
|
| + }
|
| +
|
| + void set_is_bluetooth_adapter_available(
|
| + bool is_bluetooth_adapter_available) {
|
| + is_bluetooth_adapter_available_ = is_bluetooth_adapter_available;
|
| + }
|
| +
|
| + void GetAdapter(const device::BluetoothAdapterFactory::AdapterCallback&
|
| + callback) override {
|
| + last_get_adapter_callback_ = callback;
|
| + }
|
| +
|
| + const device::BluetoothAdapterFactory::AdapterCallback
|
| + last_get_adapter_callback() {
|
| + return last_get_adapter_callback_;
|
| + }
|
| +
|
| + const std::vector<uint8_t>* GetServiceDataForUUID(
|
| + const device::BluetoothUUID& service_uuid,
|
| + device::BluetoothDevice* bluetooth_device) override {
|
| + if (device::BluetoothUUID(kAdvertisingServiceUuid) == service_uuid) {
|
| + return reinterpret_cast<MockBluetoothDeviceWithServiceData*>(
|
| + bluetooth_device)
|
| + ->service_data();
|
| + }
|
| +
|
| + return nullptr;
|
| + }
|
| +
|
| + private:
|
| + bool is_bluetooth_adapter_available_;
|
| + device::BluetoothAdapterFactory::AdapterCallback last_get_adapter_callback_;
|
| + };
|
| +
|
| + BleScannerTest()
|
| + : test_devices_(cryptauth::GenerateTestRemoteDevices(3)),
|
| + test_beacon_seeds_(CreateFakeBeaconSeeds()) {}
|
| +
|
| + void SetUp() override {
|
| + test_delegate_ = new TestDelegate();
|
| + EXPECT_TRUE(test_delegate_->IsBluetoothAdapterAvailable());
|
| + EXPECT_FALSE(test_delegate_->last_get_adapter_callback());
|
| +
|
| + mock_eid_generator_ = base::MakeUnique<cryptauth::MockEidGenerator>();
|
| + mock_eid_generator_->set_background_scan_filter(
|
| + CreateFakeBackgroundScanFilter());
|
| +
|
| + mock_local_device_data_provider_ =
|
| + base::MakeUnique<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_));
|
| +
|
| + mock_adapter_ =
|
| + make_scoped_refptr(new NiceMock<device::MockBluetoothAdapter>());
|
| + stored_discovery_filter_.reset();
|
| + stored_discovery_callback_.Reset();
|
| + stored_discovery_errback_.Reset();
|
| + ON_CALL(*mock_adapter_, StartDiscoverySessionWithFilterRaw(_, _, _))
|
| + .WillByDefault(Invoke(
|
| + this, &BleScannerTest::SaveStartDiscoverySessionWithFilterArgs));
|
| + ON_CALL(*mock_adapter_, IsPowered()).WillByDefault(Return(true));
|
| +
|
| + mock_discovery_session_ = nullptr;
|
| +
|
| + ble_scanner_ = base::WrapUnique(new BleScanner(
|
| + base::WrapUnique(test_delegate_), mock_eid_generator_.get(),
|
| + mock_local_device_data_provider_.get()));
|
| +
|
| + mock_observer_ = base::MakeUnique<MockBleScannerObserver>();
|
| + ble_scanner_->AddObserver(mock_observer_.get());
|
| + }
|
| +
|
| + void SaveStartDiscoverySessionWithFilterArgs(
|
| + const device::BluetoothDiscoveryFilter* discovery_filter,
|
| + const device::BluetoothAdapter::DiscoverySessionCallback& callback,
|
| + const device::BluetoothAdapter::ErrorCallback& errback) {
|
| + stored_discovery_filter_ =
|
| + base::MakeUnique<device::BluetoothDiscoveryFilter>(
|
| + device::BluetoothTransport::BLUETOOTH_TRANSPORT_LE);
|
| + stored_discovery_filter_->CopyFrom(*discovery_filter);
|
| + stored_discovery_callback_ = callback;
|
| + stored_discovery_errback_ = errback;
|
| + }
|
| +
|
| + void InvokeAdapterCallback() {
|
| + const device::BluetoothAdapterFactory::AdapterCallback
|
| + last_get_adapter_callback = test_delegate_->last_get_adapter_callback();
|
| + ASSERT_TRUE(last_get_adapter_callback);
|
| +
|
| + // Because the adapter has just been initialized, the discovery session
|
| + // should not have been started yet.
|
| + EXPECT_FALSE(stored_discovery_filter_);
|
| + EXPECT_TRUE(stored_discovery_callback_.is_null());
|
| + EXPECT_TRUE(stored_discovery_errback_.is_null());
|
| +
|
| + EXPECT_CALL(*mock_adapter_, AddObserver(ble_scanner_.get()));
|
| + last_get_adapter_callback.Run(mock_adapter_);
|
| +
|
| + // Once the adapter callback is returned, a discovery session should be
|
| + // started via that adapter.
|
| + AssertDiscoverySessionRequested();
|
| + }
|
| +
|
| + void AssertDiscoverySessionRequested() {
|
| + // First, ensure that the correct discovery filter was passed.
|
| + EXPECT_TRUE(stored_discovery_filter_);
|
| + EXPECT_EQ(device::BluetoothTransport::BLUETOOTH_TRANSPORT_LE,
|
| + stored_discovery_filter_->GetTransport());
|
| + int16_t observed_rssi;
|
| + ASSERT_TRUE(stored_discovery_filter_->GetRSSI(&observed_rssi));
|
| + EXPECT_EQ(kExpectedDiscoveryRSSI, observed_rssi);
|
| +
|
| + // Now, ensure that both a callback and errback were passed.
|
| + EXPECT_FALSE(stored_discovery_callback_.is_null());
|
| + EXPECT_FALSE(stored_discovery_errback_.is_null());
|
| + }
|
| +
|
| + void InvokeDiscoveryStartedCallback() {
|
| + EXPECT_FALSE(stored_discovery_callback_.is_null());
|
| +
|
| + mock_discovery_session_ = new device::MockBluetoothDiscoverySession();
|
| + stored_discovery_callback_.Run(base::WrapUnique(mock_discovery_session_));
|
| + }
|
| +
|
| + std::vector<cryptauth::RemoteDevice> test_devices_;
|
| + std::vector<cryptauth::BeaconSeed> test_beacon_seeds_;
|
| +
|
| + std::unique_ptr<MockBleScannerObserver> mock_observer_;
|
| +
|
| + TestDelegate* test_delegate_;
|
| + std::unique_ptr<cryptauth::MockEidGenerator> mock_eid_generator_;
|
| + std::unique_ptr<MockLocalDeviceDataProvider> mock_local_device_data_provider_;
|
| +
|
| + scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_adapter_;
|
| + device::MockBluetoothDiscoverySession* mock_discovery_session_;
|
| +
|
| + std::unique_ptr<device::BluetoothDiscoveryFilter> stored_discovery_filter_;
|
| + device::BluetoothAdapter::DiscoverySessionCallback stored_discovery_callback_;
|
| + device::BluetoothAdapter::ErrorCallback stored_discovery_errback_;
|
| +
|
| + std::unique_ptr<BleScanner> ble_scanner_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(BleScannerTest);
|
| +};
|
| +
|
| +TEST_F(BleScannerTest, TestNoBluetoothAdapter) {
|
| + test_delegate_->set_is_bluetooth_adapter_available(false);
|
| + EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_FALSE(test_delegate_->last_get_adapter_callback());
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestNoLocalBeaconSeeds) {
|
| + mock_local_device_data_provider_->SetBeaconSeeds(nullptr);
|
| + EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_FALSE(test_delegate_->last_get_adapter_callback());
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestNoBackgroundScanFilter) {
|
| + mock_eid_generator_->set_background_scan_filter(nullptr);
|
| + EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_FALSE(test_delegate_->last_get_adapter_callback());
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestAdapterDoesNotInitialize) {
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_TRUE(test_delegate_->last_get_adapter_callback());
|
| +
|
| + // Do not call the last GetAdapter() callback. The device should still be able
|
| + // to be unregistered.
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestAdapterDoesNotInitialize_MultipleDevicesRegistered) {
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[1]));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId()));
|
| + EXPECT_TRUE(test_delegate_->last_get_adapter_callback());
|
| +
|
| + // Do not call the last GetAdapter() callback. The devices should still be
|
| + // able to be unregistered.
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[1]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId()));
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestDiscoverySessionFailsToStart) {
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +
|
| + InvokeAdapterCallback();
|
| + stored_discovery_errback_.Run();
|
| +
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestDiscoveryStartsButNoDevicesFound) {
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +
|
| + InvokeAdapterCallback();
|
| + InvokeDiscoveryStartedCallback();
|
| +
|
| + // No devices found.
|
| +
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestDiscovery_NoServiceData) {
|
| + std::string empty_service_data = "";
|
| +
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +
|
| + InvokeAdapterCallback();
|
| + InvokeDiscoveryStartedCallback();
|
| +
|
| + // Device with no service data connected. Service data is required to identify
|
| + // the advertising device.
|
| + MockBluetoothDeviceWithServiceData device1(mock_adapter_.get(),
|
| + empty_service_data);
|
| + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device1);
|
| + EXPECT_FALSE(mock_eid_generator_->num_identify_calls());
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +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(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +
|
| + InvokeAdapterCallback();
|
| + InvokeDiscoveryStartedCallback();
|
| +
|
| + // Device with short service data connected. Service data of at least 4 bytes
|
| + // is required to identify the advertising device.
|
| + MockBluetoothDeviceWithServiceData device2(mock_adapter_.get(),
|
| + short_service_data);
|
| + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device2);
|
| + EXPECT_FALSE(mock_eid_generator_->num_identify_calls());
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +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(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +
|
| + InvokeAdapterCallback();
|
| + InvokeDiscoveryStartedCallback();
|
| +
|
| + // 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 device3(
|
| + mock_adapter_.get(), valid_service_data_for_other_device);
|
| + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device3);
|
| + EXPECT_FALSE(mock_eid_generator_->num_identify_calls());
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +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(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +
|
| + InvokeAdapterCallback();
|
| + InvokeDiscoveryStartedCallback();
|
| +
|
| + // 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 device4(
|
| + mock_adapter_.get(), valid_service_data_for_other_device);
|
| + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device4);
|
| + EXPECT_EQ(1, mock_eid_generator_->num_identify_calls());
|
| + EXPECT_FALSE(mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +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(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +
|
| + InvokeAdapterCallback();
|
| + InvokeDiscoveryStartedCallback();
|
| +
|
| + // Registered device connects.
|
| + MockBluetoothDeviceWithServiceData device5(
|
| + mock_adapter_.get(), valid_service_data_for_registered_device);
|
| + mock_eid_generator_->set_identified_device(&test_devices_[0]);
|
| + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device5);
|
| + EXPECT_EQ(1, mock_eid_generator_->num_identify_calls());
|
| + EXPECT_EQ(1, mock_observer_->GetNumCalls());
|
| + EXPECT_EQ(1, static_cast<int>(mock_observer_->bluetooth_devices().size()));
|
| + EXPECT_EQ(&device5, mock_observer_->bluetooth_devices()[0]);
|
| + EXPECT_EQ(1, static_cast<int>(mock_observer_->remote_devices().size()));
|
| + EXPECT_EQ(test_devices_[0], mock_observer_->remote_devices()[0]);
|
| +
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_EQ(1, mock_eid_generator_->num_identify_calls());
|
| + EXPECT_EQ(1, mock_observer_->GetNumCalls());
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestDiscovery_MultipleObservers) {
|
| + MockBleScannerObserver extra_observer;
|
| + ble_scanner_->AddObserver(&extra_observer);
|
| +
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +
|
| + InvokeAdapterCallback();
|
| + InvokeDiscoveryStartedCallback();
|
| +
|
| + MockBluetoothDeviceWithServiceData mock_bluetooth_device(mock_adapter_.get(),
|
| + "fakeServiceData");
|
| + mock_eid_generator_->set_identified_device(&test_devices_[0]);
|
| + ble_scanner_->DeviceAdded(mock_adapter_.get(), &mock_bluetooth_device);
|
| +
|
| + EXPECT_EQ(1, mock_observer_->GetNumCalls());
|
| + EXPECT_EQ(1, static_cast<int>(mock_observer_->bluetooth_devices().size()));
|
| + EXPECT_EQ(&mock_bluetooth_device, mock_observer_->bluetooth_devices()[0]);
|
| + EXPECT_EQ(1, static_cast<int>(mock_observer_->remote_devices().size()));
|
| + EXPECT_EQ(test_devices_[0], mock_observer_->remote_devices()[0]);
|
| +
|
| + EXPECT_EQ(1, extra_observer.GetNumCalls());
|
| + EXPECT_EQ(1, static_cast<int>(extra_observer.bluetooth_devices().size()));
|
| + EXPECT_EQ(&mock_bluetooth_device, extra_observer.bluetooth_devices()[0]);
|
| + EXPECT_EQ(1, static_cast<int>(extra_observer.remote_devices().size()));
|
| + EXPECT_EQ(test_devices_[0], extra_observer.remote_devices()[0]);
|
| +
|
| + // Now, unregister both observers.
|
| + ble_scanner_->RemoveObserver(mock_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(1, mock_observer_->GetNumCalls());
|
| + EXPECT_EQ(1, extra_observer.GetNumCalls());
|
| +
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestRegistrationLimit) {
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[1]));
|
| + EXPECT_TRUE(ble_scanner_->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(2, kMaxConcurrentAdvertisements);
|
| + EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[2]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->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(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[2].GetDeviceId()));
|
| +
|
| + // Unregister device 0.
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +
|
| + // Now, device 2 can be registered.
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[2]));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[2].GetDeviceId()));
|
| +
|
| + // Now, unregister the devices.
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[1]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId()));
|
| +
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[2].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[2]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[2].GetDeviceId()));
|
| +}
|
| +
|
| +TEST_F(BleScannerTest, TestAdapterPoweredChanged) {
|
| + // This test starts with the adapter powered on, then turns power off before
|
| + // discovery starts, then turns power back on and allows discovery to
|
| + // complete, then turns power back off again, and finally turns it back on to
|
| + // complete another discovery session.
|
| + EXPECT_CALL(*mock_adapter_, IsPowered())
|
| + .WillOnce(Return(true))
|
| + .WillOnce(Return(false))
|
| + .WillOnce(Return(true))
|
| + .WillOnce(Return(false))
|
| + .WillOnce(Return(true));
|
| +
|
| + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + InvokeAdapterCallback();
|
| +
|
| + // The discovery session should have been requested but not yet initialized.
|
| + EXPECT_TRUE(stored_discovery_filter_.get());
|
| + EXPECT_FALSE(mock_discovery_session_);
|
| +
|
| + // Turn the adapter off before the discovery session starts.
|
| + ble_scanner_->AdapterPoweredChanged(mock_adapter_.get(), false);
|
| +
|
| + // Turn the adapter back on, and finish initializing discovery this time.
|
| + ble_scanner_->AdapterPoweredChanged(mock_adapter_.get(), true);
|
| + InvokeDiscoveryStartedCallback();
|
| +
|
| + // The session should have been started.
|
| + device::MockBluetoothDiscoverySession* session1 = mock_discovery_session_;
|
| + EXPECT_NE(nullptr, session1);
|
| +
|
| + // Now turn the adapter off again.
|
| + ble_scanner_->AdapterPoweredChanged(mock_adapter_.get(), false);
|
| +
|
| + // Turn the adapter back on.
|
| + ble_scanner_->AdapterPoweredChanged(mock_adapter_.get(), true);
|
| + InvokeDiscoveryStartedCallback();
|
| +
|
| + // A new session should have started, so the session objects should not be the
|
| + // same.
|
| + device::MockBluetoothDiscoverySession* session2 = mock_discovery_session_;
|
| + EXPECT_NE(nullptr, session2);
|
| + EXPECT_NE(session1, session2);
|
| +
|
| + // Unregister device.
|
| + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0]));
|
| + EXPECT_FALSE(
|
| + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
|
| +}
|
| +
|
| +} // namespace tether
|
| +
|
| +} // namespace chromeos
|
|
|