From 7e758061ac740b99b6633c8fa55b0898a9ce93fd Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 5 Mar 2025 13:33:11 -0800 Subject: [PATCH] Allow setting of alternate service UUID on StartDiscovery. PiperOrigin-RevId: 733850300 --- connections/discovery_options.h | 20 +++++++++++-------- connections/implementation/mediums/ble_v2.cc | 7 +++++++ connections/implementation/mediums/ble_v2.h | 9 +++++++++ .../implementation/p2p_cluster_pcp_handler.cc | 4 ++++ internal/platform/ble_v2.h | 5 +++++ internal/platform/implementation/ble_v2.h | 3 +++ .../platform/implementation/windows/ble_v2.cc | 9 +++++++++ .../platform/implementation/windows/ble_v2.h | 3 +++ sharing/fake_nearby_connections_manager.cc | 1 + sharing/fake_nearby_connections_manager.h | 1 + sharing/nearby_connections_manager.h | 1 + sharing/nearby_connections_manager_impl.cc | 2 ++ sharing/nearby_connections_manager_impl.h | 1 + .../nearby_connections_manager_impl_test.cc | 1 + sharing/nearby_connections_service_impl.cc | 9 ++++++--- sharing/nearby_connections_types.h | 3 +++ sharing/nearby_sharing_service.h | 2 ++ sharing/nearby_sharing_service_impl.cc | 3 ++- sharing/nearby_sharing_service_impl.h | 5 +++++ 19 files changed, 77 insertions(+), 12 deletions(-) diff --git a/connections/discovery_options.h b/connections/discovery_options.h index 0273e802..57586888 100644 --- a/connections/discovery_options.h +++ b/connections/discovery_options.h @@ -13,19 +13,23 @@ // limitations under the License. #ifndef CORE_DISCOVERY_OPTIONS_H_ #define CORE_DISCOVERY_OPTIONS_H_ + +#include +#include #include -#include "connections/medium_selector.h" #include "connections/options_base.h" -#include "connections/power_level.h" -#include "connections/strategy.h" -#include "internal/platform/byte_array.h" -#include "proto/connections_enums.pb.h" namespace nearby { namespace connections { -// Connection Options: used for both Advertising and Discovery. +struct BleOptions { + // An alternative BLE service UUID16s for the Nearby service that is enabling + // BLE scanning. + std::optional alternate_uuid; +}; + +// Discovery Options: used for service discovery. // All fields are mutable, to make the type copy-assignable. struct DiscoveryOptions : OptionsBase { // Returns a copy and normalizes allowed mediums: @@ -33,18 +37,18 @@ struct DiscoveryOptions : OptionsBase { // medium allowed, defaulting to only Bluetooth if unspecified. // (2) If no mediums are allowed, allow all mediums. DiscoveryOptions CompatibleOptions() const; - bool auto_upgrade_bandwidth = true; bool enforce_topology_constraints; // Whether this is intended to be used in conjunction with InjectEndpoint(). bool is_out_of_band_connection = false; - // TODO(b/229927044): Replaces it as bool once Ble v1 is deprecated. std::string fast_advertisement_service_uuid; // If true, only low power mediums (like BLE) will be used for discovery. bool low_power = false; + + BleOptions ble_options; }; } // namespace connections diff --git a/connections/implementation/mediums/ble_v2.cc b/connections/implementation/mediums/ble_v2.cc index 2d3d2080..24d75c68 100644 --- a/connections/implementation/mediums/ble_v2.cc +++ b/connections/implementation/mediums/ble_v2.cc @@ -15,6 +15,7 @@ #include "connections/implementation/mediums/ble_v2.h" #include +#include #include #include #include @@ -371,6 +372,12 @@ bool BleV2::StopLegacyAdvertising(const std::string& input_service_id) { return status.ok(); } +void BleV2::AddAlternateUuidForService( + uint16_t uuid, const std::string& service_id) { + MutexLock lock(&mutex_); + medium_.AddAlternateUuidForService(uuid, service_id); +} + ErrorOr BleV2::StartScanning(const std::string& service_id, PowerLevel power_level, DiscoveredPeripheralCallback callback) { diff --git a/connections/implementation/mediums/ble_v2.h b/connections/implementation/mediums/ble_v2.h index 1b57c1ce..519e19af 100644 --- a/connections/implementation/mediums/ble_v2.h +++ b/connections/implementation/mediums/ble_v2.h @@ -15,6 +15,7 @@ #ifndef CORE_INTERNAL_MEDIUMS_BLE_V2_H_ #define CORE_INTERNAL_MEDIUMS_BLE_V2_H_ +#include #include #include #include @@ -110,6 +111,14 @@ class BleV2 final { bool StopLegacyAdvertising(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); + // Adds an alternative BLE service UUID16s for a given Nearby service + // id. If a device does not support BLE extended advertisements, an alternate + // service UUID16 may be used to trigger a GATT connection to retrieve GATT + // characteristics for the Nearby service + // These alternate uuids are active until the next call to `StopScanning`. + void AddAlternateUuidForService( + uint16_t uuid, const std::string& service_id); + // Enables BLE scanning for a service ID. Will report any discoverable // advertisement data through a callback. // Returns true, if the scanning is successfully enabled, false otherwise. diff --git a/connections/implementation/p2p_cluster_pcp_handler.cc b/connections/implementation/p2p_cluster_pcp_handler.cc index 988e9532..f43f8969 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.cc +++ b/connections/implementation/p2p_cluster_pcp_handler.cc @@ -2619,6 +2619,10 @@ ErrorOr P2pClusterPcpHandler::StartBleV2Scanning( << service_id; return {Error(OperationResultCode::DEVICE_STATE_RADIO_ENABLING_FAILURE)}; } + if (discovery_options.ble_options.alternate_uuid.has_value()) { + ble_v2_medium_.AddAlternateUuidForService( + *discovery_options.ble_options.alternate_uuid, service_id); + } ErrorOr ble_v2_result = ble_v2_medium_.StartScanning( service_id, power_level, { diff --git a/internal/platform/ble_v2.h b/internal/platform/ble_v2.h index 248322ce..bd169377 100644 --- a/internal/platform/ble_v2.h +++ b/internal/platform/ble_v2.h @@ -15,6 +15,7 @@ #ifndef PLATFORM_PUBLIC_BLE_V2_H_ #define PLATFORM_PUBLIC_BLE_V2_H_ +#include #include #include #include @@ -456,6 +457,10 @@ class BleV2Medium final { api::ble_v2::BleMedium* GetImpl() const { return impl_.get(); } BluetoothAdapter& GetAdapter() { return adapter_; } + void AddAlternateUuidForService(uint16_t uuid, + const std::string& service_id) { + impl_->AddAlternateUuidForService(uuid, service_id); + } private: Mutex mutex_; diff --git a/internal/platform/implementation/ble_v2.h b/internal/platform/implementation/ble_v2.h index d9a12ffe..fdd55ece 100644 --- a/internal/platform/implementation/ble_v2.h +++ b/internal/platform/implementation/ble_v2.h @@ -538,6 +538,9 @@ class BleMedium { // Otherwise, does not call the callback and returns false. virtual bool GetRemotePeripheral(BlePeripheral::UniqueId id, GetRemotePeripheralCallback callback) = 0; + + virtual void AddAlternateUuidForService(uint16_t uuid, + const std::string& service_id) {}; }; } // namespace ble_v2 diff --git a/internal/platform/implementation/windows/ble_v2.cc b/internal/platform/implementation/windows/ble_v2.cc index 71e3758f..71609a01 100644 --- a/internal/platform/implementation/windows/ble_v2.cc +++ b/internal/platform/implementation/windows/ble_v2.cc @@ -24,6 +24,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "absl/status/status.h" #include "absl/strings/escaping.h" #include "absl/strings/numbers.h" @@ -650,6 +651,8 @@ std::unique_ptr BleV2Medium::ConnectToGattServer( bool BleV2Medium::StopScanning() { absl::MutexLock lock(&mutex_); + alternate_uuids_for_service_.clear(); + LOG(INFO) << __func__ << ": BLE StopScanning: service_uuid: " << absl::StrCat(absl::Hex(service_uuid16_)); if (!adapter_->IsEnabled()) { @@ -1414,5 +1417,11 @@ void BleV2Medium::RemoveExpiredPeripherals() { } } +void BleV2Medium::AddAlternateUuidForService(uint16_t uuid, + const std::string& service_id) { + absl::MutexLock lock(&mutex_); + alternate_uuids_for_service_[uuid] = service_id; +} + } // namespace windows } // namespace nearby diff --git a/internal/platform/implementation/windows/ble_v2.h b/internal/platform/implementation/windows/ble_v2.h index d45bdbe9..faba51fc 100644 --- a/internal/platform/implementation/windows/ble_v2.h +++ b/internal/platform/implementation/windows/ble_v2.h @@ -90,6 +90,9 @@ class BleV2Medium : public api::ble_v2::BleMedium { GetRemotePeripheralCallback callback) override ABSL_LOCKS_EXCLUDED(mutex_); + void AddAlternateUuidForService(uint16_t uuid, + const std::string& service_id) override; + private: friend class BleV2MediumTest; diff --git a/sharing/fake_nearby_connections_manager.cc b/sharing/fake_nearby_connections_manager.cc index 46abd758..c7b6a755 100644 --- a/sharing/fake_nearby_connections_manager.cc +++ b/sharing/fake_nearby_connections_manager.cc @@ -92,6 +92,7 @@ void FakeNearbyConnectionsManager::StopAdvertising( void FakeNearbyConnectionsManager::StartDiscovery( DiscoveryListener* listener, DataUsage data_usage, + std::optional alternate_service_uuid, ConnectionsCallback callback) { is_shutdown_ = false; absl::MutexLock lock(&listener_mutex_); diff --git a/sharing/fake_nearby_connections_manager.h b/sharing/fake_nearby_connections_manager.h index cc314528..fe46f1a9 100644 --- a/sharing/fake_nearby_connections_manager.h +++ b/sharing/fake_nearby_connections_manager.h @@ -53,6 +53,7 @@ class FakeNearbyConnectionsManager : public NearbyConnectionsManager { ConnectionsCallback callback) override; void StopAdvertising(ConnectionsCallback callback) override; void StartDiscovery(DiscoveryListener* listener, proto::DataUsage data_usage, + std::optional alternate_service_uuid, ConnectionsCallback callback) override; void StopDiscovery() override; void Connect(std::vector endpoint_info, diff --git a/sharing/nearby_connections_manager.h b/sharing/nearby_connections_manager.h index e47ea42e..dd41e677 100644 --- a/sharing/nearby_connections_manager.h +++ b/sharing/nearby_connections_manager.h @@ -112,6 +112,7 @@ class NearbyConnectionsManager { // `listener` remains valid until StopDiscovery is called. virtual void StartDiscovery(DiscoveryListener* listener, proto::DataUsage data_usage, + std::optional alternate_service_uuid, ConnectionsCallback callback) = 0; // Stops discovery through Nearby Connections. diff --git a/sharing/nearby_connections_manager_impl.cc b/sharing/nearby_connections_manager_impl.cc index 307ca495..262ae3ba 100644 --- a/sharing/nearby_connections_manager_impl.cc +++ b/sharing/nearby_connections_manager_impl.cc @@ -280,6 +280,7 @@ void NearbyConnectionsManagerImpl::StopAdvertising( void NearbyConnectionsManagerImpl::StartDiscovery( DiscoveryListener* listener, DataUsage data_usage, + std::optional alternate_service_uuid, ConnectionsCallback callback) { DCHECK(listener); @@ -318,6 +319,7 @@ void NearbyConnectionsManagerImpl::StartDiscovery( .fast_advertisement_service_uuid = Uuid(kFastAdvertisementServiceUuid), .is_out_of_band_connection = false, + .alternate_service_uuid = std::move(alternate_service_uuid), }, std::move(service_discovery_listener), std::move(callback)); } diff --git a/sharing/nearby_connections_manager_impl.h b/sharing/nearby_connections_manager_impl.h index a7f30412..98d5ba4f 100644 --- a/sharing/nearby_connections_manager_impl.h +++ b/sharing/nearby_connections_manager_impl.h @@ -65,6 +65,7 @@ class NearbyConnectionsManagerImpl : public NearbyConnectionsManager { ConnectionsCallback callback) override; void StopAdvertising(ConnectionsCallback callback) override; void StartDiscovery(DiscoveryListener* listener, proto::DataUsage data_usage, + std::optional alternate_service_uuid, ConnectionsCallback callback) override; void StopDiscovery() override; void Connect(std::vector endpoint_info, diff --git a/sharing/nearby_connections_manager_impl_test.cc b/sharing/nearby_connections_manager_impl_test.cc index 27707f7d..29f16f4b 100644 --- a/sharing/nearby_connections_manager_impl_test.cc +++ b/sharing/nearby_connections_manager_impl_test.cc @@ -200,6 +200,7 @@ class NearbyConnectionsManagerImplTest : public testing::Test { }; nearby_connections_manager_->StartDiscovery(&discovery_listener, data_usage, + std::nullopt, std::move(callback)); EXPECT_TRUE( diff --git a/sharing/nearby_connections_service_impl.cc b/sharing/nearby_connections_service_impl.cc index cfb6ed4b..761a3b81 100644 --- a/sharing/nearby_connections_service_impl.cc +++ b/sharing/nearby_connections_service_impl.cc @@ -19,19 +19,16 @@ #include #include #include -#include #include #include #include #include "absl/container/flat_hash_map.h" -#include "absl/meta/type_traits.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "absl/types/span.h" #include "connections/listeners.h" #include "connections/medium_selector.h" -#include "connections/payload.h" #include "connections/strategy.h" #include "internal/analytics/event_logger.h" #include "internal/platform/logging.h" @@ -156,6 +153,12 @@ void NearbyConnectionsServiceImpl::StartDiscovery( options.is_out_of_band_connection = discovery_options.is_out_of_band_connection; + + if (discovery_options.alternate_service_uuid.has_value()) { + options.ble_options.alternate_uuid = + discovery_options.alternate_service_uuid; + } + NcDiscoveryListener listener; listener.endpoint_found_cb = [this](const std::string& endpoint_id, const NcByteArray& endpoint_info, diff --git a/sharing/nearby_connections_types.h b/sharing/nearby_connections_types.h index ddf4144e..1eaa380d 100644 --- a/sharing/nearby_connections_types.h +++ b/sharing/nearby_connections_types.h @@ -247,6 +247,9 @@ struct DiscoveryOptions { // inject discovery information synced outside the Nearby Connections library. // Intended to be used in conjunction with InjectEndpoint(). bool is_out_of_band_connection = false; + // An optional UUID16 to use for BLE discovery if the normal service data + // UUID causes the advertisement packet to exceed the maximum size. + std::optional alternate_service_uuid; }; // Options for a call to NearbyConnections::RequestConnection(). diff --git a/sharing/nearby_sharing_service.h b/sharing/nearby_sharing_service.h index 2f05441d..597ead7e 100644 --- a/sharing/nearby_sharing_service.h +++ b/sharing/nearby_sharing_service.h @@ -243,6 +243,8 @@ class NearbySharingService { virtual NearbyShareCertificateManager* GetCertificateManager() = 0; virtual AccountManager* GetAccountManager() = 0; virtual Clock& GetClock() = 0; + virtual void SetAlternateServiceUuidForDiscovery( + uint16_t alternate_service_uuid) = 0; }; } // namespace sharing diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index bba5708b..b1c00184 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -2168,7 +2168,8 @@ void NearbySharingServiceImpl::StartScanning() { scanning_session_id_ = analytics_recorder_.GenerateNextId(); nearby_connections_manager_->StartDiscovery( - /*listener=*/this, settings_->GetDataUsage(), [this](Status status) { + /*listener=*/this, settings_->GetDataUsage(), alternate_service_uuid_, + [this](Status status) { // Log analytics event of starting discovery. analytics::AnalyticsInformation analytics_information; analytics_information.send_surface_state = diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index 5c0e758e..dbd912b3 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -167,6 +167,10 @@ class NearbySharingServiceImpl NearbyShareCertificateManager* GetCertificateManager() override; AccountManager* GetAccountManager() override; Clock& GetClock() override { return *context_->GetClock(); } + void SetAlternateServiceUuidForDiscovery( + uint16_t alternate_service_uuid) override { + alternate_service_uuid_ = alternate_service_uuid; + } // NearbyConnectionsManager::IncomingConnectionListener: void OnIncomingConnection(absl::string_view endpoint_id, @@ -593,6 +597,7 @@ class NearbySharingServiceImpl // Used to track the time when share sheet activity starts absl::Time share_foreground_send_surface_start_timestamp_; std::unique_ptr app_info_; + std::optional alternate_service_uuid_; }; } // namespace nearby::sharing