From 1b557236f7018cb577bac6d063c55aa7e26a3e00 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 6 Jan 2026 10:43:27 -0800 Subject: [PATCH] Log interface count and IPv6 only interface count during wifi upgrade. PiperOrigin-RevId: 852845375 --- connections/implementation/BUILD | 6 +- .../analytics/analytics_recorder.cc | 18 +++ .../analytics/analytics_recorder.h | 4 + .../implementation/base_pcp_handler.cc | 10 +- connections/implementation/mediums/BUILD | 1 + .../implementation/mediums/wifi_lan.cc | 4 +- connections/implementation/mediums/wifi_lan.h | 7 +- .../implementation/mediums/wifi_lan_test.cc | 25 +-- .../implementation/wifi_lan_bwu_handler.cc | 13 +- .../wifi_lan_bwu_handler_test.cc | 149 +++++++++++++++--- internal/platform/implementation/BUILD | 1 + .../platform/implementation/apple/wifi_lan.h | 3 +- .../platform/implementation/apple/wifi_lan.mm | 11 +- .../platform/implementation/g3/wifi_lan.cc | 12 +- .../platform/implementation/g3/wifi_lan.h | 5 +- .../implementation/upgrade_address_info.h | 37 +++++ internal/platform/implementation/wifi_lan.h | 6 +- .../platform/implementation/windows/BUILD | 1 - .../implementation/windows/wifi_lan.h | 6 +- .../implementation/windows/wifi_lan_medium.cc | 44 ++++-- internal/platform/mock_wifi_lan_medium.h | 4 +- internal/platform/wifi_lan.cc | 4 +- internal/platform/wifi_lan.h | 12 +- .../proto/analytics/connections_log.proto | 7 + 24 files changed, 293 insertions(+), 97 deletions(-) create mode 100644 internal/platform/implementation/upgrade_address_info.h diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 36ed7544..d5b6f768 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -192,9 +192,7 @@ cc_library( "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/functional:bind_front", - "@com_google_absl//absl/log:check", "@com_google_absl//absl/random", - "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", @@ -587,12 +585,16 @@ cc_test( ], deps = [ ":internal", + "//connections:core_types", "//connections/implementation/mediums", + "//internal/analytics:mock_event_logger", "//internal/platform:base", "//internal/platform:mock_platform", + "//internal/platform:test_util", "//internal/platform/implementation:comm", "//internal/platform/implementation:platform", "//internal/platform/implementation:platform_impl", + "//internal/proto/analytics:connections_log_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", "@com_google_googletest//:gtest_main", diff --git a/connections/implementation/analytics/analytics_recorder.cc b/connections/implementation/analytics/analytics_recorder.cc index 422b8ae5..f91edcef 100644 --- a/connections/implementation/analytics/analytics_recorder.cc +++ b/connections/implementation/analytics/analytics_recorder.cc @@ -777,6 +777,24 @@ void AnalyticsRecorder::OnBandwidthUpgradeStarted( {endpoint_id, std::move(bandwidth_upgrade_attempt)}); } +void AnalyticsRecorder::UpdateBwUpgradeNetworkInfo( + const std::string& endpoint_id, int num_interfaces, + int num_ipv6_only_interfaces) { + MutexLock lock(&mutex_); + if (!CanRecordAnalyticsLocked("UpdateBwUpgradeNetworkInfo")) { + return; + } + auto it = bandwidth_upgrade_attempts_.find(endpoint_id); + if (it == bandwidth_upgrade_attempts_.end()) { + return; + } + ConnectionsLog::BandwidthUpgradeAttempt* bandwidth_upgrade_attempt = + it->second.get(); + bandwidth_upgrade_attempt->set_num_interfaces(num_interfaces); + bandwidth_upgrade_attempt->set_num_ipv6_only_interfaces( + num_ipv6_only_interfaces); +} + void AnalyticsRecorder::OnBandwidthUpgradeError( const std::string& endpoint_id, BandwidthUpgradeResult result, BandwidthUpgradeErrorStage error_stage, diff --git a/connections/implementation/analytics/analytics_recorder.h b/connections/implementation/analytics/analytics_recorder.h index 4f1fe1e8..b24232b3 100644 --- a/connections/implementation/analytics/analytics_recorder.h +++ b/connections/implementation/analytics/analytics_recorder.h @@ -198,6 +198,10 @@ class AnalyticsRecorder { location::nearby::proto::connections::ConnectionAttemptDirection direction, const std::string& connection_token) ABSL_LOCKS_EXCLUDED(mutex_); + void UpdateBwUpgradeNetworkInfo(const std::string& endpoint_id, + int num_interfaces, + int num_ipv6_only_interfaces) + ABSL_LOCKS_EXCLUDED(mutex_); void OnBandwidthUpgradeError( const std::string& endpoint_id, location::nearby::proto::connections::BandwidthUpgradeResult result, diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 3fee41cd..0bd75153 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -75,13 +75,13 @@ #include "internal/platform/feature_flags.h" #include "internal/platform/future.h" #include "internal/platform/implementation/system_clock.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi.h" #include "internal/platform/logging.h" #include "internal/platform/mac_address.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/prng.h" #include "internal/platform/runnable.h" -#include "internal/platform/service_address.h" #include "internal/platform/wifi.h" #include "internal/platform/wifi_lan_connection_info.h" #include "proto/connections_enums.pb.h" @@ -198,17 +198,17 @@ std::vector BasePcpHandler::GetConnectionInfoFromResult( BleConnectionInfo info("", "", "", {}); connection_infos.push_back(info); } else if (medium == location::nearby::proto::connections::WIFI_LAN) { - std::vector upgrade_candidates = + api::UpgradeAddressInfo upgrade_candidates = mediums_->GetWifiLan().GetUpgradeAddressCandidates( std::string(service_id)); // Only use IPv4 address. IPv4 addresses are always at the end of the // list. std::vector ip_address; int port = 0; - if (!upgrade_candidates.empty()) { - ip_address = upgrade_candidates.back().address; + if (!upgrade_candidates.address_candidates.empty()) { + ip_address = upgrade_candidates.address_candidates.back().address; if (ip_address.size() == 4) { - port = upgrade_candidates.back().port; + port = upgrade_candidates.address_candidates.back().port; } } WifiLanConnectionInfo info( diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index 1f777773..cdb45d70 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -175,6 +175,7 @@ cc_test( "//internal/platform:mac_address", "//internal/platform:test_util", "//internal/platform:types", + "//internal/platform/implementation:comm", "//internal/platform/implementation:types", "//internal/platform/implementation/g3", # build_cleaner: keep "@com_github_protobuf_matchers//protobuf-matchers", diff --git a/connections/implementation/mediums/wifi_lan.cc b/connections/implementation/mediums/wifi_lan.cc index 8a8c2d98..ff3c58ad 100644 --- a/connections/implementation/mediums/wifi_lan.cc +++ b/connections/implementation/mediums/wifi_lan.cc @@ -30,6 +30,7 @@ #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_utils.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" @@ -37,7 +38,6 @@ #include "internal/platform/service_address.h" #include "internal/platform/socket.h" #include "internal/platform/types.h" -#include "internal/platform/wifi_credential.h" #include "internal/platform/wifi_lan.h" namespace nearby { @@ -612,7 +612,7 @@ ExceptionOr WifiLan::CreateOutgoingMultiplexSocketLocked( return ExceptionOr(Exception::kFailed); } -std::vector WifiLan::GetUpgradeAddressCandidates( +api::UpgradeAddressInfo WifiLan::GetUpgradeAddressCandidates( const std::string& service_id) { MutexLock lock(&mutex_); const auto& it = server_sockets_.find(service_id); diff --git a/connections/implementation/mediums/wifi_lan.h b/connections/implementation/mediums/wifi_lan.h index 9c11f341..990439ce 100644 --- a/connections/implementation/mediums/wifi_lan.h +++ b/connections/implementation/mediums/wifi_lan.h @@ -30,11 +30,11 @@ #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/multi_thread_executor.h" #include "internal/platform/mutex.h" #include "internal/platform/nsd_service_info.h" #include "internal/platform/service_address.h" -#include "internal/platform/wifi_credential.h" #include "internal/platform/wifi_lan.h" namespace nearby { @@ -115,10 +115,7 @@ class WifiLan { // Returns the list of ip address candidates that can be used to connect to // this device for bandwidth upgrade + port number the service is listening // on. - // The candidates list is ordered to have IPv6 addresses first, then IPv4. - // Both IPv4 and IPv6 adddresses are represented as network order byte - // sequence. - std::vector GetUpgradeAddressCandidates( + api::UpgradeAddressInfo GetUpgradeAddressCandidates( const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); private: diff --git a/connections/implementation/mediums/wifi_lan_test.cc b/connections/implementation/mediums/wifi_lan_test.cc index d354e9c0..95bbfa5c 100644 --- a/connections/implementation/mediums/wifi_lan_test.cc +++ b/connections/implementation/mediums/wifi_lan_test.cc @@ -28,6 +28,7 @@ #include "internal/platform/count_down_latch.h" #include "internal/platform/expected.h" #include "internal/platform/feature_flags.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "internal/platform/nsd_service_info.h" @@ -76,15 +77,16 @@ TEST_P(WifiLanTest, AdvertiseSameServiceNameReusesPort) { NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(std::string(kServiceInfoName)); wifi_lan_server.StartAdvertising(service_id, nsd_service_info, {}); - std::vector addresses = + api::UpgradeAddressInfo addresses_info = wifi_lan_server.GetUpgradeAddressCandidates(service_id); wifi_lan_server.StopAdvertising(service_id); wifi_lan_server.StopAcceptingConnections(service_id); wifi_lan_server.StartAdvertising(service_id, nsd_service_info, {}); - std::vector addresses2 = + api::UpgradeAddressInfo addresses_info2 = wifi_lan_server.GetUpgradeAddressCandidates(service_id); - EXPECT_EQ(addresses.back().port, addresses2.back().port); + EXPECT_EQ(addresses_info.address_candidates.back().port, + addresses_info2.address_candidates.back().port); env_.Stop(); } @@ -100,16 +102,17 @@ TEST_P(WifiLanTest, AdvertiseDifferentServiceNameUsesDifferentPort) { NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(std::string(kServiceInfoName)); wifi_lan_server.StartAdvertising(service_id, nsd_service_info, {}); - std::vector addresses = + api::UpgradeAddressInfo addresses_info = wifi_lan_server.GetUpgradeAddressCandidates(service_id); wifi_lan_server.StopAdvertising(service_id); wifi_lan_server.StopAcceptingConnections(service_id); nsd_service_info.SetServiceName("ServiceInfoName2"); wifi_lan_server.StartAdvertising(service_id, nsd_service_info, {}); - std::vector addresses2 = + api::UpgradeAddressInfo addresses_info2 = wifi_lan_server.GetUpgradeAddressCandidates(service_id); - EXPECT_NE(addresses.back().port, addresses2.back().port); + EXPECT_NE(addresses_info.address_candidates.back().port, + addresses_info2.address_candidates.back().port); env_.Stop(); } @@ -320,14 +323,14 @@ TEST_P(WifiLanTest, CanConnectWithIpAddressAndPort) { accept_latch.CountDown(); })); - std::vector server_candidates = + api::UpgradeAddressInfo server_address_info = wifi_lan_server.GetUpgradeAddressCandidates(service_id); - ASSERT_FALSE(server_candidates.empty()); - ASSERT_NE(server_candidates.back().port, 0); + ASSERT_FALSE(server_address_info.address_candidates.empty()); + ASSERT_NE(server_address_info.address_candidates.back().port, 0); CancellationFlag flag; - ErrorOr socket_for_client_result = - wifi_lan_client.Connect(service_id, server_candidates.front(), &flag); + ErrorOr socket_for_client_result = wifi_lan_client.Connect( + service_id, server_address_info.address_candidates.front(), &flag); EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); diff --git a/connections/implementation/wifi_lan_bwu_handler.cc b/connections/implementation/wifi_lan_bwu_handler.cc index bc758ad8..1a31c931 100644 --- a/connections/implementation/wifi_lan_bwu_handler.cc +++ b/connections/implementation/wifi_lan_bwu_handler.cc @@ -29,10 +29,9 @@ #include "connections/implementation/wifi_lan_endpoint_channel.h" #include "internal/platform/byte_array.h" #include "internal/platform/expected.h" -#include "internal/platform/implementation/wifi_utils.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/logging.h" #include "internal/platform/service_address.h" -#include "internal/platform/wifi_credential.h" #include "internal/platform/wifi_lan.h" namespace nearby { @@ -143,15 +142,19 @@ ByteArray WifiLanBwuHandler::HandleInitializeUpgradedMediumForEndpoint( // Address candidates are not populated until StartAcceptingConnections() is // called and the server socket is created. Be careful moving this codeblock // around. - std::vector upgrade_candidates = + api::UpgradeAddressInfo upgrade_candidates = wifi_lan_medium_.GetUpgradeAddressCandidates(upgrade_service_id); - if (upgrade_candidates.empty()) { + if (upgrade_candidates.address_candidates.empty()) { LOG(INFO) << "WifiLanBwuHandler couldn't initiate the wifi_lan upgrade for " << "service " << upgrade_service_id << " and endpoint " << endpoint_id << " because there are no available ip addresses."; return {}; } - return parser::ForBwuWifiLanPathAvailable(upgrade_candidates); + client->GetAnalyticsRecorder().UpdateBwUpgradeNetworkInfo( + endpoint_id, upgrade_candidates.num_interfaces, + upgrade_candidates.num_ipv6_only_interfaces); + return parser::ForBwuWifiLanPathAvailable( + upgrade_candidates.address_candidates); } void WifiLanBwuHandler::HandleRevertInitiatorStateForService( diff --git a/connections/implementation/wifi_lan_bwu_handler_test.cc b/connections/implementation/wifi_lan_bwu_handler_test.cc index 59e7c05e..f6623db9 100644 --- a/connections/implementation/wifi_lan_bwu_handler_test.cc +++ b/connections/implementation/wifi_lan_bwu_handler_test.cc @@ -26,15 +26,21 @@ #include "connections/implementation/bwu_handler.h" #include "connections/implementation/client_proxy.h" #include "connections/implementation/mediums/mediums.h" +#include "connections/strategy.h" +#include "internal/analytics/mock_event_logger.h" +#include "internal/analytics/sharing_log_matchers.h" #include "internal/platform/byte_array.h" #include "internal/platform/implementation/platform.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_lan.h" +#include "internal/platform/medium_environment.h" #include "internal/platform/mock_input_stream.h" #include "internal/platform/mock_output_stream.h" #include "internal/platform/mock_wifi_lan_medium.h" #include "internal/platform/mock_wifi_lan_server_socket.h" #include "internal/platform/mock_wifi_lan_socket.h" #include "internal/platform/service_address.h" +#include "internal/proto/analytics/connections_log.pb.h" namespace nearby { @@ -42,14 +48,18 @@ MockWifiLanMedium* wifi_lan_medium = nullptr; namespace connections { namespace { +using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame; using ::location::nearby::connections::OfflineFrame; using ::location::nearby::connections::V1Frame; +using ::location::nearby::proto::connections::EventType; using ::location::nearby::proto::connections::OperationResultCode; +using ::nearby::analytics::HasEventType; using ::testing::_; using ::testing::ByMove; using ::protobuf_matchers::EqualsProto; using ::testing::InSequence; +using ::testing::Matcher; using ::testing::MockFunction; using ::testing::Return; using ::testing::ReturnRef; @@ -70,11 +80,12 @@ class WifiLanBwuHandlerTest : public ::testing::Test { std::unique_ptr)> incoming_connection_callback_; WifiLanBwuHandler handler_; + nearby::analytics::MockEventLogger mock_event_logger_; }; TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_EmptyPathInfo_Fails) { - ClientProxy client; + ClientProxy client(&mock_event_logger_); BandwidthUpgradeNegotiationFrame::UpgradePathInfo path_info; // Create an empty wifi_lan_socket. path_info.mutable_wifi_lan_socket(); @@ -88,7 +99,7 @@ TEST_F(WifiLanBwuHandlerTest, }; TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_IpAddress_Success) { - ClientProxy client; + ClientProxy client(&mock_event_logger_); client.AddCancellationFlag(std::string(kEndpointId)); MockInputStream input_stream; MockOutputStream output_stream; @@ -100,10 +111,12 @@ TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_IpAddress_Success) { EXPECT_CALL(*wifi_lan_medium, IsNetworkConnected()) .WillRepeatedly(Return(true)); EXPECT_CALL(*wifi_lan_medium, - ConnectToService(ServiceAddress{ - .address = {kIpv4Address.begin(), kIpv4Address.end()}, - .port = 8080, - }, _)) + ConnectToService( + ServiceAddress{ + .address = {kIpv4Address.begin(), kIpv4Address.end()}, + .port = 8080, + }, + _)) .WillOnce(Return(ByMove(std::move(wifi_lan_socket)))); BandwidthUpgradeNegotiationFrame::UpgradePathInfo path_info; @@ -119,7 +132,7 @@ TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_IpAddress_Success) { TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_AddressCandidates_FirstCandidate_Success) { - ClientProxy client; + ClientProxy client(&mock_event_logger_); client.AddCancellationFlag(std::string(kEndpointId)); MockInputStream input_stream; MockOutputStream output_stream; @@ -131,10 +144,12 @@ TEST_F(WifiLanBwuHandlerTest, EXPECT_CALL(*wifi_lan_medium, IsNetworkConnected()) .WillRepeatedly(Return(true)); EXPECT_CALL(*wifi_lan_medium, - ConnectToService(ServiceAddress{ - .address = {kIpv6Address.begin(), kIpv6Address.end()}, - .port = 8080, - }, _)) + ConnectToService( + ServiceAddress{ + .address = {kIpv6Address.begin(), kIpv6Address.end()}, + .port = 8080, + }, + _)) .WillOnce(Return(ByMove(std::move(wifi_lan_socket)))); BandwidthUpgradeNegotiationFrame::UpgradePathInfo path_info; @@ -156,7 +171,7 @@ TEST_F(WifiLanBwuHandlerTest, TEST_F(WifiLanBwuHandlerTest, CreateUpgradedEndpointChannel_AddressCandidates_FirstCandidate_Fails) { - ClientProxy client; + ClientProxy client(&mock_event_logger_); client.AddCancellationFlag(std::string(kEndpointId)); MockInputStream input_stream; MockOutputStream output_stream; @@ -169,16 +184,20 @@ TEST_F(WifiLanBwuHandlerTest, .WillRepeatedly(Return(true)); InSequence seq; EXPECT_CALL(*wifi_lan_medium, - ConnectToService(ServiceAddress{ - .address = {kIpv6Address.begin(), kIpv6Address.end()}, - .port = 8080, - }, _)) + ConnectToService( + ServiceAddress{ + .address = {kIpv6Address.begin(), kIpv6Address.end()}, + .port = 8080, + }, + _)) .WillOnce(Return(ByMove(nullptr))); EXPECT_CALL(*wifi_lan_medium, - ConnectToService(ServiceAddress{ - .address = {kIpv4Address.begin(), kIpv4Address.end()}, - .port = 8080, - }, _)) + ConnectToService( + ServiceAddress{ + .address = {kIpv4Address.begin(), kIpv4Address.end()}, + .port = 8080, + }, + _)) .WillOnce(Return(ByMove(std::move(wifi_lan_socket)))); BandwidthUpgradeNegotiationFrame::UpgradePathInfo path_info; @@ -199,7 +218,19 @@ TEST_F(WifiLanBwuHandlerTest, }; TEST_F(WifiLanBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { - ClientProxy client; + MediumEnvironment::Instance().Start({.use_simulated_clock = true}); + ClientProxy client(&mock_event_logger_); + client.GetAnalyticsRecorder().OnStartAdvertising( + Strategy::kP2pPointToPoint, + {location::nearby::proto::connections::Medium::BLUETOOTH}, + /*advertising_metadata_params=*/nullptr); + client.GetAnalyticsRecorder().OnBandwidthUpgradeStarted( + std::string(kEndpointId), + location::nearby::proto::connections::Medium::BLUETOOTH, + location::nearby::proto::connections::Medium::WIFI_LAN, + location::nearby::proto::connections::ConnectionAttemptDirection:: + OUTGOING, + /*connection_token=*/""); client.AddCancellationFlag(std::string(kEndpointId)); auto wifi_lan_server_socket = std::make_unique(); EXPECT_CALL(*wifi_lan_server_socket, GetPort()).WillRepeatedly(Return(8080)); @@ -208,10 +239,14 @@ TEST_F(WifiLanBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { EXPECT_CALL(*wifi_lan_medium, ListenForService(_)) .WillOnce(Return(ByMove(std::move(wifi_lan_server_socket)))); EXPECT_CALL(*wifi_lan_medium, GetUpgradeAddressCandidates(_)) - .WillOnce(Return(std::vector{ - {std::vector{kIpv6Address.begin(), kIpv6Address.end()}, 8080}, - {std::vector{kIpv4Address.begin(), kIpv4Address.end()}, - 8888}})); + .WillOnce(Return(api::UpgradeAddressInfo{ + .num_interfaces = 1, + .num_ipv6_only_interfaces = 1, + .address_candidates = { + {std::vector{kIpv6Address.begin(), kIpv6Address.end()}, + 8080}, + {std::vector{kIpv4Address.begin(), kIpv4Address.end()}, + 8888}}})); OfflineFrame expected_frame; expected_frame.set_version(OfflineFrame::V1); expected_frame.mutable_v1()->set_type(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION); @@ -243,6 +278,70 @@ TEST_F(WifiLanBwuHandlerTest, InitializeUpgradedMediumForEndpoint_Success) { OfflineFrame result_frame; EXPECT_TRUE(result_frame.ParseFromString(std::string(result))); EXPECT_THAT(result_frame, EqualsProto(expected_frame)); + + constexpr absl::string_view kClientSessionLog = R"pb( + event_type: CLIENT_SESSION + client_session { duration_millis: 0 } + version: "v1.5.0" + )pb"; + constexpr absl::string_view kExpectedUpgradeLog = R"pb( + event_type: CLIENT_SESSION + client_session { + duration_millis: 0 + strategy_session { + duration_millis: 0 + strategy: P2P_POINT_TO_POINT + role: ADVERTISER + advertising_phase { + duration_millis: 0 + medium: BLUETOOTH + advertising_metadata { + supports_extended_ble_advertisements: false + connected_ap_frequency: 0 + supports_nfc_technology: false + } + stop_reason: FINISH_SESSION_STOP_ADVERTISING + } + upgrade_attempt { + direction: OUTGOING + duration_millis: 0 + from_medium: BLUETOOTH + to_medium: WIFI_LAN + upgrade_result: UNFINISHED_ERROR + error_stage: UPGRADE_UNFINISHED + connection_token: "" + operation_result { + result_category: CATEGORY_DEVICE_STATE_ERROR + result_code: DEVICE_STATE_ERROR_UNFINISHED_UPGRADE_ATTEMPTS + } + num_interfaces: 1 + num_ipv6_only_interfaces: 1 + } + } + } + version: "v1.5.0" + )pb"; + EXPECT_CALL(mock_event_logger_, + Log(Matcher( + HasEventType(EventType::STOP_STRATEGY_SESSION)))) + .Times(1); + EXPECT_CALL(mock_event_logger_, + Log(Matcher( + HasEventType(EventType::STOP_CLIENT_SESSION)))) + .Times(3); + EXPECT_CALL(mock_event_logger_, + Log(Matcher( + HasEventType(EventType::START_CLIENT_SESSION)))) + .Times(3); + EXPECT_CALL( + mock_event_logger_, + Log(Matcher(EqualsProto(kClientSessionLog)))) + .Times(2); + EXPECT_CALL( + mock_event_logger_, + Log(Matcher(EqualsProto(kExpectedUpgradeLog)))); + // Flush pending logs. + client.GetAnalyticsRecorder().LogSession(); } } // namespace diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 4e9b7e2a..14778478 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -159,6 +159,7 @@ cc_library( "credential_storage.h", "http_loader.h", "psk_info.h", + "upgrade_address_info.h", "webrtc.h", "wifi.h", "wifi_direct.h", diff --git a/internal/platform/implementation/apple/wifi_lan.h b/internal/platform/implementation/apple/wifi_lan.h index b98c60ac..41e4acc0 100644 --- a/internal/platform/implementation/apple/wifi_lan.h +++ b/internal/platform/implementation/apple/wifi_lan.h @@ -21,6 +21,7 @@ #include #include +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/nsd_service_info.h" #include "internal/platform/service_address.h" @@ -125,7 +126,7 @@ class WifiLanMedium : public api::WifiLanMedium { std::unique_ptr ConnectToService( const ServiceAddress& service_address, CancellationFlag* cancellation_flag) override; std::unique_ptr ListenForService(int port) override; - std::vector GetUpgradeAddressCandidates(const api::WifiLanServerSocket& server_socket) override; + api::UpgradeAddressInfo GetUpgradeAddressCandidates(const api::WifiLanServerSocket& server_socket) override; private: GNCNWFramework* medium_; diff --git a/internal/platform/implementation/apple/wifi_lan.mm b/internal/platform/implementation/apple/wifi_lan.mm index bd2196a1..a3bb8a84 100644 --- a/internal/platform/implementation/apple/wifi_lan.mm +++ b/internal/platform/implementation/apple/wifi_lan.mm @@ -183,11 +183,16 @@ std::unique_ptr WifiLanMedium::ListenForService(int po return nil; } -std::vector WifiLanMedium::GetUpgradeAddressCandidates( +api::UpgradeAddressInfo WifiLanMedium::GetUpgradeAddressCandidates( const api::WifiLanServerSocket& server_socket) { std::string ip_address = server_socket.GetIPAddress(); - return {ServiceAddress{.address = std::vector(ip_address.begin(), ip_address.end()), - .port = static_cast(server_socket.GetPort())}}; + api::UpgradeAddressInfo result; + result.num_interfaces = 1; + result.num_ipv6_only_interfaces = 0; + result.address_candidates.push_back( + {.address = std::vector(ip_address.begin(), ip_address.end()), + .port = static_cast(server_socket.GetPort())}); + return result; } } // namespace apple diff --git a/internal/platform/implementation/g3/wifi_lan.cc b/internal/platform/implementation/g3/wifi_lan.cc index 8367b144..b643dc16 100644 --- a/internal/platform/implementation/g3/wifi_lan.cc +++ b/internal/platform/implementation/g3/wifi_lan.cc @@ -26,6 +26,7 @@ #include "internal/platform/cancellation_flag.h" #include "internal/platform/cancellation_flag_listener.h" #include "internal/platform/exception.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" @@ -289,12 +290,17 @@ std::unique_ptr WifiLanMedium::ListenForService( return server_socket; } -std::vector WifiLanMedium::GetUpgradeAddressCandidates( +api::UpgradeAddressInfo WifiLanMedium::GetUpgradeAddressCandidates( const api::WifiLanServerSocket& server_socket) { std::string ip_address = server_socket.GetIPAddress(); - return {ServiceAddress{ + return { + .num_interfaces = 1, + .num_ipv6_only_interfaces = 0, + .address_candidates = + {ServiceAddress{ .address = std::vector(ip_address.begin(), ip_address.end()), - .port = static_cast(server_socket.GetPort())}}; + .port = static_cast(server_socket.GetPort())}} + }; } } // namespace g3 diff --git a/internal/platform/implementation/g3/wifi_lan.h b/internal/platform/implementation/g3/wifi_lan.h index 483ae1cc..69206a3b 100644 --- a/internal/platform/implementation/g3/wifi_lan.h +++ b/internal/platform/implementation/g3/wifi_lan.h @@ -18,19 +18,18 @@ #include #include #include -#include #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/synchronization/mutex.h" #include "internal/platform/implementation/g3/socket_base.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/input_stream.h" #include "internal/platform/medium_environment.h" #include "internal/platform/nsd_service_info.h" #include "internal/platform/output_stream.h" #include "internal/platform/service_address.h" -#include "internal/platform/wifi_credential.h" namespace nearby { namespace g3 { @@ -209,7 +208,7 @@ class WifiLanMedium : public api::WifiLanMedium { return std::nullopt; } - std::vector GetUpgradeAddressCandidates( + api::UpgradeAddressInfo GetUpgradeAddressCandidates( const api::WifiLanServerSocket& server_socket) override; private: diff --git a/internal/platform/implementation/upgrade_address_info.h b/internal/platform/implementation/upgrade_address_info.h new file mode 100644 index 00000000..68f6bd7c --- /dev/null +++ b/internal/platform/implementation/upgrade_address_info.h @@ -0,0 +1,37 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_UPGRADE_ADDRESS_INFO_H_ +#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_UPGRADE_ADDRESS_INFO_H_ + +#include + + +#include "internal/platform/service_address.h" + +namespace nearby::api { + +// Container for upgrade address candidates and network configuration info. +struct UpgradeAddressInfo { + // Number of network interfaces that can be used for upgrade. + int num_interfaces = 0; + // Number of network interfaces for upgrade that are IPv6 only. + int num_ipv6_only_interfaces = 0; + // Address list is sorted so IPv6 addresses are first. + std::vector address_candidates; +}; + +} // namespace nearby::api + +#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_UPGRADE_ADDRESS_INFO_H_ diff --git a/internal/platform/implementation/wifi_lan.h b/internal/platform/implementation/wifi_lan.h index ddd75932..c174cf3b 100644 --- a/internal/platform/implementation/wifi_lan.h +++ b/internal/platform/implementation/wifi_lan.h @@ -17,10 +17,10 @@ #include #include -#include #include "absl/functional/any_invocable.h" #include "internal/platform/cancellation_flag.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/input_stream.h" #include "internal/platform/listeners.h" #include "internal/platform/nsd_service_info.h" @@ -159,9 +159,7 @@ class WifiLanMedium { // this device for bandwidth upgrade. // `server_socket` is the socket that is currently listening for service // requests. - // Returned adddress list is sorted so IPv6 addresses are first. Both IPv4 - // and IPv6 addresses are represented as network order byte sequence. - virtual std::vector GetUpgradeAddressCandidates( + virtual UpgradeAddressInfo GetUpgradeAddressCandidates( const WifiLanServerSocket& server_socket) = 0; }; diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index a95e6d5b..206b9838 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -309,7 +309,6 @@ cc_library( "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:mac_address", - "//internal/platform:types", "//internal/platform:uuid", "//internal/platform/flags:platform_flags", "//internal/platform/implementation:comm", diff --git a/internal/platform/implementation/windows/wifi_lan.h b/internal/platform/implementation/windows/wifi_lan.h index f47240fd..4963883f 100644 --- a/internal/platform/implementation/windows/wifi_lan.h +++ b/internal/platform/implementation/windows/wifi_lan.h @@ -27,7 +27,6 @@ #include #include #include -#include // Nearby connections headers #include "absl/base/nullability.h" @@ -38,10 +37,10 @@ #include "absl/synchronization/mutex.h" #include "absl/time/time.h" #include "absl/types/optional.h" -#include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/implementation/cancelable.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/implementation/windows/nearby_client_socket.h" #include "internal/platform/implementation/windows/nearby_server_socket.h" @@ -52,7 +51,6 @@ #include "internal/platform/nsd_service_info.h" #include "internal/platform/output_stream.h" #include "internal/platform/service_address.h" -#include "internal/platform/wifi_credential.h" // WinRT headers #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h" @@ -185,7 +183,7 @@ class WifiLanMedium : public api::WifiLanMedium { return absl::nullopt; } - std::vector GetUpgradeAddressCandidates( + api::UpgradeAddressInfo GetUpgradeAddressCandidates( const api::WifiLanServerSocket& server_socket) override; private: diff --git a/internal/platform/implementation/windows/wifi_lan_medium.cc b/internal/platform/implementation/windows/wifi_lan_medium.cc index 9dce679e..37361804 100644 --- a/internal/platform/implementation/windows/wifi_lan_medium.cc +++ b/internal/platform/implementation/windows/wifi_lan_medium.cc @@ -30,7 +30,6 @@ #include #include -#include "absl/container/flat_hash_map.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" @@ -42,6 +41,7 @@ #include "internal/platform/feature_flags.h" #include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/service_address.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.Collections.h" @@ -717,13 +717,16 @@ bool WifiLanMedium::IsConnectableIpAddress(NsdServiceInfo& nsd_service_info, return false; } -std::vector WifiLanMedium::GetUpgradeAddressCandidates( +api::UpgradeAddressInfo WifiLanMedium::GetUpgradeAddressCandidates( const api::WifiLanServerSocket& server_socket) { const NetworkInfo& network_info = NetworkInfo::GetNetworkInfo(); uint16_t port = server_socket.GetPort(); - std::vector ip_addresses; + api::UpgradeAddressInfo result; std::vector ipv4_addresses; - for (const auto& net_interface : network_info.GetInterfaces()) { + for (const NetworkInfo::InterfaceInfo& net_interface : + network_info.GetInterfaces()) { + bool has_ipv6_address = false; + bool has_ipv4_address = false; // Only use wifi and ethernet interfaces for upgrade. if (net_interface.type != InterfaceType::kWifi && net_interface.type != InterfaceType::kEthernet) { @@ -735,24 +738,41 @@ std::vector WifiLanMedium::GetUpgradeAddressCandidates( if (address.IsV6LinkLocal()) { continue; } - ip_addresses.push_back(address.ToServiceAddress(port)); + result.address_candidates.push_back(address.ToServiceAddress(port)); + has_ipv6_address = true; } for (const SocketAddress& v4_address : net_interface.ipv4_addresses) { + // Link local addresses cannot be used for upgrade since we can't tell + // which interface on the remote device the address is valid. + if (v4_address.IsV4LinkLocal()) { + continue; + } ipv4_addresses.push_back(v4_address.ToServiceAddress(port)); + has_ipv4_address = true; + } + if (has_ipv6_address || has_ipv4_address) { + result.num_interfaces++; + if (has_ipv6_address && !has_ipv4_address) { + result.num_ipv6_only_interfaces++; + } } } if (NearbyFlags::GetInstance().GetBoolFlag( platform::config_package_nearby::nearby_platform_feature:: kEnableWifiLanAddressCandidates)) { // Append v4 addresses to the end of the list. - ip_addresses.insert(ip_addresses.end(), ipv4_addresses.begin(), - ipv4_addresses.end()); - return ip_addresses; + result.address_candidates.insert(result.address_candidates.end(), + ipv4_addresses.begin(), + ipv4_addresses.end()); + } else { + // If kEnableWifiLanAddressCandidates is disabled, only return the last v4 + // address. + result.address_candidates.clear(); + if (!ipv4_addresses.empty()) { + result.address_candidates.push_back(ipv4_addresses.back()); + } } - if (!ipv4_addresses.empty()) { - return {ipv4_addresses.back()}; - } - return {}; + return result; } } // namespace nearby::windows diff --git a/internal/platform/mock_wifi_lan_medium.h b/internal/platform/mock_wifi_lan_medium.h index 96b11823..2dbf2da9 100644 --- a/internal/platform/mock_wifi_lan_medium.h +++ b/internal/platform/mock_wifi_lan_medium.h @@ -19,11 +19,11 @@ #include #include #include -#include #include "absl/types/optional.h" #include "gmock/gmock.h" #include "internal/platform/cancellation_flag.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/nsd_service_info.h" #include "internal/platform/service_address.h" @@ -55,7 +55,7 @@ class MockWifiLanMedium : public api::WifiLanMedium { (int port), (override)); MOCK_METHOD((absl::optional>), GetDynamicPortRange, (), (override)); - MOCK_METHOD(std::vector, GetUpgradeAddressCandidates, + MOCK_METHOD(api::UpgradeAddressInfo, GetUpgradeAddressCandidates, (const api::WifiLanServerSocket& server_socket), (override)); }; diff --git a/internal/platform/wifi_lan.cc b/internal/platform/wifi_lan.cc index e29e40ee..5476a642 100644 --- a/internal/platform/wifi_lan.cc +++ b/internal/platform/wifi_lan.cc @@ -17,10 +17,10 @@ #include #include #include -#include #include "absl/container/flat_hash_map.h" #include "internal/platform/cancellation_flag.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" #include "internal/platform/nsd_service_info.h" @@ -201,7 +201,7 @@ WifiLanSocket WifiLanMedium::ConnectToService( impl_->ConnectToService(service_address, cancellation_flag)); } -std::vector WifiLanMedium::GetUpgradeAddressCandidates( +api::UpgradeAddressInfo WifiLanMedium::GetUpgradeAddressCandidates( const WifiLanServerSocket& server_socket) { return impl_->GetUpgradeAddressCandidates(server_socket.GetImpl()); } diff --git a/internal/platform/wifi_lan.h b/internal/platform/wifi_lan.h index 75236ecc..e46a39f6 100644 --- a/internal/platform/wifi_lan.h +++ b/internal/platform/wifi_lan.h @@ -19,9 +19,10 @@ #include #include #include -#include +#include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/functional/any_invocable.h" #include "absl/types/optional.h" #include "internal/platform/blocking_queue_stream.h" @@ -29,6 +30,7 @@ #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/implementation/platform.h" +#include "internal/platform/implementation/upgrade_address_info.h" #include "internal/platform/implementation/wifi_lan.h" #include "internal/platform/input_stream.h" #include "internal/platform/listeners.h" @@ -189,8 +191,6 @@ class WifiLanServerSocket final { // Container of operations that can be performed over the WifiLan medium. class WifiLanMedium { public: - using Platform = api::ImplementationPlatform; - struct DiscoveredServiceCallback { absl::AnyInvocable @@ -206,7 +206,7 @@ class WifiLanMedium { DiscoveredServiceCallback medium_callback; }; - WifiLanMedium() : impl_(Platform::CreateWifiLanMedium()) {} + WifiLanMedium() : impl_(api::ImplementationPlatform::CreateWifiLanMedium()) {} ~WifiLanMedium() = default; // Starts WifiLan advertising. @@ -274,9 +274,7 @@ class WifiLanMedium { // this device for bandwidth upgrade. // `server_socket` is the socket that is currently listening for service // requests. - // Returned adddress list is sorted so IPv6 addresses are first. Both IPv4 - // and IPv6 addresses are represented as network order byte sequence. - std::vector GetUpgradeAddressCandidates( + api::UpgradeAddressInfo GetUpgradeAddressCandidates( const WifiLanServerSocket& server_socket); private: diff --git a/internal/proto/analytics/connections_log.proto b/internal/proto/analytics/connections_log.proto index 1af8d81e..77b0ea4f 100644 --- a/internal/proto/analytics/connections_log.proto +++ b/internal/proto/analytics/connections_log.proto @@ -556,6 +556,13 @@ message ConnectionsLog { // The supported service. optional location.nearby.proto.connections.SupportedService supported_service = 11; + + // The number of network interfaces on the device for the upgrade medium + // that can be used for bandwidth upgrade. + optional int32 num_interfaces = 12; + // The number of network interfaces on the device for the upgrade medium + // that can be used for bandwidth upgrade and are IPv6 only. + optional int32 num_ipv6_only_interfaces = 13; } // Next Id: 22