Handle GATT query in separate thread

PiperOrigin-RevId: 538819295
This commit is contained in:
Guogang Li
2023-06-08 10:10:00 -07:00
committed by Copybara-Service
parent 46c9d17f95
commit dbd42b0de3
3 changed files with 109 additions and 10 deletions
@@ -36,6 +36,10 @@ constexpr auto kEnableBleV2 =
constexpr auto kBlePeripheralLostTimeoutMillis =
flags::Flag<int64_t>(kConfigPackage, "45411439", 12000);
// Enable/Disable GATT query during scanning.
constexpr auto kEnableGattQueryInThread =
flags::Flag<bool>(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,
@@ -19,19 +19,47 @@
#include <memory>
#include <string>
#include <utility>
#include <vector>
#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<MultiThreadExecutor>(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<const ByteArray*> 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<const ByteArray*> 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<const ByteArray*> 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<const ByteArray*>
DiscoveredPeripheralTracker::FetchRawAdvertisementsInThread(
BleV2Peripheral peripheral,
const BleAdvertisementHeader& advertisement_header,
AdvertisementFetcher advertisement_fetcher) {
std::vector<std::string> 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<mediums::AdvertisementReadResult>();
}
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);
@@ -18,6 +18,7 @@
#include <functional>
#include <memory>
#include <string>
#include <vector>
#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<const ByteArray*> 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<BleAdvertisement, GattAdvertisementInfo>
gatt_advertisement_infos_ ABSL_GUARDED_BY(mutex_);
std::unique_ptr<MultiThreadExecutor> executor_ ABSL_GUARDED_BY(mutex_) =
nullptr;
};
} // namespace mediums