diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index 4a39873e..6b1e7ee7 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -61,6 +61,7 @@ cc_library( "//internal/platform/implementation:comm", "//proto/mediums:web_rtc_signaling_frames_cc_proto", # TODO: Support WebRTC + "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:btree", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", diff --git a/connections/implementation/mediums/ble_v2.h b/connections/implementation/mediums/ble_v2.h index e580d6f4..8216ea5b 100644 --- a/connections/implementation/mediums/ble_v2.h +++ b/connections/implementation/mediums/ble_v2.h @@ -20,11 +20,15 @@ #include #include +#include "absl/base/thread_annotations.h" #include "absl/container/btree_map.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" +#include "absl/functional/any_invocable.h" +#include "absl/strings/string_view.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/discovered_peripheral_callback.h" #include "connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h" #include "connections/implementation/mediums/bluetooth_radio.h" #include "connections/power_level.h" @@ -32,9 +36,12 @@ #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/byte_array.h" #include "internal/platform/cancelable_alarm.h" +#include "internal/platform/cancellation_flag.h" +#include "internal/platform/implementation/ble_v2.h" #include "internal/platform/multi_thread_executor.h" #include "internal/platform/mutex.h" #include "internal/platform/mutex_lock.h" +#include "internal/platform/runnable.h" #include "internal/platform/scheduled_executor.h" #include "internal/platform/single_thread_executor.h" @@ -139,6 +146,12 @@ class BleV2 final { return medium_.IsValid(); } + // Returns true if the BLE device support extended advertisement. + bool IsExtendedAdvertisementsAvailable() ABSL_LOCKS_EXCLUDED(mutex_) { + MutexLock lock(&mutex_); + return medium_.IsExtendedAdvertisementsAvailable(); + }; + private: struct AdvertisingInfo { mediums::BleAdvertisement medium_advertisement; diff --git a/connections/implementation/mediums/bluetooth_classic.cc b/connections/implementation/mediums/bluetooth_classic.cc index 0c6e86a7..72045016 100644 --- a/connections/implementation/mediums/bluetooth_classic.cc +++ b/connections/implementation/mediums/bluetooth_classic.cc @@ -18,7 +18,10 @@ #include #include +#include "connections/implementation/mediums/bluetooth_radio.h" +#include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" +#include "internal/platform/cancellation_flag.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/uuid.h" @@ -208,7 +211,7 @@ bool BluetoothClassic::StartDiscovery(DiscoveredDeviceCallback callback) { return false; } - if (IsDiscovering()) { + if (IsDiscoveringLocked()) { NEARBY_LOGS(INFO) << "Refusing to start discovery of BT devices because another " "discovery is already in-progress."; @@ -229,7 +232,7 @@ bool BluetoothClassic::StartDiscovery(DiscoveredDeviceCallback callback) { bool BluetoothClassic::StopDiscovery() { MutexLock lock(&mutex_); - if (!IsDiscovering()) { + if (!IsDiscoveringLocked()) { NEARBY_LOGS(INFO) << "Can't stop discovery of BT devices because it never started."; return false; @@ -244,7 +247,7 @@ bool BluetoothClassic::StopDiscovery() { return true; } -bool BluetoothClassic::IsDiscovering() const { return scan_info_.valid; } +bool BluetoothClassic::IsDiscoveringLocked() const { return scan_info_.valid; } bool BluetoothClassic::StartAcceptingConnections( const std::string& service_id, AcceptedConnectionCallback callback) { @@ -445,6 +448,12 @@ BluetoothDevice BluetoothClassic::GetRemoteDevice( return medium_->GetRemoteDevice(mac_address); } +bool BluetoothClassic::IsDiscovering() const { + MutexLock lock(&mutex_); + return IsDiscoveringLocked(); + ; +} + std::string BluetoothClassic::GetMacAddress() const { MutexLock lock(&mutex_); diff --git a/connections/implementation/mediums/bluetooth_classic.h b/connections/implementation/mediums/bluetooth_classic.h index 8c84215f..897c96a7 100644 --- a/connections/implementation/mediums/bluetooth_classic.h +++ b/connections/implementation/mediums/bluetooth_classic.h @@ -15,18 +15,16 @@ #ifndef CORE_INTERNAL_MEDIUMS_BLUETOOTH_CLASSIC_H_ #define CORE_INTERNAL_MEDIUMS_BLUETOOTH_CLASSIC_H_ -#include -#include #include #include #include +#include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" +#include "absl/functional/any_invocable.h" #include "connections/implementation/mediums/bluetooth_radio.h" -#include "connections/listeners.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_classic.h" -#include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/multi_thread_executor.h" #include "internal/platform/mutex.h" @@ -121,6 +119,8 @@ class BluetoothClassic { BluetoothDevice GetRemoteDevice(const std::string& mac_address) ABSL_LOCKS_EXCLUDED(mutex_); + bool IsDiscovering() const ABSL_LOCKS_EXCLUDED(mutex_); + protected: // Use for unit tests only to inject a BluetoothClassicMedium. BluetoothClassic(BluetoothRadio& radio, @@ -171,7 +171,7 @@ class BluetoothClassic { bool RestoreDeviceName() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); // Returns true if device is currently in discovery mode. - bool IsDiscovering() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + bool IsDiscoveringLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); // Establishes connection to BT service that was might be started on another // device with StartAcceptingConnections() using the same service_id. diff --git a/connections/implementation/p2p_cluster_pcp_handler.cc b/connections/implementation/p2p_cluster_pcp_handler.cc index 270d3406..33020e86 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.cc +++ b/connections/implementation/p2p_cluster_pcp_handler.cc @@ -14,6 +14,7 @@ #include "connections/implementation/p2p_cluster_pcp_handler.h" +#include #include #include #include @@ -38,6 +39,7 @@ #include "connections/implementation/endpoint_manager.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "connections/implementation/injected_bluetooth_device_store.h" +#include "connections/implementation/mediums/bluetooth_classic.h" #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/mediums/utils.h" #include "connections/implementation/pcp.h" @@ -817,7 +819,7 @@ void P2pClusterPcpHandler::BleV2PeripheralLostHandler( NEARBY_LOGS(ERROR) << ble_status_or.status(); return; } - auto advertisement = ble_status_or.value(); + const auto& advertisement = ble_status_or.value(); // Make sure the BLE advertisement points to a valid // endpoint we're discovering. @@ -870,6 +872,44 @@ void P2pClusterPcpHandler::BleV2PeripheralLostHandler( }); } +void P2pClusterPcpHandler::BleV2LegacyDeviceDiscoveredHandler() { + if (!NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kDisableBluetoothClassicScanning)) { + return; + } + + RunOnPcpHandlerThread( + "p2p-ble-legacy-peripheral-discovered", + [this]() RUN_ON_PCP_HANDLER_THREAD() { + if (paused_bluetooth_clients_discoveries_.empty()) { + return; + } + + NEARBY_LOGS(INFO) << "Found nearby legacy BLE device, pending " + "bluetooth discovery size :" + << paused_bluetooth_clients_discoveries_.size(); + + for (auto& paused_bluetooth_client : + paused_bluetooth_clients_discoveries_) { + if (!paused_bluetooth_client.second->IsDiscoveringServiceId( + paused_bluetooth_client.first)) { + NEARBY_LOGS(INFO) << "Do not start bluetooth scanning since client " + "is no longer discovering for service id: " + << paused_bluetooth_client.first; + continue; + } + + // Start the paused bluetooth discovery. + StartBluetoothDiscovery(paused_bluetooth_client.second, + paused_bluetooth_client.first); + } + + // Remove all pending bluetooth clients. + paused_bluetooth_clients_discoveries_.clear(); + }); +} + bool P2pClusterPcpHandler::IsRecognizedWifiLanEndpoint( const std::string& service_id, const WifiLanServiceInfo& wifi_lan_service_info) const { @@ -1016,16 +1056,6 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( } } - if (discovery_options.allowed.bluetooth) { - Medium bluetooth_medium = StartBluetoothDiscovery(client, service_id); - if (bluetooth_medium != - location::nearby::proto::connections::UNKNOWN_MEDIUM) { - NEARBY_LOG(INFO, "P2pClusterPcpHandler::StartDiscoveryImpl: BT added"); - mediums_started_successfully.push_back(bluetooth_medium); - bluetooth_classic_discoverer_client_id_ = client->GetClientId(); - } - } - if (discovery_options.allowed.ble) { if (NearbyFlags::GetInstance().GetBoolFlag( config_package_nearby::nearby_connections_feature::kEnableBleV2)) { @@ -1049,6 +1079,23 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( } } + if (discovery_options.allowed.bluetooth) { + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kDisableBluetoothClassicScanning)) { + StartBluetoothDiscoveryWithPause(client, service_id, discovery_options, + mediums_started_successfully); + } else { + Medium bluetooth_medium = StartBluetoothDiscovery(client, service_id); + if (bluetooth_medium != + location::nearby::proto::connections::UNKNOWN_MEDIUM) { + NEARBY_LOG(INFO, "P2pClusterPcpHandler::StartDiscoveryImpl: BT added"); + mediums_started_successfully.push_back(bluetooth_medium); + bluetooth_classic_discoverer_client_id_ = client->GetClientId(); + } + } + } + if (mediums_started_successfully.empty()) { NEARBY_LOGS(ERROR) << "Failed StartDiscovery() for client=" << client->GetClientId() @@ -1084,6 +1131,14 @@ Status P2pClusterPcpHandler::StopDiscoveryImpl(ClientProxy* client) { } else { ble_medium_.StopScanning(client->GetDiscoveryServiceId()); } + + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kDisableBluetoothClassicScanning)) { + paused_bluetooth_clients_discoveries_.erase( + client->GetDiscoveryServiceId()); + } + return {Status::kSuccess}; } @@ -1499,21 +1554,6 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( bool should_start_discovery = false; auto new_mediums = discovery_options.allowed; auto old_mediums = old_options.allowed; - // bt classic - if (new_mediums.bluetooth && !discovery_options.low_power) { - should_start_discovery = true; - if (!needs_restart && old_mediums.bluetooth) { - restarted_mediums.push_back(Medium::BLUETOOTH); - } else { - if (StartBluetoothDiscovery(client, std::string(service_id)) != - location::nearby::proto::connections::UNKNOWN_MEDIUM) { - restarted_mediums.push_back(Medium::BLUETOOTH); - } else { - NEARBY_LOGS(WARNING) - << "UpdateDiscoveryOptionsImpl: unable to restart bt scanning"; - } - } - } // ble if (new_mediums.ble) { should_start_discovery = true; @@ -1544,6 +1584,28 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( } } } + // bt classic + if (new_mediums.bluetooth && !discovery_options.low_power) { + should_start_discovery = true; + if (!needs_restart && old_mediums.bluetooth) { + restarted_mediums.push_back(Medium::BLUETOOTH); + } else { + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature:: + kDisableBluetoothClassicScanning)) { + StartBluetoothDiscoveryWithPause(client, std::string(service_id), + discovery_options, restarted_mediums); + } else { + if (StartBluetoothDiscovery(client, std::string(service_id)) != + location::nearby::proto::connections::UNKNOWN_MEDIUM) { + restarted_mediums.push_back(Medium::BLUETOOTH); + } else { + NEARBY_LOGS(WARNING) + << "UpdateDiscoveryOptionsImpl: unable to restart bt scanning"; + } + } + } + } // wifi lan if (new_mediums.wifi_lan && !discovery_options.low_power) { should_start_discovery = true; @@ -1705,6 +1767,52 @@ Medium P2pClusterPcpHandler::StartBluetoothDiscovery( } } +void P2pClusterPcpHandler::StartBluetoothDiscoveryWithPause( + ClientProxy* client, const std::string& service_id, + const DiscoveryOptions& discovery_options, + std::vector& mediums_started_successfully) { + if (bluetooth_radio_.IsEnabled()) { + if (ble_v2_medium_.IsExtendedAdvertisementsAvailable() && + std::find(mediums_started_successfully.begin(), + mediums_started_successfully.end(), + location::nearby::proto::connections::BLE) != + mediums_started_successfully.end()) { + if (bluetooth_medium_.IsDiscovering()) { + // If we are already discovering, we don't need to start again. + Medium bluetooth_medium = StartBluetoothDiscovery(client, service_id); + if (bluetooth_medium != + location::nearby::proto::connections::UNKNOWN_MEDIUM) { + NEARBY_LOG(INFO, + "P2pClusterPcpHandler::StartBluetoothDiscoveryWithPause: " + "BT added"); + mediums_started_successfully.push_back(bluetooth_medium); + bluetooth_classic_discoverer_client_id_ = client->GetClientId(); + } + } else { + NEARBY_LOGS(INFO) << "Pause bluetooth discovery for service id : " + << service_id; + paused_bluetooth_clients_discoveries_.insert({service_id, client}); + } + } else { + // Always start bluetooth discovery if BLE doesn't support extended + // advertisements. + Medium bluetooth_medium = StartBluetoothDiscovery(client, service_id); + if (bluetooth_medium != + location::nearby::proto::connections::UNKNOWN_MEDIUM) { + NEARBY_LOG( + INFO, + "P2pClusterPcpHandler::StartBluetoothDiscoveryWithPause: BT added"); + mediums_started_successfully.push_back(bluetooth_medium); + bluetooth_classic_discoverer_client_id_ = client->GetClientId(); + } + } + } else { + NEARBY_LOGS(WARNING) << "Ignore to discover on bluetooth for service id: " + << service_id + << " because bluetooth is disabled or low power mode."; + } +} + BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BluetoothConnectImpl( ClientProxy* client, BluetoothEndpoint* endpoint) { NEARBY_LOGS(VERBOSE) << "Client " << client->GetClientId() @@ -2129,6 +2237,9 @@ Medium P2pClusterPcpHandler::StartBleV2Scanning( .peripheral_lost_cb = absl::bind_front( &P2pClusterPcpHandler::BleV2PeripheralLostHandler, this, client), + .legacy_device_discovered_cb = absl::bind_front( + &P2pClusterPcpHandler::BleV2LegacyDeviceDiscoveredHandler, + this), })) { NEARBY_LOGS(INFO) << "In StartBleV2Scanning(), client=" << client->GetClientId() diff --git a/connections/implementation/p2p_cluster_pcp_handler.h b/connections/implementation/p2p_cluster_pcp_handler.h index aa1c3950..285a3ff7 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.h +++ b/connections/implementation/p2p_cluster_pcp_handler.h @@ -15,10 +15,15 @@ #ifndef CORE_INTERNAL_P2P_CLUSTER_PCP_HANDLER_H_ #define CORE_INTERNAL_P2P_CLUSTER_PCP_HANDLER_H_ -#include +#include +#include #include #include +#include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" +#include "connections/advertising_options.h" +#include "connections/discovery_options.h" #include "connections/implementation/base_pcp_handler.h" #include "connections/implementation/ble_advertisement.h" #include "connections/implementation/bluetooth_device_name.h" @@ -27,8 +32,26 @@ #include "connections/implementation/endpoint_channel_manager.h" #include "connections/implementation/endpoint_manager.h" #include "connections/implementation/injected_bluetooth_device_store.h" +#include "connections/implementation/mediums/ble.h" +#include "connections/implementation/mediums/ble_v2.h" #include "connections/implementation/mediums/bluetooth_classic.h" +#include "connections/implementation/mediums/bluetooth_radio.h" #include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/mediums/wifi_direct.h" +#include "connections/implementation/mediums/wifi_hotspot.h" +#include "connections/implementation/mediums/wifi_lan.h" +#include "connections/medium_selector.h" +#include "connections/out_of_band_connection_metadata.h" +#include "connections/power_level.h" +#include "connections/status.h" +#include "connections/v3/connection_listening_options.h" +#include "internal/interop/device.h" +#include "internal/platform/ble.h" +#include "internal/platform/ble_v2.h" +#include "internal/platform/bluetooth_adapter.h" +#include "internal/platform/bluetooth_classic.h" +#include "internal/platform/nsd_service_info.h" +#include "internal/platform/wifi_lan.h" #ifdef NO_WEBRTC #include "connections/implementation/mediums/webrtc_socket_stub.h" #include "connections/implementation/mediums/webrtc_stub.h" @@ -123,7 +146,8 @@ class P2pClusterPcpHandler : public BasePcpHandler { // in to BasePCPHandler::onEndpointFound(). struct BleEndpointState { public: - BleEndpointState(const string& endpoint_id, const ByteArray& endpoint_info) + BleEndpointState(const std::string& endpoint_id, + const ByteArray& endpoint_info) : endpoint_id(endpoint_id), endpoint_info(endpoint_info) {} std::string endpoint_id; @@ -178,6 +202,10 @@ class P2pClusterPcpHandler : public BasePcpHandler { const ByteArray& local_endpoint_info, WebRtcState web_rtc_state); location::nearby::proto::connections::Medium StartBluetoothDiscovery( ClientProxy* client, const std::string& service_id); + void StartBluetoothDiscoveryWithPause( + ClientProxy* client, const std::string& service_id, + const DiscoveryOptions& discovery_options, + std::vector& mediums_started_successfully); BasePcpHandler::ConnectImplResult BluetoothConnectImpl( ClientProxy* client, BluetoothEndpoint* endpoint); @@ -220,6 +248,8 @@ class P2pClusterPcpHandler : public BasePcpHandler { const std::string& service_id, const ByteArray& advertisement_bytes, bool fast_advertisement); + void BleV2LegacyDeviceDiscoveredHandler(); + void BleV2ConnectionAcceptedHandler(ClientProxy* client, absl::string_view local_endpoint_info, NearbyDevice::Type device_type, @@ -279,6 +309,10 @@ class P2pClusterPcpHandler : public BasePcpHandler { // Maps a BlePeripheral.Id_ to its corresponding BleEndpointState. absl::flat_hash_map found_endpoints_in_ble_discover_cb_; + + // Maps service id to its client. + absl::flat_hash_map + paused_bluetooth_clients_discoveries_; }; } // namespace connections diff --git a/connections/implementation/p2p_cluster_pcp_handler_test.cc b/connections/implementation/p2p_cluster_pcp_handler_test.cc index ecf49f4a..a948ff10 100644 --- a/connections/implementation/p2p_cluster_pcp_handler_test.cc +++ b/connections/implementation/p2p_cluster_pcp_handler_test.cc @@ -14,22 +14,32 @@ #include "connections/implementation/p2p_cluster_pcp_handler.h" -#include +#include #include #include -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "absl/time/clock.h" #include "absl/time/time.h" #include "connections/advertising_options.h" +#include "connections/connection_options.h" +#include "connections/discovery_options.h" #include "connections/implementation/bluetooth_device_name.h" #include "connections/implementation/bwu_manager.h" +#include "connections/implementation/client_proxy.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/injected_bluetooth_device_store.h" +#include "connections/implementation/mediums/bluetooth_radio.h" +#include "connections/implementation/mediums/mediums.h" +#include "connections/listeners.h" #include "connections/medium_selector.h" +#include "connections/status.h" +#include "connections/strategy.h" #include "connections/v3/connection_listening_options.h" #include "internal/flags/nearby_flags.h" +#include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" @@ -70,14 +80,21 @@ constexpr BooleanMediumSelector kTestCases[] = { // Combines the bool `kEnableBleV2` as param testing but should revert it back // if ble_v2 is done and ble will be replaced by ble_v2. class P2pClusterPcpHandlerTest - : public testing::TestWithParam> { + : public testing::TestWithParam< + std::tuple> { protected: void SetUp() override { NEARBY_LOG(INFO, "SetUp: begin"); - auto ble_v2_enabled = std::get<1>(GetParam()); + env_.SetBleExtendedAdvertisementsAvailable(false); + bool ble_v2_enabled = std::get<1>(GetParam()); NearbyFlags::GetInstance().OverrideBoolFlagValue( config_package_nearby::nearby_connections_feature::kEnableBleV2, ble_v2_enabled); + bool is_disable_bluetooth_scanning = std::get<2>(GetParam()); + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_connections_feature:: + kDisableBluetoothClassicScanning, + is_disable_bluetooth_scanning); if (advertising_options_.allowed.ble) { NEARBY_LOG(INFO, "SetUp: BLE enabled"); } @@ -91,6 +108,8 @@ class P2pClusterPcpHandlerTest NEARBY_LOG(INFO, "SetUp: WebRTC enabled"); } NEARBY_LOG(INFO, "SetUp: ble v2 enabled: %d", ble_v2_enabled); + NEARBY_LOG(INFO, "SetUp: is_disable_bluetooth_scanning: %d", + is_disable_bluetooth_scanning); NEARBY_LOG(INFO, "SetUp: end"); } @@ -441,6 +460,101 @@ TEST_P(P2pClusterPcpHandlerTest, CanDiscoverLegacy) { env_.Stop(); } +TEST_P(P2pClusterPcpHandlerTest, PauseBluetoothClassicDiscovery) { + // Skip the case which not disable bluetooth scanning. + if (!std::get<2>(GetParam()) || !std::get<1>(GetParam()) || + !advertising_options_.allowed.bluetooth || + !advertising_options_.allowed.ble) { + return; + } + + env_.SetBleExtendedAdvertisementsAvailable(true); + env_.Start(); + std::string endpoint_name{"endpoint_name"}; + Mediums mediums_a; + EndpointChannelManager ecm_a; + EndpointManager em_a(&ecm_a); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + InjectedBluetoothDeviceStore ibds_a; + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); + + EXPECT_EQ( + handler_a.StartDiscovery(&client_a_, service_id_, discovery_options_, {}), + Status{Status::kSuccess}); + + EXPECT_TRUE(mediums_a.GetBleV2().IsScanning(service_id_)); + EXPECT_FALSE(mediums_a.GetBluetoothClassic().IsDiscovering()); + // Before we finish the test, we have to stop discovery for other mediums that + // may be still ongoing. + handler_a.StopDiscovery(&client_a_); + env_.Stop(); +} + +TEST_P(P2pClusterPcpHandlerTest, ResumeBluetoothClassicDiscovery) { + // Skip the case which not disable bluetooth scanning. + if (!std::get<2>(GetParam()) || !std::get<1>(GetParam()) || + !advertising_options_.allowed.bluetooth || + !advertising_options_.allowed.ble) { + return; + } + + std::string endpoint_name{"endpoint_name"}; + + env_.Start(); + // Enable BLE V2 extended advertisement for client_a_. + env_.SetBleExtendedAdvertisementsAvailable(true); + Mediums mediums_a; + EndpointChannelManager ecm_a; + EndpointManager em_a(&ecm_a); + InjectedBluetoothDeviceStore ibds_a; + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); + + // Disable BLE V2 extended advertisement for client_b_. + env_.SetBleExtendedAdvertisementsAvailable(false); + Mediums mediums_b; + EndpointChannelManager ecm_b; + EndpointManager em_b(&ecm_b); + BwuManager bwu_b(mediums_b, em_b, ecm_b, {}, {}); + InjectedBluetoothDeviceStore ibds_b; + P2pClusterPcpHandler handler_b(&mediums_b, &em_b, &ecm_b, &bwu_b, ibds_b); + CountDownLatch latch(1); + + EXPECT_EQ(handler_a.StartDiscovery( + &client_a_, service_id_, discovery_options_, + { + .endpoint_found_cb = + [&latch](const std::string& endpoint_id, + const ByteArray& endpoint_info, + const std::string& service_id) { + NEARBY_LOG(INFO, "Device discovered: id=%s", + endpoint_id.c_str()); + latch.CountDown(); + }, + }), + Status{Status::kSuccess}); + + EXPECT_TRUE(mediums_a.GetBleV2().IsScanning(service_id_)); + EXPECT_FALSE(mediums_a.GetBluetoothClassic().IsDiscovering()); + + EXPECT_EQ( + handler_b.StartAdvertising(&client_b_, service_id_, advertising_options_, + {.endpoint_info = ByteArray{endpoint_name}}), + Status{Status::kSuccess}); + + EXPECT_TRUE(latch.Await(absl::Milliseconds(1000)).result()); + absl::SleepFor(absl::Milliseconds(100)); + + EXPECT_TRUE(mediums_a.GetBleV2().IsScanning(service_id_)); + EXPECT_TRUE(mediums_a.GetBluetoothClassic().IsDiscovering()); + + // Before we finish the test, we have to stop discovery for other mediums that + // may be still ongoing. + handler_b.StopAdvertising(&client_b_); + handler_a.StopDiscovery(&client_a_); + env_.Stop(); +} + TEST_P(P2pClusterPcpHandlerTest, CanBluetoothDiscoverChangeName) { env_.Start(); std::string endpoint_name{"endpoint_name"}; @@ -907,6 +1021,7 @@ TEST_P(P2pClusterPcpHandlerTest, CanStopListeningForIncomingConnections) { INSTANTIATE_TEST_SUITE_P(ParametrisedPcpHandlerTest, P2pClusterPcpHandlerTest, ::testing::Combine(::testing::ValuesIn(kTestCases), + ::testing::Bool(), ::testing::Bool())); } // namespace diff --git a/connections/implementation/pcp_manager.cc b/connections/implementation/pcp_manager.cc index 91b7fa14..bb214374 100644 --- a/connections/implementation/pcp_manager.cc +++ b/connections/implementation/pcp_manager.cc @@ -14,13 +14,35 @@ #include "connections/implementation/pcp_manager.h" +#include +#include +#include #include +#include "absl/strings/string_view.h" +#include "connections/advertising_options.h" +#include "connections/connection_options.h" +#include "connections/discovery_options.h" +#include "connections/implementation/bwu_manager.h" +#include "connections/implementation/client_proxy.h" +#include "connections/implementation/endpoint_channel_manager.h" +#include "connections/implementation/endpoint_manager.h" +#include "connections/implementation/injected_bluetooth_device_store.h" +#include "connections/implementation/mediums/mediums.h" #include "connections/implementation/p2p_cluster_pcp_handler.h" #include "connections/implementation/p2p_point_to_point_pcp_handler.h" #include "connections/implementation/p2p_star_pcp_handler.h" +#include "connections/implementation/pcp.h" #include "connections/implementation/pcp_handler.h" +#include "connections/listeners.h" +#include "connections/out_of_band_connection_metadata.h" +#include "connections/params.h" +#include "connections/status.h" +#include "connections/strategy.h" +#include "connections/v3/connection_listening_options.h" +#include "connections/v3/listeners.h" #include "internal/interop/device.h" +#include "internal/platform/logging.h" namespace nearby { namespace connections { @@ -56,7 +78,7 @@ PcpManager::~PcpManager() { } Status PcpManager::StartAdvertising( - ClientProxy* client, const string& service_id, + ClientProxy* client, const std::string& service_id, const AdvertisingOptions& advertising_options, const ConnectionRequestInfo& info) { if (!SetCurrentPcpHandler(advertising_options.strategy)) { @@ -73,7 +95,8 @@ void PcpManager::StopAdvertising(ClientProxy* client) { } } -Status PcpManager::StartDiscovery(ClientProxy* client, const string& service_id, +Status PcpManager::StartDiscovery(ClientProxy* client, + const std::string& service_id, const DiscoveryOptions& discovery_options, DiscoveryListener listener) { if (!SetCurrentPcpHandler(discovery_options.strategy)) { @@ -117,7 +140,7 @@ void PcpManager::InjectEndpoint(ClientProxy* client, } Status PcpManager::RequestConnection( - ClientProxy* client, const string& endpoint_id, + ClientProxy* client, const std::string& endpoint_id, const ConnectionRequestInfo& info, const ConnectionOptions& connection_options) { if (!current_) { @@ -142,7 +165,7 @@ Status PcpManager::RequestConnectionV3( } Status PcpManager::AcceptConnection(ClientProxy* client, - const string& endpoint_id, + const std::string& endpoint_id, PayloadListener payload_listener) { if (!current_) { return {Status::kOutOfOrderApiCall}; @@ -153,7 +176,7 @@ Status PcpManager::AcceptConnection(ClientProxy* client, } Status PcpManager::RejectConnection(ClientProxy* client, - const string& endpoint_id) { + const std::string& endpoint_id) { if (!current_) { return {Status::kOutOfOrderApiCall}; } diff --git a/connections/implementation/pcp_manager.h b/connections/implementation/pcp_manager.h index 2596e56f..3983b713 100644 --- a/connections/implementation/pcp_manager.h +++ b/connections/implementation/pcp_manager.h @@ -15,9 +15,16 @@ #ifndef CORE_INTERNAL_PCP_MANAGER_H_ #define CORE_INTERNAL_PCP_MANAGER_H_ +#include #include +#include +#include #include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" +#include "connections/advertising_options.h" +#include "connections/connection_options.h" +#include "connections/discovery_options.h" #include "connections/implementation/base_pcp_handler.h" #include "connections/implementation/bwu_manager.h" #include "connections/implementation/client_proxy.h" @@ -25,9 +32,16 @@ #include "connections/implementation/endpoint_manager.h" #include "connections/implementation/injected_bluetooth_device_store.h" #include "connections/implementation/mediums/mediums.h" +#include "connections/implementation/pcp.h" +#include "connections/implementation/pcp_handler.h" #include "connections/listeners.h" +#include "connections/out_of_band_connection_metadata.h" +#include "connections/params.h" #include "connections/status.h" #include "connections/strategy.h" +#include "connections/v3/connection_listening_options.h" +#include "connections/v3/listeners.h" +#include "internal/interop/device.h" #include "internal/platform/atomic_boolean.h" namespace nearby { @@ -47,12 +61,12 @@ class PcpManager { InjectedBluetoothDeviceStore& injected_bluetooth_device_store); ~PcpManager(); - Status StartAdvertising(ClientProxy* client, const string& service_id, + Status StartAdvertising(ClientProxy* client, const std::string& service_id, const AdvertisingOptions& advertising_options, const ConnectionRequestInfo& info); void StopAdvertising(ClientProxy* client); - Status StartDiscovery(ClientProxy* client, const string& service_id, + Status StartDiscovery(ClientProxy* client, const std::string& service_id, const DiscoveryOptions& discovery_options, DiscoveryListener listener); void StopDiscovery(ClientProxy* client); @@ -68,7 +82,7 @@ class PcpManager { void InjectEndpoint(ClientProxy* client, const std::string& service_id, const OutOfBandConnectionMetadata& metadata); - Status RequestConnection(ClientProxy* client, const string& endpoint_id, + Status RequestConnection(ClientProxy* client, const std::string& endpoint_id, const ConnectionRequestInfo& info, const ConnectionOptions& connection_options); @@ -76,9 +90,9 @@ class PcpManager { const NearbyDevice& remote_device, const ConnectionRequestInfo& info, const ConnectionOptions& connection_options); - Status AcceptConnection(ClientProxy* client, const string& endpoint_id, + Status AcceptConnection(ClientProxy* client, const std::string& endpoint_id, PayloadListener payload_listener); - Status RejectConnection(ClientProxy* client, const string& endpoint_id); + Status RejectConnection(ClientProxy* client, const std::string& endpoint_id); Status UpdateAdvertisingOptions( ClientProxy* client, absl::string_view service_id, diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 3b866f20..ce968d3d 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -209,6 +209,7 @@ cc_library( "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/time", "@com_google_absl//absl/types:optional", ], diff --git a/internal/platform/implementation/g3/ble_v2.cc b/internal/platform/implementation/g3/ble_v2.cc index 09e663ab..bf053e01 100644 --- a/internal/platform/implementation/g3/ble_v2.cc +++ b/internal/platform/implementation/g3/ble_v2.cc @@ -160,6 +160,8 @@ Exception BleV2ServerSocket::DoClose() { BleV2Medium::BleV2Medium(api::BluetoothAdapter& adapter) : adapter_(static_cast(&adapter)) { adapter_->SetBleV2Medium(this); + is_extended_advertisements_available_ = + MediumEnvironment::Instance().IsBleExtendedAdvertisementsAvailable(); MediumEnvironment::Instance().RegisterBleV2Medium(*this, &peripheral_); } @@ -326,7 +328,7 @@ std::unique_ptr BleV2Medium::ConnectToGattServer( } bool BleV2Medium::IsExtendedAdvertisementsAvailable() { - return MediumEnvironment::Instance().IsBleExtendedAdvertisementsAvailable(); + return is_extended_advertisements_available_; } bool BleV2Medium::GetRemotePeripheral(const std::string& mac_address, diff --git a/internal/platform/implementation/g3/ble_v2.h b/internal/platform/implementation/g3/ble_v2.h index e51178a8..80972c4c 100644 --- a/internal/platform/implementation/g3/ble_v2.h +++ b/internal/platform/implementation/g3/ble_v2.h @@ -332,6 +332,7 @@ class BleV2Medium : public api::ble_v2::BleMedium { ABSL_GUARDED_BY(mutex_); absl::flat_hash_set> scanning_internal_session_ids_ ABSL_GUARDED_BY(mutex_); + bool is_extended_advertisements_available_ = false; }; } // namespace g3 diff --git a/internal/platform/medium_environment.cc b/internal/platform/medium_environment.cc index 8f1dccbb..f44fd6cf 100644 --- a/internal/platform/medium_environment.cc +++ b/internal/platform/medium_environment.cc @@ -24,9 +24,11 @@ #include "absl/container/flat_hash_set.h" #include "absl/status/status.h" +#include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "absl/types/optional.h" +#include "internal/platform/borrowable.h" #include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/feature_flags.h" @@ -35,6 +37,7 @@ #include "internal/platform/implementation/bluetooth_adapter.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/wifi_direct.h" +#include "internal/platform/implementation/wifi_hotspot.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" @@ -1153,7 +1156,7 @@ std::optional MediumEnvironment::GetSimulatedClock() { if (simulated_clock_) { return std::optional(simulated_clock_.get()); } - return absl::nullopt; + return std::nullopt; } void MediumEnvironment::RegisterGattServer(