Stop BLE_V2 scan before upgrading to Wifi HotSpot to avoid interference

PiperOrigin-RevId: 746541587
This commit is contained in:
hai007
2025-04-11 11:59:18 -07:00
committed by Copybara-Service
parent b10957d712
commit 3c77c0dfa0
12 changed files with 138 additions and 8 deletions
+38
View File
@@ -23,6 +23,7 @@
#include "absl/container/flat_hash_map.h"
#include "absl/functional/bind_front.h"
#include "absl/strings/str_cat.h"
#include "absl/time/time.h"
#include "connections/implementation/analytics/connection_attempt_metadata_params.h"
#include "connections/implementation/bluetooth_bwu_handler.h"
@@ -31,9 +32,11 @@
#include "connections/implementation/endpoint_channel.h"
#include "connections/implementation/endpoint_channel_manager.h"
#include "connections/implementation/endpoint_manager.h"
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
#include "connections/implementation/mediums/mediums.h"
#include "connections/implementation/offline_frames.h"
#include "connections/implementation/service_id_constants.h"
#include "internal/flags/nearby_flags.h"
#ifdef NO_WEBRTC
#include "connections/implementation/webrtc_bwu_handler_stub.h"
#else
@@ -897,6 +900,8 @@ BwuManager::ProcessBwuPathAvailableEventInternal(
// Get service ID from the old channel. Don't keep the old channel's shared
// pointer in scope longer than necessary.
std::string service_id;
Medium old_medium = Medium::UNKNOWN_MEDIUM;
bool disable_ble_scanning = false;
{
std::shared_ptr<EndpointChannel> old_channel =
channel_manager_->GetChannelForEndpoint(endpoint_id);
@@ -910,11 +915,44 @@ BwuManager::ProcessBwuPathAvailableEventInternal(
Error(OperationResultCode::NEARBY_GENERIC_OLD_ENDPOINT_CHANNEL_NULL)};
}
service_id = old_channel->GetServiceId();
old_medium = old_channel->GetMedium();
}
bool enable_ble_v2 = NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2);
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableStopBLEScanningOnWifiUpgrade)) {
if (client->GetLocalOsInfo().type() ==
location::nearby::connections::OsInfo::APPLE &&
old_medium == Medium::BLE && medium == Medium::WIFI_HOTSPOT) {
disable_ble_scanning = true;
if (enable_ble_v2) {
NEARBY_LOGS(INFO)
<< "For Apple OS, if upgrade from BLE_V2 to WIFI_HOTSPOT, "
"we need to pause "
"BLE_V2 scanning because it can interfere with WIFI "
"Hotspot scanning and connection.";
ble_v2_medium_.PauseMediumScanning();
}
}
}
ErrorOr<std::unique_ptr<EndpointChannel>> result =
handler->CreateUpgradedEndpointChannel(client, service_id, endpoint_id,
upgrade_path_info);
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableStopBLEScanningOnWifiUpgrade)) {
if (disable_ble_scanning) {
if (enable_ble_v2) {
NEARBY_LOGS(INFO) << "Resume BLE_V2 scanning.";
ble_v2_medium_.ResumeMediumScanning();
}
}
}
if (result.has_error() || !result.has_value()) {
NEARBY_LOGS(ERROR) << "BwuManager failed to create an endpoint "
"channel to endpoint"
+2
View File
@@ -28,6 +28,7 @@
#include "connections/implementation/endpoint_channel.h"
#include "connections/implementation/endpoint_channel_manager.h"
#include "connections/implementation/endpoint_manager.h"
#include "connections/implementation/mediums/ble_v2.h"
#include "connections/implementation/mediums/mediums.h"
#include "connections/medium_selector.h"
#include "internal/platform/cancelable_alarm.h"
@@ -226,6 +227,7 @@ class BwuManager : public EndpointManager::FrameProcessor {
Mediums* mediums_;
absl::flat_hash_map<Medium, std::unique_ptr<BwuHandler>> handlers_;
BleV2& ble_v2_medium_{mediums_->GetBleV2()};
EndpointManager* endpoint_manager_;
EndpointChannelManager* channel_manager_;
@@ -89,6 +89,9 @@ constexpr auto kUseStableEndpointId =
// When true, disable instant on lost on BLE without extended feature.
constexpr auto kDisableInstantOnLostOnBleWithoutExtended =
flags::Flag<bool>(kConfigPackage, "45687098", true);
// When true, stop BLE_V2 scanning when upgrading to WIFI Hotspot or WFD.
constexpr auto kEnableStopBLEScanningOnWifiUpgrade =
flags::Flag<bool>(kConfigPackage, "45687902", false);
// When true, enable multiplexing in NC for AWDL.
constexpr auto kEnableMultiplexAwdl =
flags::Flag<bool>(kConfigPackage, "45690761", false);
@@ -564,6 +564,16 @@ bool BleV2::StopScanning(const std::string& service_id) {
return medium_.StopScanning();
}
bool BleV2::PauseMediumScanning() {
MutexLock lock(&mutex_);
return medium_.PauseMediumScanning();
}
bool BleV2::ResumeMediumScanning() {
MutexLock lock(&mutex_);
return medium_.ResumeMediumScanning();
}
bool BleV2::IsScanning(const std::string& service_id) const {
MutexLock lock(&mutex_);
@@ -145,6 +145,12 @@ class BleV2 final {
// Returns true, if the scanning was previously enabled, false otherwise.
bool StopScanning(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_);
// Pauses BLE scanning at platform Medium level.
bool PauseMediumScanning();
// Resumes BLE scanning at platform Medium level.
bool ResumeMediumScanning();
// Returns true if the scanning for service ID is enabled.
bool IsScanning(const std::string& service_id) const
ABSL_LOCKS_EXCLUDED(mutex_);
+14
View File
@@ -147,6 +147,20 @@ bool BleV2Medium::StopScanning() {
NEARBY_LOGS(INFO) << "Ble Scanning disabled: impl=" << GetImpl();
return impl_->StopScanning();
}
bool BleV2Medium::PauseMediumScanning() {
MutexLock lock(&mutex_);
if (!scanning_enabled_) {
return true;
}
NEARBY_LOGS(INFO) << "Pause Medium level BLE_V2 Scanning: impl="
<< GetImpl();
return impl_->PauseMediumScanning();
}
bool BleV2Medium::ResumeMediumScanning() {
MutexLock lock(&mutex_);
return impl_->ResumeMediumScanning();
}
std::unique_ptr<api::ble_v2::BleMedium::ScanningSession>
BleV2Medium::StartScanning(const Uuid& service_uuid,
+6
View File
@@ -496,6 +496,12 @@ class BleV2Medium final {
// TODO(b/271305977) remove this function.
bool StopScanning();
// Pause BLE scanning at platform Medium level.
bool PauseMediumScanning();
// Resume BLE scanning at platform Medium level.
bool ResumeMediumScanning();
std::unique_ptr<api::ble_v2::BleMedium::ScanningSession> StartScanning(
const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BleMedium::ScanningCallback callback);
@@ -120,7 +120,7 @@ typedef void (^GNCOpenL2CAPServerCompletionHandler)(GNCBLEL2CAPServer *_Nullable
*
* @param serviceData A dictionary that contains service-specific advertisement data.
* @param completionHandler Called on a private queue with @c nil if successfully started
* advertising or an error if one has occured.
* advertising or an error if one has occurred.
*/
- (void)startAdvertisingData:(NSDictionary<CBUUID *, NSData *> *)serviceData
completionHandler:(nullable GNCStartAdvertisingCompletionHandler)completionHandler;
@@ -129,7 +129,7 @@ typedef void (^GNCOpenL2CAPServerCompletionHandler)(GNCBLEL2CAPServer *_Nullable
* Stops advertising all service data.
*
* @param completionHandler Called on a private queue with @c nil if successfully stopped
* advertising or an error if one has occured.
* advertising or an error if one has occurred.
*/
- (void)stopAdvertisingWithCompletionHandler:
(nullable GNCStopAdvertisingCompletionHandler)completionHandler;
@@ -140,7 +140,7 @@ typedef void (^GNCOpenL2CAPServerCompletionHandler)(GNCBLEL2CAPServer *_Nullable
* @param serviceUUID The service UUID to scan for.
* @param advertisementFoundHandler Called on a private queue when a peripheral has been discovered.
* @param completionHandler Called on a private queue with @c nil if successfully started scanning
* or an error if one has occured.
* or an error if one has occurred.
*/
- (void)startScanningForService:(CBUUID *)serviceUUID
advertisementFoundHandler:(GNCAdvertisementFoundHandler)advertisementFoundHandler
@@ -154,7 +154,7 @@ typedef void (^GNCOpenL2CAPServerCompletionHandler)(GNCBLEL2CAPServer *_Nullable
* discovered.
* @param advertisementFoundHandler Called on a private queue when a peripheral has been discovered.
* @param completionHandler Called on a private queue with @c nil if successfully started scanning
* or an error if one has occured.
* or an error if one has occurred.
*/
- (void)startScanningForMultipleServices:(NSArray<CBUUID *> *)serviceUUIDs
advertisementFoundHandler:(GNCAdvertisementFoundHandler)advertisementFoundHandler
@@ -165,16 +165,25 @@ typedef void (^GNCOpenL2CAPServerCompletionHandler)(GNCBLEL2CAPServer *_Nullable
* Stops scanning for peripherals.
*
* @param completionHandler Called on a private queue with @c nil if successfully stopped
* scanning or an error if one has occured.
* scanning or an error if one has occurred.
*/
- (void)stopScanningWithCompletionHandler:
(nullable GNCStopScanningCompletionHandler)completionHandler;
/**
* Resumes scanning for peripherals.
*
* @param completionHandler Called on a private queue with @c nil if successfully resumed scanning
* or an error if one has occurred.
*/
- (void)resumeMediumScanning:
(nullable GNCStartScanningCompletionHandler)completionHandler;
/**
* Starts a GATT server.
*
* @param completionHandler Called on a private queue with the GATT server if successfully started
* or an error if one has occured.
* or an error if one has occurred.
*/
- (void)startGATTServerWithCompletionHandler:
(nullable GNCGATTServerCompletionHandler)completionHandler;
@@ -185,7 +194,7 @@ typedef void (^GNCOpenL2CAPServerCompletionHandler)(GNCBLEL2CAPServer *_Nullable
* @param remotePeripheral The peripheral to which the central is attempting to connect.
* @param disconnectionHandler Called on a private queue when the peripheral has been disconnected.
* @param completionHandler Called on a private queue with a GATT client if successfully connected
* or an error if one has occured.
* or an error if one has occurred.
*/
- (void)connectToGATTServerForPeripheral:(id<GNCPeripheral>)remotePeripheral
disconnectionHandler:(nullable GNCGATTDisconnectionHandler)disconnectionHandler
@@ -196,7 +205,7 @@ typedef void (^GNCOpenL2CAPServerCompletionHandler)(GNCBLEL2CAPServer *_Nullable
* Opens a L2CAP server.
*
* @param completionHandler Called on a private queue with the L2CAP server if successfully started
* or an error if one has occured.
* or an error if one has occurred.
* @param peripheralManager The peripheral manager instance.
*/
- (void)openL2CAPServerWithCompletionHandler:(GNCOpenL2CAPServerCompletionHandler)completionHandler
@@ -170,6 +170,16 @@ static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer(
});
}
- (void)resumeMediumScanning:
(nullable GNCStartScanningCompletionHandler)completionHandler {
dispatch_async(_queue, ^{
[self internalStartScanningIfPoweredOn];
if (completionHandler) {
completionHandler(nil);
}
});
}
- (void)startGATTServerWithCompletionHandler:
(nullable GNCGATTServerCompletionHandler)completionHandler {
dispatch_async(_queue, ^{
@@ -97,6 +97,16 @@ class BleMedium : public api::ble_v2::BleMedium {
// Returns whether or not scanning was successfully stopped.
bool StopScanning() override;
// Pauses BLE scanning at platform Medium level.
//
// Returns whether or not scanning was successfully paused.
bool PauseMediumScanning() override;
// Resumes BLE scanning at platform Medium level.
//
// Returns whether or not scanning was successfully resumed.
bool ResumeMediumScanning() override;
// TODO(b/290385712): ServerGattConnectionCallback methods are not yet implemented.
//
// Starts a GATT server. Returns a nullptr upon error.
@@ -266,6 +266,24 @@ bool BleMedium::StopScanning() {
return blockError == nil;
}
bool BleMedium::PauseMediumScanning() {
return StopScanning();
}
bool BleMedium::ResumeMediumScanning() {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block NSError *blockError = nil;
[medium_ resumeMediumScanning:^(NSError *error) {
if (error != nil) {
GTMLoggerError(@"Failed to start scanning for multiple services: %@", error);
blockError = error;
}
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return blockError == nil;
}
// TODO(b/290385712): Add implementation that calls ServerGattConnectionCallback methods.
std::unique_ptr<api::ble_v2::GattServer> BleMedium::StartGattServer(
api::ble_v2::ServerGattConnectionCallback callback) {
@@ -512,6 +512,10 @@ class BleMedium {
// Stops scanning.
virtual bool StopScanning() = 0;
virtual bool PauseMediumScanning() { return true; }
virtual bool ResumeMediumScanning() { return true; }
struct ScanningSession {
absl::AnyInvocable<absl::Status()> stop_scanning;
};