Introduce scanning sessions

FastPairScanner::ScanningSession and ScannerBroker::ScanningSession separate
the lifetime of FastPairScanner/ScannerBroker from the lifetime of scanning
sessions. This simplifies the cleanup.
PiperOrigin-RevId: 535675988
This commit is contained in:
Janusz Sobczak
2023-05-26 11:50:54 -07:00
committed by Copybara-Service
parent 4596f32499
commit 3adb98a5ff
13 changed files with 122 additions and 24 deletions
+3 -2
View File
@@ -40,10 +40,11 @@ void Mediator::OnDeviceLost(FastPairDevice& device) {
void Mediator::StartScanning() {
if (IsFastPairEnabled()) {
scanner_broker_->StartScanning(Protocol::kFastPairInitialPairing);
scanning_session_ =
scanner_broker_->StartScanning(Protocol::kFastPairInitialPairing);
return;
}
scanner_broker_->StopScanning(Protocol::kFastPairInitialPairing);
scanning_session_.reset();
}
bool Mediator::IsFastPairEnabled() {
@@ -42,6 +42,7 @@ class Mediator final : public ScannerBroker::Observer {
bool IsFastPairEnabled();
std::unique_ptr<ScannerBroker> scanner_broker_;
std::unique_ptr<ScannerBroker::ScanningSession> scanning_session_;
std::unique_ptr<FastPairRepository> fast_pair_repository_;
};
@@ -15,6 +15,8 @@
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAKE_FAST_PAIR_SCANNER_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAKE_FAST_PAIR_SCANNER_H_
#include <memory>
#include "fastpair/scanning/fastpair/fast_pair_scanner.h"
#include "internal/base/observer_list.h"
@@ -32,7 +34,9 @@ class FakeFastPairScanner final : public FastPairScanner {
void RemoveObserver(Observer* observer) override;
void NotifyDeviceFound(const BlePeripheral& peripheral);
void NotifyDeviceLost(const BlePeripheral& peripheral);
void StartScanning() override {};
std::unique_ptr<ScanningSession> StartScanning() override {
return std::make_unique<ScanningSession>();
};
private:
ObserverList<FastPairScanner::Observer> observer_;
@@ -36,10 +36,16 @@ class FastPairScanner {
virtual void OnDeviceLost(const BlePeripheral& peripheral) = 0;
};
// Represents scanning session. Must be destroyed before FastPairScanner.
class ScanningSession {
public:
virtual ~ScanningSession() = default;
};
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
virtual void StartScanning() = 0;
virtual std::unique_ptr<ScanningSession> StartScanning() = 0;
virtual ~FastPairScanner() = default;
};
@@ -30,6 +30,17 @@ namespace {
constexpr absl::Duration kFastPairLowPowerActiveSeconds = absl::Seconds(2);
constexpr absl::Duration kFastPairLowPowerInactiveSeconds = absl::Seconds(3);
constexpr char kFastPairServiceUuid[] = "0000FE2C-0000-1000-8000-00805F9B34FB";
class ScanningSessionImpl : public FastPairScanner::ScanningSession {
public:
explicit ScanningSessionImpl(FastPairScannerImpl* scanner)
: scanner_(scanner) {}
~ScanningSessionImpl() override { scanner_->StopScanning(); }
private:
FastPairScannerImpl* scanner_;
};
} // namespace
// FastPairScannerImpl
@@ -45,11 +56,14 @@ void FastPairScannerImpl::RemoveObserver(FastPairScanner::Observer* observer) {
observer_.RemoveObserver(observer);
}
void FastPairScannerImpl::StartScanning() {
std::unique_ptr<FastPairScanner::ScanningSession>
FastPairScannerImpl::StartScanning() {
NEARBY_LOGS(VERBOSE) << __func__;
executor_->Execute("scanning", [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
*executor_) { StartScanningInternal(); });
return std::make_unique<ScanningSessionImpl>(this);
}
void FastPairScannerImpl::StartScanningInternal() {
if (mediums_.GetBluetoothRadio().Enable() &&
mediums_.GetBle().IsAvailable() &&
@@ -80,7 +94,7 @@ void FastPairScannerImpl::StartScanningInternal() {
if (IsFastPairLowPowerEnabled()) {
StartTimer(kFastPairLowPowerActiveSeconds,
[this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) {
StopScanning();
PauseScanning();
});
}
} else {
@@ -90,6 +104,14 @@ void FastPairScannerImpl::StartScanningInternal() {
}
void FastPairScannerImpl::StopScanning() {
executor_->Execute("stop-scan",
[this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) {
timer_.reset();
mediums_.GetBle().StopScanning(kServiceId);
});
}
void FastPairScannerImpl::PauseScanning() {
DCHECK(IsFastPairLowPowerEnabled());
mediums_.GetBle().StopScanning(kServiceId);
StartTimer(kFastPairLowPowerInactiveSeconds,
@@ -49,11 +49,13 @@ class FastPairScannerImpl : public FastPairScanner {
// Todo(b/267348348): Support Flags to control feature ramp
bool IsFastPairLowPowerEnabled() const { return false; }
void StartScanning() override;
std::unique_ptr<ScanningSession> StartScanning() override;
void StopScanning();
private:
void StartScanningInternal() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_);
void StopScanning() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_);
// Pauses, and then restarts, scanning for a few seconds to safe power.
void PauseScanning() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_);
void StartTimer(absl::Duration delay, absl::AnyInvocable<void()> callback)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_);
@@ -65,8 +67,6 @@ class FastPairScannerImpl : public FastPairScanner {
// seen.
absl::flat_hash_map<std::string, std::set<std::string>>
device_address_advertisement_data_map_;
BluetoothAdapter bluetooth_adapter_;
ObserverList<FastPairScanner::Observer> observer_;
};
@@ -32,6 +32,7 @@ namespace fastpair {
namespace {
constexpr absl::Duration kTaskWaitTimeout = absl::Milliseconds(1000);
constexpr absl::Duration kShortTimeout = absl::Milliseconds(100);
constexpr absl::string_view kServiceID{"Fast Pair"};
constexpr absl::string_view kModelId{"718c17"};
constexpr absl::string_view kFastPairServiceUuid{
@@ -85,7 +86,7 @@ TEST_F(FastPairScannerImplTest, StartScanning) {
service_id, advertisement_bytes, fast_pair_service_uuid);
// Fast Pair scanner startScanning
scanner->StartScanning();
auto scan_session = scanner->StartScanning();
// Notify device found
EXPECT_TRUE(accept_latch.Await(kTaskWaitTimeout).result());
@@ -93,9 +94,35 @@ TEST_F(FastPairScannerImplTest, StartScanning) {
mediums_2.GetBle().GetMedium().StopAdvertising(service_id);
// Notify device lost
EXPECT_TRUE(lost_latch.Await(kTaskWaitTimeout).result());
scan_session.reset();
env_.Stop();
}
TEST_F(FastPairScannerImplTest, StopScanning) {
env_.Start();
// Create Fast Pair Scanner and add its observer
Mediums mediums_1;
auto scanner = std::make_unique<FastPairScannerImpl>(mediums_1, &executor_);
CountDownLatch accept_latch(1);
CountDownLatch lost_latch(1);
FastPairScannerObserver observer(scanner.get(), &accept_latch, &lost_latch);
// Create Advertiser and startAdvertising
Mediums mediums_2;
std::string service_id(kServiceID);
ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)};
std::string fast_pair_service_uuid(kFastPairServiceUuid);
mediums_2.GetBle().GetMedium().StartAdvertising(
service_id, advertisement_bytes, fast_pair_service_uuid);
auto scan_session = scanner->StartScanning();
scan_session.reset();
mediums_2.GetBle().GetMedium().StopAdvertising(service_id);
// Device lost event should not be delivered when scan session has terminated.
EXPECT_FALSE(lost_latch.Await(kShortTimeout).result());
env_.Stop();
}
} // namespace
} // namespace fastpair
} // namespace nearby
+2 -2
View File
@@ -24,8 +24,8 @@ namespace fastpair {
class MockScannerBroker : public ScannerBroker {
public:
MOCK_METHOD(void, StartScanning, (Protocol), (override));
MOCK_METHOD(void, StopScanning, (Protocol), (override));
MOCK_METHOD(std::unique_ptr<ScanningSession>, StartScanning, (Protocol),
(override));
void AddObserver(Observer* observer) override {
observers_.AddObserver(observer);
+7 -2
View File
@@ -15,6 +15,8 @@
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_H_
#include <memory>
#include "fastpair/common/fast_pair_device.h"
#include "fastpair/common/protocol.h"
@@ -35,14 +37,17 @@ class ScannerBroker {
virtual void OnDeviceFound(FastPairDevice& device) = 0;
virtual void OnDeviceLost(FastPairDevice& device) = 0;
};
class ScanningSession {
public:
virtual ~ScanningSession() = default;
};
virtual ~ScannerBroker() = default;
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
virtual void StartScanning(Protocol protocol) = 0;
virtual void StopScanning(Protocol protocol) = 0;
virtual std::unique_ptr<ScanningSession> StartScanning(Protocol protocol) = 0;
};
} // namespace fastpair
+25 -5
View File
@@ -15,6 +15,7 @@
#include "fastpair/scanning/scanner_broker_impl.h"
#include <memory>
#include <utility>
#include "absl/functional/bind_front.h"
#include "fastpair/common/fast_pair_device.h"
@@ -24,6 +25,22 @@
namespace nearby {
namespace fastpair {
namespace {
class ScanningSessionImpl : public ScannerBroker::ScanningSession {
public:
ScanningSessionImpl(ScannerBrokerImpl* scanner, Protocol protocol)
: scanner_(scanner), protocol_(protocol) {}
~ScanningSessionImpl() override { scanner_->StopScanning(protocol_); }
private:
ScannerBrokerImpl* scanner_;
Protocol protocol_;
};
} // namespace
ScannerBrokerImpl::ScannerBrokerImpl(
Mediums& mediums, SingleThreadExecutor* executor,
FastPairDeviceRepository* device_repository)
@@ -39,12 +56,14 @@ void ScannerBrokerImpl::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
void ScannerBrokerImpl::StartScanning(Protocol protocol) {
std::unique_ptr<ScannerBroker::ScanningSession>
ScannerBrokerImpl::StartScanning(Protocol protocol) {
NEARBY_LOGS(VERBOSE) << __func__ << ": protocol=" << protocol;
executor_->Execute("start-scan",
[this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) {
StartFastPairScanning();
});
return std::make_unique<ScanningSessionImpl>(this, protocol);
}
void ScannerBrokerImpl::StopScanning(Protocol protocol) {
@@ -63,14 +82,15 @@ void ScannerBrokerImpl::StartFastPairScanning() {
absl::bind_front(&ScannerBrokerImpl::NotifyDeviceFound, this),
absl::bind_front(&ScannerBrokerImpl::NotifyDeviceLost, this),
executor_, device_repository_);
scanner_->StartScanning();
scanning_session_ = scanner_->StartScanning();
}
void ScannerBrokerImpl::StopFastPairScanning() {
fast_pair_discoverable_scanner_.reset();
scanner_.reset();
observers_.Clear();
NEARBY_LOGS(VERBOSE) << __func__ << "Stopping Fast Pair Scanning.";
scanning_session_.reset();
observers_.Clear();
DestroyOnExecutor(std::move(fast_pair_discoverable_scanner_), executor_);
DestroyOnExecutor(std::move(scanner_), executor_);
}
void ScannerBrokerImpl::NotifyDeviceFound(FastPairDevice& device) {
+3 -2
View File
@@ -38,8 +38,8 @@ class ScannerBrokerImpl : public ScannerBroker {
// ScannerBroker:
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
void StartScanning(Protocol protocol) override;
void StopScanning(Protocol protocol) override;
std::unique_ptr<ScanningSession> StartScanning(Protocol protocol) override;
void StopScanning(Protocol protocol);
private:
void StartFastPairScanning() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_);
@@ -54,6 +54,7 @@ class ScannerBrokerImpl : public ScannerBroker {
ABSL_GUARDED_BY(*executor_);
ObserverList<Observer> observers_;
FastPairDeviceRepository* device_repository_;
std::unique_ptr<FastPairScanner::ScanningSession> scanning_session_;
};
} // namespace fastpair
@@ -99,7 +99,8 @@ TEST_F(ScannerBrokerImplTest, CanStartScanning) {
service_id, advertisement_bytes, fast_pair_service_uuid);
// Fast Pair scanner startScanning
scanner_broker->StartScanning(Protocol::kFastPairInitialPairing);
auto scanning_session =
scanner_broker->StartScanning(Protocol::kFastPairInitialPairing);
// Notify device found
EXPECT_TRUE(accept_latch.Await(kTaskWaitTimeout).result());
@@ -109,6 +110,7 @@ TEST_F(ScannerBrokerImplTest, CanStartScanning) {
// Notify device lost
EXPECT_TRUE(lost_latch.Await(kTaskWaitTimeout).result());
scanning_session.reset();
env_.Stop();
}
} // namespace
@@ -34,6 +34,15 @@ class ABSL_LOCKABLE SingleThreadExecutor : public SubmittableExecutor {
SingleThreadExecutor& operator=(SingleThreadExecutor&&) = default;
};
// Moves the object to `executor` and destroys it there.
// This pattern is useful when there are some tasks running on `executor` that
// hold a reference to `object`. The tasks will complete before `object` is
// destroyed.
template <typename T>
void DestroyOnExecutor(T object, SingleThreadExecutor* executor) {
executor->Execute([object = std::move(object)] {});
}
} // namespace nearby
#endif // PLATFORM_PUBLIC_SINGLE_THREAD_EXECUTOR_H_