From e295e2eca28a1998dcd4eb3fc0471968d04487f7 Mon Sep 17 00:00:00 2001 From: Vibhav Pant Date: Fri, 8 Sep 2023 16:48:00 +0530 Subject: [PATCH] Allow marking/unmarking devices as lost. --- .../linux/bluetooth_classic_device.cc | 3 +- .../linux/bluetooth_classic_device.h | 7 ++++ .../implementation/linux/bluetooth_devices.cc | 37 +++++++++++++++++-- .../implementation/linux/bluetooth_devices.h | 26 ++++++++++--- 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/internal/platform/implementation/linux/bluetooth_classic_device.cc b/internal/platform/implementation/linux/bluetooth_classic_device.cc index aa0c5373..2afa8db7 100644 --- a/internal/platform/implementation/linux/bluetooth_classic_device.cc +++ b/internal/platform/implementation/linux/bluetooth_classic_device.cc @@ -28,7 +28,8 @@ namespace linux { BluetoothDevice::BluetoothDevice(sdbus::IConnection &system_bus, sdbus::ObjectPath device_object_path) : ProxyInterfaces(system_bus, bluez::SERVICE_DEST, - std::move(device_object_path)) { + std::move(device_object_path)), + lost_(false) { registerProxy(); try { last_known_name_ = Alias(); diff --git a/internal/platform/implementation/linux/bluetooth_classic_device.h b/internal/platform/implementation/linux/bluetooth_classic_device.h index e29920e9..6d5d934d 100644 --- a/internal/platform/implementation/linux/bluetooth_classic_device.h +++ b/internal/platform/implementation/linux/bluetooth_classic_device.h @@ -15,6 +15,8 @@ #ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_CLASSIC_DEVICE_H_ #define PLATFORM_IMPL_LINUX_BLUETOOTH_CLASSIC_DEVICE_H_ +#include + #include #include #include @@ -69,6 +71,10 @@ class BluetoothDevice on_pair_reply_cb_ = DefaultCallback(); } + void MarkLost() { lost_ = true; } + void UnmarkLost() { lost_ = false; } + bool Lost() const { return lost_; } + protected: void onConnectProfileReply(const sdbus::Error *error) override; void onPairReply(const sdbus::Error *error) override { @@ -81,6 +87,7 @@ class BluetoothDevice absl::AnyInvocable on_pair_reply_cb_ = DefaultCallback(); UniqueId unique_id_; + std::atomic_bool lost_; mutable absl::Mutex properties_mutex_; mutable std::string last_known_name_ ABSL_GUARDED_BY(properties_mutex_); diff --git a/internal/platform/implementation/linux/bluetooth_devices.cc b/internal/platform/implementation/linux/bluetooth_devices.cc index c50b7b93..43a0d1e7 100644 --- a/internal/platform/implementation/linux/bluetooth_devices.cc +++ b/internal/platform/implementation/linux/bluetooth_devices.cc @@ -12,18 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include +#include #include #include "absl/synchronization/mutex.h" #include "internal/platform/implementation/linux/bluetooth_classic_device.h" #include "internal/platform/implementation/linux/bluetooth_devices.h" #include "internal/platform/implementation/linux/bluez.h" +#include "internal/platform/logging.h" namespace nearby { namespace linux { +static constexpr std::chrono::minutes kLostPeripheralsCleanupMinFreq(5); + std::shared_ptr BluetoothDevices::get_device_by_path( const sdbus::ObjectPath &device_object_path) { absl::ReaderMutexLock l(&devices_by_path_lock_); @@ -49,14 +54,40 @@ void BluetoothDevices::remove_device_by_path( devices_by_path_.erase(device_object_path); } +void BluetoothDevices::mark_peripheral_lost( + const sdbus::ObjectPath &device_object_path) { + absl::ReaderMutexLock lock(&devices_by_path_lock_); + if (devices_by_path_.count(device_object_path) == 0) { + NEARBY_LOGS(ERROR) << __func__ << ": Device " << device_object_path + << " doesn't exist"; + } + devices_by_path_[device_object_path]->MarkLost(); +} + +void BluetoothDevices::cleanup_lost_peripherals() { + auto now = std::chrono::steady_clock::now(); + absl::MutexLock lock(&devices_by_path_lock_); + if ((now - last_cleanup_) < kLostPeripheralsCleanupMinFreq) { + return; + } + last_cleanup_ = now; + + for (auto it = devices_by_path_.begin(), end = devices_by_path_.end(); + it != end;) { + auto copy = it++; + if (copy->second->Lost()) devices_by_path_.erase(copy); + } +} + std::shared_ptr BluetoothDevices::add_new_device( sdbus::ObjectPath device_object_path) { absl::MutexLock l(&devices_by_path_lock_); - auto pair = devices_by_path_.emplace( + auto [device_it, inserted] = devices_by_path_.emplace( std::string(device_object_path), - std::make_unique( + std::make_shared( system_bus_, std::move(device_object_path), observers_)); - return pair.first->second; + if (!inserted) device_it->second->UnmarkLost(); + return device_it->second; } } // namespace linux } // namespace nearby diff --git a/internal/platform/implementation/linux/bluetooth_devices.h b/internal/platform/implementation/linux/bluetooth_devices.h index 078dc0b2..448c289c 100644 --- a/internal/platform/implementation/linux/bluetooth_devices.h +++ b/internal/platform/implementation/linux/bluetooth_devices.h @@ -15,6 +15,7 @@ #ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_DEVICES_H_ #define PLATFORM_IMPL_LINUX_BLUETOOTH_DEVICES_H_ +#include #include #include @@ -24,6 +25,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/synchronization/mutex.h" #include "internal/base/observer_list.h" +#include "internal/platform/bluetooth_utils.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/linux/bluetooth_classic_device.h" @@ -41,19 +43,31 @@ class BluetoothDevices final { std::shared_ptr get_device_by_path(const sdbus::ObjectPath &) ABSL_LOCKS_EXCLUDED(devices_by_path_lock_); std::shared_ptr get_device_by_address(const std::string &); - void remove_device_by_path(const sdbus::ObjectPath &) - ABSL_LOCKS_EXCLUDED(devices_by_path_lock_); + std::shared_ptr get_device_by_unique_id( + api::ble_v2::BlePeripheral::UniqueId id) { + auto addr = BluetoothUtils::FromNumber(id); + return get_device_by_address(addr); + } + std::shared_ptr add_new_device(sdbus::ObjectPath) ABSL_LOCKS_EXCLUDED(devices_by_path_lock_); - private: - absl::Mutex devices_by_path_lock_; - absl::flat_hash_map> - devices_by_path_ ABSL_GUARDED_BY(devices_by_path_lock_); + void remove_device_by_path(const sdbus::ObjectPath &) + ABSL_LOCKS_EXCLUDED(devices_by_path_lock_); + void mark_peripheral_lost(const sdbus::ObjectPath &) + ABSL_LOCKS_EXCLUDED(devices_by_path_lock_); + void cleanup_lost_peripherals() ABSL_LOCKS_EXCLUDED(devices_by_path_lock_); + private: sdbus::IConnection &system_bus_; ObserverList &observers_; sdbus::ObjectPath adapter_object_path_; + + absl::Mutex devices_by_path_lock_; + absl::flat_hash_map> + devices_by_path_ ABSL_GUARDED_BY(devices_by_path_lock_); + std::chrono::time_point last_cleanup_ + ABSL_GUARDED_BY(devices_by_path_lock_); }; } // namespace linux } // namespace nearby