Increase plugin life time

A plugin is created when it is first needed and destroyed when the FP device
is destroyed. This allows the plugins to keep state during long running
operations such as presenting a UI query.

PiperOrigin-RevId: 543502491
This commit is contained in:
Janusz Sobczak
2023-06-26 11:58:56 -07:00
committed by Copybara-Service
parent c5c65714a0
commit 33abd7d879
7 changed files with 76 additions and 9 deletions
+2
View File
@@ -40,8 +40,10 @@ cc_library(
visibility = ["//fastpair:__subpackages__"],
deps = [
"//fastpair/common",
"//internal/base",
"//internal/platform:logging",
"//internal/platform:types",
"@com_google_absl//absl/functional:any_invocable",
],
)
@@ -47,7 +47,10 @@ void FastPairDeviceRepository::RemoveDevice(const FastPairDevice* device) {
// Tasks running in the background may still be referencing `device`. Defering
// the destruction to the background thread should prevent use-after-free
// errors.
executor_->Execute([fast_pair_device = std::move(fast_pair_device)]() {
executor_->Execute([this, fast_pair_device = std::move(fast_pair_device)]() {
for (auto* callback : observers_.GetObservers()) {
(*callback)(*fast_pair_device);
}
NEARBY_LOGS(VERBOSE) << "Destroyed FP device: " << fast_pair_device;
});
}
@@ -19,7 +19,9 @@
#include <optional>
#include <vector>
#include "absl/functional/any_invocable.h"
#include "fastpair/common/fast_pair_device.h"
#include "internal/base/observer_list.h"
#include "internal/platform/mutex.h"
#include "internal/platform/single_thread_executor.h"
@@ -29,6 +31,12 @@ namespace fastpair {
// Owner of `FastPairDevice` instances.
class FastPairDeviceRepository {
public:
// Called on the background thread right before `device` is destroyed.
// The callbacks are not called when FastPairDeviceRepository is
// destructing.
using RemoveDeviceCallback =
absl::AnyInvocable<void(const FastPairDevice& device)>;
explicit FastPairDeviceRepository(SingleThreadExecutor* executor)
: executor_(executor) {}
@@ -46,12 +54,20 @@ class FastPairDeviceRepository {
// or BLE.
std::optional<FastPairDevice*> FindDevice(absl::string_view mac_address);
void AddObserver(RemoveDeviceCallback* observer) {
observers_.AddObserver(observer);
}
void RemoveObserver(RemoveDeviceCallback* observer) {
observers_.RemoveObserver(observer);
}
private:
// Removes `device` from `devices_`.
std::unique_ptr<FastPairDevice> ExtractDevice(const FastPairDevice* device);
Mutex mutex_;
SingleThreadExecutor* executor_;
std::vector<std::unique_ptr<FastPairDevice>> devices_ ABSL_GUARDED_BY(mutex_);
ObserverList<RemoveDeviceCallback> observers_;
};
} // namespace fastpair
@@ -100,6 +100,19 @@ TEST(FastPairDeviceRepositoryTest, RemovingNonRegisteredDeviceIsSafe) {
EXPECT_FALSE(repo.FindDevice(kBleAddress).has_value());
}
TEST(FastPairDeviceRepositoryTest, RemovingDeviceCallsCallback) {
SingleThreadExecutor executor;
FastPairDeviceRepository repo(&executor);
FastPairDevice* device = repo.AddDevice(std::make_unique<FastPairDevice>(
kModelId, kBleAddress, Protocol::kFastPairInitialPairing));
FastPairDeviceRepository::RemoveDeviceCallback callback =
[&](const FastPairDevice& device) {};
repo.AddObserver(&callback);
repo.RemoveDevice(device);
EXPECT_FALSE(repo.FindDevice(kBleAddress).has_value());
}
} // namespace
} // namespace fastpair