blob: 7f175018c21aa0f48667a7d80167857ea8abdb96 [file] [log] [blame]
// Copyright 2021 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 "ash/quick_pair/scanning/fast_pair/fast_pair_scanner_impl.h"
#include <memory>
#include "ash/quick_pair/common/constants.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_low_energy_scan_filter.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "device/bluetooth/test/mock_bluetooth_device.h"
#include "device/bluetooth/test/mock_bluetooth_low_energy_scan_session.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
// Below constants are used to construct MockBluetoothDevice for testing.
constexpr char kTestBleDeviceAddress[] = "11:12:13:14:15:16";
constexpr char kTestBleDeviceName[] = "Test Device Name";
std::unique_ptr<device::MockBluetoothDevice> CreateTestBluetoothDevice() {
auto mock_device =
std::make_unique<testing::NiceMock<device::MockBluetoothDevice>>(
/*adapter=*/nullptr, /*bluetooth_class=*/0, kTestBleDeviceName,
kTestBleDeviceAddress, /*paired=*/true, /*connected=*/true);
mock_device->AddUUID(ash::quick_pair::kFastPairBluetoothUuid);
mock_device->SetServiceDataForUUID(ash::quick_pair::kFastPairBluetoothUuid,
{1, 2, 3});
return mock_device;
}
} // namespace
namespace ash {
namespace quick_pair {
class FakeBluetoothAdapter
: public testing::NiceMock<device::MockBluetoothAdapter> {
public:
void AddDevice() {
auto mock_device = CreateTestBluetoothDevice();
auto* mock_device_ptr = mock_device.get();
AddMockDevice(std::move(mock_device));
for (auto& observer : GetObservers())
observer.DeviceAdded(this, mock_device_ptr);
}
void RemoveDevice() {
auto mock_device = RemoveMockDevice(kTestBleDeviceAddress);
for (auto& observer : GetObservers())
observer.DeviceRemoved(this, mock_device.get());
}
void ChangeDevice() {
auto mock_device = CreateTestBluetoothDevice();
auto* mock_device_ptr = mock_device.get();
mock_device->SetServiceDataForUUID(ash::quick_pair::kFastPairBluetoothUuid,
{4, 5, 6});
for (auto& observer : GetObservers())
observer.DeviceChanged(this, mock_device_ptr);
}
private:
~FakeBluetoothAdapter() override = default;
};
class FastPairScannerObserver : public FastPairScanner::Observer {
public:
// FastPairScanner::Observer overrides
void OnDeviceFound(device::BluetoothDevice* device) override {
device_addreses_.push_back(device->GetAddress());
on_device_found_count_++;
}
void OnDeviceLost(device::BluetoothDevice* device) override {
device_addreses_.erase(std::find(device_addreses_.begin(),
device_addreses_.end(),
device->GetAddress()));
}
bool DoesDeviceListContainTestDevice() {
return std::find(device_addreses_.begin(), device_addreses_.end(),
kTestBleDeviceAddress) != device_addreses_.end();
}
int on_device_found_count() { return on_device_found_count_; }
private:
std::vector<std::string> device_addreses_;
int on_device_found_count_ = 0;
};
class FastPairScannerTest : public testing::Test {
public:
void SetUp() override {
adapter_ = base::MakeRefCounted<FakeBluetoothAdapter>();
ON_CALL(*adapter_, StartLowEnergyScanSession(testing::_, testing::_))
.WillByDefault(
Invoke(this, &FastPairScannerTest::StartLowEnergyScanSession));
device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
EXPECT_CALL(adapter(), AddObserver);
scanner_ = base::MakeRefCounted<FastPairScannerImpl>();
scanner_observer_ = std::make_unique<FastPairScannerObserver>();
scanner().AddObserver(scanner_observer_.get());
}
void TearDown() override {
EXPECT_CALL(adapter(), RemoveObserver(scanner_.get()));
scanner().RemoveObserver(scanner_observer_.get());
}
std::unique_ptr<device::BluetoothLowEnergyScanSession>
StartLowEnergyScanSession(
std::unique_ptr<device::BluetoothLowEnergyScanFilter> filter,
base::WeakPtr<device::BluetoothLowEnergyScanSession::Delegate> delegate) {
auto mock_scan_session =
std::make_unique<device::MockBluetoothLowEnergyScanSession>(
base::BindOnce(&FastPairScannerTest::OnScanSessionDestroyed,
weak_ptr_factory_.GetWeakPtr()));
mock_scan_session_ = mock_scan_session.get();
delegate_ = delegate;
return mock_scan_session;
}
void OnScanSessionDestroyed() { mock_scan_session_ = nullptr; }
FakeBluetoothAdapter& adapter() { return *(adapter_.get()); }
device::MockBluetoothLowEnergyScanSession* scan_session() {
return mock_scan_session_;
}
FastPairScannerObserver& scanner_observer() {
return *(scanner_observer_.get());
}
FastPairScanner& scanner() { return *(scanner_.get()); }
void TriggerOnDeviceFound() {
delegate_->OnDeviceFound(mock_scan_session_,
CreateTestBluetoothDevice().get());
}
void TriggerOnDeviceLost() {
delegate_->OnDeviceLost(mock_scan_session_,
CreateTestBluetoothDevice().get());
}
protected:
scoped_refptr<FakeBluetoothAdapter> adapter_;
scoped_refptr<FastPairScannerImpl> scanner_;
device::MockBluetoothLowEnergyScanSession* mock_scan_session_ = nullptr;
std::unique_ptr<FastPairScannerObserver> scanner_observer_;
base::WeakPtr<device::BluetoothLowEnergyScanSession::Delegate> delegate_;
base::WeakPtrFactory<FastPairScannerTest> weak_ptr_factory_{this};
};
TEST_F(FastPairScannerTest, DeviceAddedNotifiesObservers) {
TriggerOnDeviceFound();
EXPECT_TRUE(scanner_observer().DoesDeviceListContainTestDevice());
}
TEST_F(FastPairScannerTest, DeviceLostNotifiesObservers) {
TriggerOnDeviceFound();
EXPECT_TRUE(scanner_observer().DoesDeviceListContainTestDevice());
TriggerOnDeviceLost();
EXPECT_FALSE(scanner_observer().DoesDeviceListContainTestDevice());
}
TEST_F(FastPairScannerTest, DeviceChangedNotifiesObservors) {
TriggerOnDeviceFound();
EXPECT_EQ(scanner_observer().on_device_found_count(), 1);
adapter().ChangeDevice();
EXPECT_EQ(scanner_observer().on_device_found_count(), 2);
}
} // namespace quick_pair
} // namespace ash