From dbd42b0de35bf36ba9e2fa4cc6cb457140c2797d Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Thu, 8 Jun 2023 10:08:49 -0700 Subject: [PATCH] Handle GATT query in separate thread PiperOrigin-RevId: 538819295 --- .../flags/nearby_connections_feature_flags.h | 4 + .../ble_v2/discovered_peripheral_tracker.cc | 99 +++++++++++++++++-- .../ble_v2/discovered_peripheral_tracker.h | 16 ++- 3 files changed, 109 insertions(+), 10 deletions(-) diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index dd9f3a47..cd2d771e 100644 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -36,6 +36,10 @@ constexpr auto kEnableBleV2 = constexpr auto kBlePeripheralLostTimeoutMillis = flags::Flag(kConfigPackage, "45411439", 12000); +// Enable/Disable GATT query during scanning. +constexpr auto kEnableGattQueryInThread = + flags::Flag(kConfigPackage, "45415261", false); + // LINT.ThenChange( // //depot/google3/location/nearby/cpp/sharing/clients/cpp/nearby_sharing_service_adapter_dart.h, // //depot/google3/location/nearby/cpp/sharing/clients/cpp/nearby_sharing_service_adapter_dart.cc, diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc index 2a5384e9..b03b34b2 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc @@ -19,19 +19,47 @@ #include #include #include +#include #include "absl/strings/escaping.h" +#include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/mediums/ble_v2/advertisement_read_result.h" #include "connections/implementation/mediums/ble_v2/ble_advertisement.h" #include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h" #include "connections/implementation/mediums/ble_v2/ble_utils.h" #include "connections/implementation/mediums/ble_v2/bloom_filter.h" +#include "internal/flags/nearby_flags.h" #include "internal/platform/ble_v2.h" +#include "internal/platform/logging.h" +#include "internal/platform/multi_thread_executor.h" #include "internal/platform/mutex_lock.h" namespace nearby { namespace connections { namespace mediums { +namespace { +constexpr int kGattThreadCount = 1; +} + +DiscoveredPeripheralTracker::DiscoveredPeripheralTracker( + bool is_extended_advertisement_available) + : is_extended_advertisement_available_( + is_extended_advertisement_available) { + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kEnableGattQueryInThread)) { + executor_ = std::make_unique(kGattThreadCount); + } +} + +DiscoveredPeripheralTracker::~DiscoveredPeripheralTracker() { + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kEnableGattQueryInThread)) { + MutexLock lock(&mutex_); + executor_->Shutdown(); + } +} void DiscoveredPeripheralTracker::StartTracking( const std::string& service_id, @@ -484,13 +512,41 @@ void DiscoveredPeripheralTracker::HandleAdvertisementHeader( // Determine whether or not we need to read a fresh GATT advertisement. if (ShouldReadRawAdvertisementFromServer(advertisement_header)) { // Determine whether or not we need to read a fresh GATT advertisement. - std::vector gatt_advertisement_bytes_list = - FetchRawAdvertisements(peripheral, advertisement_header, - std::move(advertisement_fetcher)); - if (!gatt_advertisement_bytes_list.empty()) { - HandleRawGattAdvertisements(peripheral, advertisement_header, - gatt_advertisement_bytes_list, - /*service_uuid=*/{}); + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kEnableGattQueryInThread)) { + NEARBY_LOGS(VERBOSE) << ": Handle GATT advertisement " + << absl::BytesToHexString( + ByteArray(advertisement_header).data()) + << " in thread"; + executor_->Execute([this, peripheral, advertisement_header, + advertisement_fetcher = + std::move(advertisement_fetcher)]() { + std::vector gatt_advertisement_bytes_list = + FetchRawAdvertisementsInThread(peripheral, advertisement_header, + std::move(advertisement_fetcher)); + { + MutexLock lock(&mutex_); + HandleRawGattAdvertisements(peripheral, advertisement_header, + gatt_advertisement_bytes_list, + /*service_uuid=*/{}); + UpdateCommonStateForFoundBleAdvertisement(advertisement_header); + NEARBY_LOGS(VERBOSE) + << ": Completed to handle GATT advertisement " + << absl::BytesToHexString(ByteArray(advertisement_header).data()) + << " in thread"; + } + }); + return; + } else { + std::vector gatt_advertisement_bytes_list = + FetchRawAdvertisements(peripheral, advertisement_header, + std::move(advertisement_fetcher)); + if (!gatt_advertisement_bytes_list.empty()) { + HandleRawGattAdvertisements(peripheral, advertisement_header, + gatt_advertisement_bytes_list, + /*service_uuid=*/{}); + } } } @@ -604,6 +660,35 @@ DiscoveredPeripheralTracker::FetchRawAdvertisements( return result->GetAdvertisements(); } +std::vector +DiscoveredPeripheralTracker::FetchRawAdvertisementsInThread( + BleV2Peripheral peripheral, + const BleAdvertisementHeader& advertisement_header, + AdvertisementFetcher advertisement_fetcher) { + std::vector service_ids; + AdvertisementReadResult* result = nullptr; + { + MutexLock lock(&mutex_); + // Fetch the raw GATT advertisements and store the results. + auto& read_result = advertisement_read_results_[advertisement_header]; + if (read_result == nullptr) { + read_result = std::make_unique(); + } + + result = read_result.get(); + std::transform(service_id_infos_.begin(), service_id_infos_.end(), + std::back_inserter(service_ids), + [](auto& kv) { return kv.first; }); + } + advertisement_fetcher.fetch_advertisements( + std::move(peripheral), advertisement_header.GetNumSlots(), + advertisement_header.GetPsm(), service_ids, *result); + + // Take those results and return all the advertisements we were able to + // read. + return result->GetAdvertisements(); +} + void DiscoveredPeripheralTracker::UpdateCommonStateForFoundBleAdvertisement( const BleAdvertisementHeader& advertisement_header) { const auto ga_it = gatt_advertisements_.find(advertisement_header); diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h index c0ae6a01..423514cb 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "connections/implementation/mediums//lost_entity_tracker.h" #include "connections/implementation/mediums/ble_v2/advertisement_read_result.h" @@ -27,6 +28,7 @@ #include "connections/implementation/mediums/lost_entity_tracker.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/byte_array.h" +#include "internal/platform/multi_thread_executor.h" #include "internal/platform/mutex.h" namespace nearby { @@ -58,9 +60,9 @@ class DiscoveredPeripheralTracker { }; explicit DiscoveredPeripheralTracker( - bool is_extended_advertisement_available = false) - : is_extended_advertisement_available_( - is_extended_advertisement_available) {} + bool is_extended_advertisement_available = false); + + ~DiscoveredPeripheralTracker(); // Starts tracking discoveries for a particular service Id. // @@ -234,6 +236,11 @@ class DiscoveredPeripheralTracker { AdvertisementFetcher advertisement_fetcher) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + std::vector FetchRawAdvertisementsInThread( + BleV2Peripheral peripheral, + const BleAdvertisementHeader& advertisement_header, + AdvertisementFetcher advertisement_fetcher); + // Updates `gatt_advertisement_infos_` map no matter whether we read a new // GATT advertisement by the input `advertisement_header` and 'mac_address`. void UpdateCommonStateForFoundBleAdvertisement( @@ -281,6 +288,9 @@ class DiscoveredPeripheralTracker { // advertisements are lost or become stale. absl::flat_hash_map gatt_advertisement_infos_ ABSL_GUARDED_BY(mutex_); + + std::unique_ptr executor_ ABSL_GUARDED_BY(mutex_) = + nullptr; }; } // namespace mediums